diff options
Diffstat (limited to 'libmysqld')
-rw-r--r-- | libmysqld/Makefile.am | 40 | ||||
-rw-r--r-- | libmysqld/embedded_priv.h | 6 | ||||
-rw-r--r-- | libmysqld/examples/Makefile.am | 4 | ||||
-rw-r--r-- | libmysqld/examples/builder-sample/emb_sample.tds | bin | 2293760 -> 0 bytes | |||
-rw-r--r-- | libmysqld/examples/builder-sample/libmysqld.lib | bin | 7168 -> 0 bytes | |||
-rw-r--r-- | libmysqld/lib_sql.cc | 684 | ||||
-rw-r--r-- | libmysqld/lib_vio.c | 226 | ||||
-rw-r--r-- | libmysqld/libmysqld.c | 2016 | ||||
-rw-r--r-- | libmysqld/libmysqld.def | 183 |
9 files changed, 571 insertions, 2588 deletions
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index d831d2a7a5a..b22ff9e5001 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -25,37 +25,38 @@ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" -INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include \ - -I../include -I$(srcdir)/.. -I$(top_srcdir) -I.. \ - -I../sql -I../regex +INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ + -I$(top_srcdir)/sql -I$(top_srcdir)/regex \ + $(openssl_includes) noinst_LIBRARIES = libmysqld_int.a pkglib_LIBRARIES = libmysqld.a SUBDIRS = . examples libmysqld_sources= libmysqld.c lib_sql.cc -libmysqlsources = errmsg.c get_password.c +libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c noinst_HEADERS = embedded_priv.h -sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ +sqlsources = derror.cc field.cc field_conv.cc filesort.cc \ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \ hostname.cc init.cc password.c \ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \ - item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\ - mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \ + item_geofunc.cc item_uniq.cc item_subselect.cc item_row.cc\ + key.cc lock.cc log.cc log_event.cc sql_state.c \ + protocol.cc net_serv.cc opt_ft.cc opt_range.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \ - repl_failsafe.cc slave.cc sql_load.cc sql_olap.cc \ + sql_load.cc sql_olap.cc \ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \ - sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \ - sql_list.cc sql_manager.cc sql_map.cc set_var.cc sql_parse.cc \ - sql_rename.cc sql_repl.cc sql_select.cc sql_do.cc sql_show.cc \ + sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \ + sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \ + sql_prepare.cc sql_derived.cc sql_rename.cc \ + sql_select.cc sql_do.cc sql_show.cc set_var.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ - unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc - -EXTRA_DIST = lib_vio.c + unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ + spatial.cc gstream.cc sql_help.cc libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) libmysqld_a_SOURCES= @@ -72,7 +73,8 @@ INC_LIB= $(top_builddir)/regex/libregex.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/regex/libregex.a + $(top_builddir)/regex/libregex.a \ + $(top_builddir)/vio/libvio.a # # To make it easy for the end user to use the embedded library we @@ -113,11 +115,15 @@ link_sources: for f in $(libmysqlsources); do \ rm -f $(srcdir)/$$f; \ @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \ - done + done; \ + rm -f $(srcdir)/client_settings.h; \ + @LN_CP_F@ $(srcdir)/../libmysql/client_settings.h $(srcdir)/client_settings.h; + clean-local: rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"` \ - $(top_srcdir)/linked_libmysqld_sources + $(top_srcdir)/linked_libmysqld_sources; \ + rm -f client_settings.h # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index e17b72e84d8..dfc06e38ab2 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -23,9 +23,7 @@ #include <my_pthread.h> C_MODE_START -extern void start_embedded_connection(NET * net); -extern void end_embedded_connection(NET * net); extern void lib_connection_phase(NET *net, int phase); -extern bool lib_dispatch_command(enum enum_server_command command, NET *net, - const char *arg, ulong length); +extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); +extern void *create_embedded_thd(int client_flag, char *db); C_MODE_END diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index f741ddf0191..c2292a6b48d 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -10,8 +10,8 @@ link_sources: DEFS = -DEMBEDDED_LIBRARY INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \ -I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes) -LIBS = @LIBS@ @WRAPLIBS@ -LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) +LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ +LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @bdb_libs_with_path@ @LIBDL@ $(CXXLDFLAGS) mysqltest_SOURCES = mysqltest.c diff --git a/libmysqld/examples/builder-sample/emb_sample.tds b/libmysqld/examples/builder-sample/emb_sample.tds Binary files differdeleted file mode 100644 index 2471b6c112f..00000000000 --- a/libmysqld/examples/builder-sample/emb_sample.tds +++ /dev/null diff --git a/libmysqld/examples/builder-sample/libmysqld.lib b/libmysqld/examples/builder-sample/libmysqld.lib Binary files differdeleted file mode 100644 index 994e67e675e..00000000000 --- a/libmysqld/examples/builder-sample/libmysqld.lib +++ /dev/null diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 52ff08b8787..892a21ed08b 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -23,15 +23,22 @@ #define mysql_unix_port mysql_inix_port1 #define mysql_port mysql_port1 +static int fake_argc= 1; +static char *fake_argv[]= {(char *)"", 0}; +static const char *fake_groups[] = { "server", "embedded", 0 }; +static my_bool org_my_init_done; +my_bool server_inited; + #if defined (__WIN__) #include "../sql/mysqld.cpp" #else #include "../sql/mysqld.cc" #endif -#define SCRAMBLE_LENGTH 8 C_MODE_START -#include "lib_vio.c" +#include <mysql.h> +#include "errmsg.h" +#include <sql_common.h> static int check_connections1(THD * thd); static int check_connections2(THD * thd); @@ -41,225 +48,66 @@ static bool check_user(THD *thd, enum_server_command command, char * get_mysql_home(){ return mysql_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;}; -bool lib_dispatch_command(enum enum_server_command command, NET *net, - const char *arg, ulong length) +my_bool STDCALL +emb_advanced_command(MYSQL *mysql, enum enum_server_command command, + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check) { - THD *thd=(THD *) net->vio->dest_thd; - thd->store_globals(); // Fix if more than one connect - thd->net.last_error[0]=0; // Clear error message - thd->net.last_errno=0; - - net_new_transaction(&thd->net); - return dispatch_command(command, thd, (char *) arg, length + 1); -} + my_bool result= 1; + THD *thd=(THD *) mysql->thd; - -void lib_connection_phase(NET * net, int phase) -{ - THD * thd; - thd = (THD *)(net->vio->dest_thd); - if (thd) + /* Check that we are calling the client functions in right order */ + if (mysql->status != MYSQL_STATUS_READY) { - switch (phase) - { - case 2: - check_connections2(thd); - break; - } - } -} -C_MODE_END - - -void start_embedded_conn1(NET * net) -{ - THD * thd = new THD; - my_net_init(&thd->net,NULL); - /* if (protocol_version>9) */ - thd->net.return_errno=1; - thd->thread_id = thread_id++; - - Vio * v = net->vio; - if (!v) - { - v = vio_new(0,VIO_CLOSED,0); - net->vio = v; - } - if (v) - { - v -> dest_thd = thd; - } - thd->net.vio = v; - if (thd->store_globals()) - { - fprintf(stderr,"store_globals failed.\n"); - return; + strmov(thd->net.last_error, + ER(thd->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); + return 1; } - thd->mysys_var=my_thread_var; - thd->dbug_thread_id=my_thread_id(); - thd->thread_stack= (char*) &thd; - - if (thd->variables.max_join_size == (ulong) HA_POS_ERROR) - thd->options |= OPTION_BIG_SELECTS; - - thd->proc_info=0; // Remove 'login' - thd->command=COM_SLEEP; - thd->version=refresh_version; - thd->set_time(); - bzero(thd->scramble, sizeof(thd->scramble)); - init_sql_alloc(&thd->mem_root,8192,8192); - - check_connections1(thd); -} - + /* Clear result variables */ + thd->clear_error(); + mysql->affected_rows= ~(my_ulonglong) 0; + mysql->field_count= 0; + thd->store_globals(); // Fix if more than one connect + free_old_query(mysql); + result= dispatch_command(command, thd, (char *) arg, arg_length + 1); + if (!skip_check) + result= thd->net.last_errno ? -1 : 0; -static int -check_connections1(THD *thd) -{ - uint connect_errors=0; - NET *net= &thd->net; - /* - ** store the connection details - */ - DBUG_PRINT("info", (("check_connections called by thread %d"), - thd->thread_id)); - DBUG_PRINT("general",("New connection received on %s", - vio_description(net->vio))); - if (!thd->host) // If TCP/IP connection + if ((mysql->net.last_errno= thd->net.last_errno)) { - thd->host=(char*) localhost; + memcpy(mysql->net.last_error, thd->net.last_error, + sizeof(mysql->net.last_error)); + memcpy(mysql->net.sqlstate, thd->net.sqlstate, + sizeof(mysql->net.sqlstate)); } - else /* Hostname given means that the connection was on a socket */ - { - DBUG_PRINT("general",("Host: %s",thd->host)); - thd->ip=0; - bzero((char*) &thd->remote,sizeof(struct sockaddr)); - } - //vio_keepalive(net->vio, TRUE); - - /* nasty, but any other way? */ - uint pkt_len = 0; - - char buff[80],*end; - int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | - CLIENT_TRANSACTIONS; - LINT_INIT(pkt_len); - - end=strmov(buff,server_version)+1; - int4store((uchar*) end,thd->thread_id); - end+=4; - memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1); - end+=SCRAMBLE_LENGTH +1; - int2store(end,client_flags); - end[2]=MY_CHARSET_CURRENT; - -#define MIN_HANDSHAKE_SIZE 6 - - int2store(end+3,thd->server_status); - bzero(end+5,13); - end+=18; - if (net_write_command(net,protocol_version, buff, - (uint) (end-buff))) - { - inc_host_errors(&thd->remote.sin_addr); - return(ER_HANDSHAKE_ERROR); - } - return 0; + mysql->warning_count= ((THD*)mysql->thd)->total_warn_count; + return result; } -static int -check_connections2(THD * thd) -{ - uint connect_errors=0; - uint pkt_len = 0; - NET * net = &thd -> net; - if (protocol_version>9) net -> return_errno=1; - - if ( (pkt_len=my_net_read(net)) == packet_error || - pkt_len < MIN_HANDSHAKE_SIZE) - { - inc_host_errors(&thd->remote.sin_addr); - return(ER_HANDSHAKE_ERROR); - } +C_MODE_END -#ifdef _CUSTOMCONFIG_ -#include "_cust_sql_parse.h" -#endif - if (connect_errors) - reset_host_errors(&thd->remote.sin_addr); - if (thd->packet.alloc(thd->variables.net_buffer_length)) - return(ER_OUT_OF_RESOURCES); - - thd->client_capabilities=uint2korr(net->read_pos); - - thd->max_client_packet_length=uint3korr(net->read_pos+2); - char *user= (char*) net->read_pos+5; - char *passwd= strend(user)+1; - char *db=0; - if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH) - return ER_HANDSHAKE_ERROR; - if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) - db=strend(passwd)+1; - if (thd->client_capabilities & CLIENT_TRANSACTIONS) - thd->net.return_status= &thd->server_status; - net->read_timeout=thd->variables.net_read_timeout; - if (check_user(thd,COM_CONNECT, user, passwd, db, 1)) - return (-1); - thd->password=test(passwd[0]); - return 0; +void THD::clear_error() +{ + net.last_error[0]= 0; + net.last_errno= 0; + net.report_error= 0; } static bool check_user(THD *thd,enum_server_command command, const char *user, const char *passwd, const char *db, bool check_count) { - NET *net= &thd->net; - USER_RESOURCES ur; thd->db=0; if (!(thd->user = my_strdup(user, MYF(0)))) { - send_error(net,ER_OUT_OF_RESOURCES); + send_error(thd,ER_OUT_OF_RESOURCES); return 1; } - thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, - passwd, thd->scramble, - &thd->priv_user, thd->priv_host, - protocol_version == 9 || - !(thd->client_capabilities & - CLIENT_LONG_PASSWORD),&ur); - DBUG_PRINT("info", - ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", - thd->client_capabilities, thd->max_client_packet_length, - thd->host_or_ip, thd->priv_user, - passwd[0] ? "yes": "no", - thd->master_access, thd->db ? thd->db : "*none*")); - if (thd->master_access & NO_ACCESS) - { - net_printf(net, ER_ACCESS_DENIED_ERROR, - thd->user, - thd->host_or_ip, - passwd[0] ? ER(ER_YES) : ER(ER_NO)); - mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR), - thd->user, - thd->host_or_ip, - passwd[0] ? ER(ER_YES) : ER(ER_NO)); - return(1); // Error already given - } - if (check_count) - { - VOID(pthread_mutex_lock(&LOCK_thread_count)); - bool tmp=(thread_count - delayed_insert_threads >= max_connections && - !(thd->master_access & PROCESS_ACL)); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); - if (tmp) - { // Too many connections - send_error(net, ER_CON_COUNT_ERROR); - return(1); - } - } + thd->master_access= ~0L; // No user checking + thd->priv_user= thd->user; mysql_log.write(thd,command, (thd->priv_user == thd->user ? (char*) "%s@%s on %s" : @@ -271,7 +119,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, if (db && db[0]) return test(mysql_change_db(thd,db)); else - send_ok(net); // Ready to handle questions + send_ok(thd); // Ready to handle questions return 0; // ok } @@ -306,9 +154,6 @@ char **copy_arguments(int argc, char **argv) extern "C" { -static my_bool org_my_init_done; -my_bool server_inited; -ulong max_allowed_packet, net_buffer_length; char ** copy_arguments_ptr= 0; int STDCALL mysql_server_init(int argc, char **argv, char **groups) @@ -324,19 +169,17 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) const char *fake_groups[] = { "server", "embedded", 0 }; if (argc) { - argcp = &argc; - argvp = (char***) &argv; + argcp= &argc; + argvp= (char***) &argv; } else { - argcp = &fake_argc; - argvp = (char ***) &fake_argv; + argcp= &fake_argc; + argvp= (char ***) &fake_argv; } if (!groups) - groups = (char**) fake_groups; + groups= (char**) fake_groups; - my_umask=0660; // Default umask for new files - my_umask_dir=0700; // Default umask for new directories /* Only call MY_INIT() if it hasn't been called before */ if (!server_inited) @@ -349,43 +192,12 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads } - /* - Make a copy of the arguments to guard against applications that - may change or move the initial arguments. - */ - if (argvp == &argv) - if (!(copy_arguments_ptr= argv= copy_arguments(argc, argv))) - return 1; - - tzset(); // Set tzname - - start_time=time((time_t*) 0); -#ifdef HAVE_TZNAME -#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT) - { - struct tm tm_tmp; - localtime_r(&start_time,&tm_tmp); - strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]); - } -#else + if (init_common_variables("my", *argcp, *argvp, (const char **)groups)) { - struct tm *start_tm; - start_tm=localtime(&start_time); - strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]); + mysql_server_end(); + return 1; } -#endif -#endif - - if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) - strmov(glob_hostname,"mysql"); -#ifndef DBUG_OFF - strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS); -#else - strmov(strend(server_version),MYSQL_SERVER_SUFFIX); -#endif - load_defaults("my", (const char **) groups, argcp, argvp); - defaults_argv=*argvp; - + /* Get default temporary directory */ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ #if defined( __WIN__) || defined(OS2) @@ -397,175 +209,23 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0]) opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ - set_options(); - get_options(*argcp, *argvp); - - if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) - strcat(server_version,"-log"); - DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, - server_version, SYSTEM_TYPE,MACHINE_TYPE)); - - if (opt_error_log) - { - if (!log_error_file_ptr[0]) - fn_format(log_error_file, glob_hostname, mysql_data_home, ".err", 0); - else - fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err", - MY_UNPACK_FILENAME | MY_SAFE_PATH); - if (!log_error_file[0]) - opt_error_log= 1; // Too long file name - else - { - freopen(log_error_file, "a+", stderr); - } - } - - /* These must be set early */ - - (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); - (void) pthread_cond_init(&COND_thread_count,NULL); - (void) pthread_cond_init(&COND_refresh,NULL); - (void) pthread_cond_init(&COND_thread_cache,NULL); - (void) pthread_cond_init(&COND_flush_thread_cache,NULL); - (void) pthread_cond_init(&COND_manager,NULL); - (void) pthread_cond_init(&COND_rpl_status, NULL); - - if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME))) - { - mysql_server_end(); - return 1; - } - charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); - - /* Parameter for threads created for connections */ - (void) pthread_attr_init(&connection_attrib); - (void) pthread_attr_setdetachstate(&connection_attrib, - PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&connection_attrib,thread_stack); - pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); - -#if defined( SET_RLIMIT_NOFILE) || defined( OS2) - /* connections and databases needs lots of files */ - { - uint wanted_files=10+(uint) max(max_connections*5, - max_connections+table_cache_size*2); - set_if_bigger(wanted_files, open_files_limit); - // Note that some system returns 0 if we succeed here: - uint files=set_maximum_open_files(wanted_files); - if (files && files < wanted_files && ! open_files_limit) - { - max_connections= (ulong) min((files-10),max_connections); - table_cache_size= (ulong) max((files-10-max_connections)/2,64); - DBUG_PRINT("warning", - ("Changed limits: max_connections: %ld table_cache: %ld", - max_connections,table_cache_size)); - sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size); - } - } -#endif - unireg_init(opt_specialflag); /* Set up extern variabels */ - init_errmessage(); /* Read error messages from file */ - lex_init(); - item_init(); - set_var_init(); - mysys_uses_curses=0; -#ifdef USE_REGEX - regex_init(); -#endif - if (use_temp_pool && bitmap_init(&temp_pool,1024,1)) + umask(((~my_umask) & 0666)); + if (init_server_components()) { mysql_server_end(); return 1; } - /* - We have enough space for fiddling with the argv, continue - */ - umask(((~my_umask) & 0666)); - table_cache_init(); - hostname_cache_init(); - query_cache_result_size_limit(query_cache_limit); - query_cache_resize(query_cache_size); - randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2); - reset_floating_point_exceptions(); - init_thr_lock(); - init_slave_list(); - - /* Setup log files */ - if (opt_log) - open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, - LOG_NORMAL, 0, 0, 0); - if (opt_update_log) - { - open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW, 0, 0, 0); - using_update_log=1; - } - - if (opt_slow_log) - open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - NullS, LOG_NORMAL, 0, 0, 0); - if (ha_init()) - { - sql_print_error("Can't init databases"); - exit(1); - } - ha_key_cache(); -#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) - if (locked_in_memory && !geteuid()) - { - if (mlockall(MCL_CURRENT)) - { - sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); - } - else - locked_in_memory=1; - } -#else - locked_in_memory=0; -#endif - - if (opt_myisam_log) - (void) mi_log( 1 ); - ft_init_stopwords(); - - /* - init signals & alarm - After this we can't quit by a simple unireg_abort - */ error_handler_hook = my_message_sql; - if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) || - pthread_key_create(&THR_MALLOC,NULL)) - { - sql_print_error("Can't create thread-keys"); - exit(1); - } + opt_noacl = 1; // No permissions - if (acl_init((THD*) 0,opt_noacl)) + if (acl_init((THD *)0, opt_noacl)) { mysql_server_end(); return 1; } if (!opt_noacl) - (void) grant_init((THD*) 0); + (void) grant_init((THD *)0); init_max_user_conn(); init_update_queries(); @@ -615,7 +275,6 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) return 0; } - void STDCALL mysql_server_end() { my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR)); @@ -631,31 +290,222 @@ void STDCALL mysql_server_end() my_end(0); } -my_bool STDCALL mysql_thread_init() +} /* extern "C" */ + +C_MODE_START +void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db) { -#ifdef THREAD - return my_thread_init(); -#else - return 0; -#endif + THD *thd = (THD *)mysql->thd; + thd->mysql= mysql; } -void STDCALL mysql_thread_end() +void *create_embedded_thd(int client_flag, char *db) { -#ifdef THREAD - my_thread_end(); -#endif + THD * thd= new THD; + thd->thread_id= thread_id++; + + if (thd->store_globals()) + { + fprintf(stderr,"store_globals failed.\n"); + return NULL; + } + + thd->mysys_var= my_thread_var; + thd->dbug_thread_id= my_thread_id(); + thd->thread_stack= (char*) &thd; + + thd->proc_info=0; // Remove 'login' + thd->command=COM_SLEEP; + thd->version=refresh_version; + thd->set_time(); + init_sql_alloc(&thd->mem_root,8192,8192); + thd->client_capabilities= client_flag; + + thd->db= db; + thd->db_length= db ? strip_sp(db) : 0; + thd->db_access= DB_ACLS; + thd->master_access= ~NO_ACCESS; + thd->net.query_cache_query= 0; + + return thd; } -void start_embedded_connection(NET * net) +C_MODE_END + +bool Protocol::send_fields(List<Item> *list, uint flag) { - start_embedded_conn1(net); + List_iterator_fast<Item> it(*list); + Item *item; + MYSQL_FIELD *field, *client_field; + MYSQL *mysql= thd->mysql; + + DBUG_ENTER("send_fields"); + + field_count= list->elements; + if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ + sizeof(ulong) * (field_count + 1), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + mysql->result->lengths= (ulong *)(mysql->result + 1); + + mysql->field_count=field_count; + alloc= &mysql->field_alloc; + field= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD) * field_count); + if (!field) + goto err; + + client_field= field; + while ((item= it++)) + { + Send_field server_field; + item->make_field(&server_field); + + client_field->db= strdup_root(alloc, server_field.db_name); + client_field->table= strdup_root(alloc, server_field.table_name); + client_field->name= strdup_root(alloc, server_field.col_name); + client_field->org_table= strdup_root(alloc, server_field.org_table_name); + client_field->org_name= strdup_root(alloc, server_field.org_col_name); + client_field->length= server_field.length; + client_field->type= server_field.type; + client_field->flags= server_field.flags; + client_field->decimals= server_field.decimals; + client_field->db_length= strlen(client_field->db); + client_field->table_length= strlen(client_field->table); + client_field->name_length= strlen(client_field->name); + client_field->org_name_length= strlen(client_field->org_name); + client_field->org_table_length= strlen(client_field->org_table); + client_field->charsetnr= server_field.charsetnr; + + if (INTERNAL_NUM_FIELD(client_field)) + client_field->flags|= NUM_FLAG; + + if (flag & 2) + { + char buff[80]; + String tmp(buff, sizeof(buff), default_charset_info), *res; + + if (!(res=item->val_str(&tmp))) + client_field->def= strdup_root(alloc, ""); + else + client_field->def= strdup_root(alloc, tmp.ptr()); + } + else + client_field->def=0; + client_field->max_length= 0; + ++client_field; + } + mysql->result->fields = field; + + if (!(mysql->result->data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + + init_alloc_root(&mysql->result->data->alloc,8192,0); /* Assume rowlength < 8192 */ + mysql->result->data->alloc.min_malloc=sizeof(MYSQL_ROWS); + mysql->result->data->rows=0; + mysql->result->data->fields=field_count; + mysql->result->field_count=field_count; + mysql->result->data->prev_ptr= &mysql->result->data->data; + + mysql->result->field_alloc= mysql->field_alloc; + mysql->result->current_field=0; + mysql->result->current_row=0; + + DBUG_RETURN(prepare_for_send(list)); + err: + send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ } -void end_embedded_connection(NET * net) +bool Protocol::send_records_num(List<Item> *list, ulonglong records) { - THD *thd = (THD *) net->vio->dest_thd; - delete thd; + return false; } -} /* extern "C" */ +bool Protocol::write() +{ + *next_field= 0; + return false; +} + +void +send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message) +{ + DBUG_ENTER("send_ok"); + MYSQL *mysql= current_thd->mysql; + mysql->affected_rows= affected_rows; + mysql->insert_id= id; + if (message) + { + strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1); + } + DBUG_VOID_RETURN; +} + +void +send_eof(THD *thd, bool no_flush) +{ +} + +void Protocol_simple::prepare_for_resend() +{ + MYSQL_ROWS *cur; + MYSQL_DATA *result= thd->mysql->result->data; + + DBUG_ENTER("send_data"); + + alloc= &result->alloc; + result->rows++; + if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *)))) + { + my_error(ER_OUT_OF_RESOURCES,MYF(0)); + DBUG_VOID_RETURN; + } + cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS)); + + *result->prev_ptr= cur; + result->prev_ptr= &cur->next; + next_field=cur->data; + next_mysql_field= thd->mysql->result->fields; + + DBUG_VOID_RETURN; +} + +bool Protocol_simple::store_null() +{ + *(next_field++)= NULL; + ++next_mysql_field; + return false; +} + +bool Protocol::net_store_data(const char *from, uint length) +{ + if (!(*next_field=alloc_root(alloc, length + 1))) + return true; + memcpy(*next_field, from, length); + (*next_field)[length]= 0; + if (next_mysql_field->max_length < length) + next_mysql_field->max_length=length; + ++next_field; + ++next_mysql_field; + + return false; +} + +#if 0 +/* The same as Protocol::net_store_data but does the converstion +*/ +bool Protocol::convert_str(const char *from, uint length) +{ + if (!(*next_field=alloc_root(alloc, length + 1))) + return true; + convert->store_dest(*next_field, from, length); + (*next_field)[length]= 0; + if (next_mysql_field->max_length < length) + next_mysql_field->max_length=length; + ++next_field; + ++next_mysql_field; + + return false; +} +#endif diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c deleted file mode 100644 index ccad6ac8b7e..00000000000 --- a/libmysqld/lib_vio.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright (C) 2000 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; either version 2 of the License, or - (at your option) any later version. - - 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 */ - -/* - Note that we can't have assertion on file descriptors; The reason for - this is that during mysql shutdown, another thread can close a file - we are working on. In this case we should just return read errors from - the file descriptior. -*/ - -#include <my_global.h> -#include "mysql_embed.h" -#include "mysql.h" - -#ifndef HAVE_VIO /* is Vio enabled */ - -#include <errno.h> -#include <my_sys.h> -#include <violite.h> -#include <my_sys.h> -#include <my_net.h> -#include <m_string.h> -#include <assert.h> - -#ifndef __WIN__ -#define HANDLE void * -#endif - -struct st_vio -{ - my_socket sd; /* my_socket - real or imaginary */ - HANDLE hPipe; - my_bool localhost; /* Are we from localhost? */ - int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */ - struct sockaddr_in local; /* Local internet address */ - struct sockaddr_in remote; /* Remote internet address */ - enum enum_vio_type type; /* Type of connection */ - char desc[30]; /* String description */ - void *dest_thd; - char *packets, **last_packet; - char *where_in_packet, *end_of_packet; - my_bool reading; - MEM_ROOT root; -}; - -/* Initialize the communication buffer */ - -Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) -{ - DBUG_ENTER("vio_new"); - Vio * vio; - - if ((vio= (Vio *) my_malloc(sizeof(*vio),MYF(MY_WME|MY_ZEROFILL)))) - { - init_alloc_root(&vio->root, 8192, 8192); - vio->root.min_malloc = sizeof(char *) + 4; - vio->last_packet = &vio->packets; - } - DBUG_RETURN(vio); -} - - -#ifdef __WIN__ - -Vio *vio_new_win32pipe(HANDLE hPipe) -{ - return (NULL); -} - -#endif - -void vio_delete(Vio * vio) -{ - DBUG_ENTER("vio_delete"); - if (vio) - { - if (vio->type != VIO_CLOSED) - vio_close(vio); - free_root(&vio->root, MYF(0)); - my_free((gptr) vio, MYF(0)); - } - DBUG_VOID_RETURN; -} - -void vio_reset(Vio *vio) -{ - DBUG_ENTER("vio_reset"); - free_root(&vio->root, MYF(MY_KEEP_PREALLOC)); - vio->packets = vio->where_in_packet = vio->end_of_packet = 0; - vio->last_packet = &vio->packets; - DBUG_VOID_RETURN; -} - -int vio_errno(Vio *vio __attribute__((unused))) -{ - return socket_errno; /* On Win32 this mapped to WSAGetLastError() */ -} - -int vio_read(Vio * vio, gptr buf, int size) -{ - vio->reading = 1; - if (vio->where_in_packet >= vio->end_of_packet) - { - DBUG_ASSERT(vio->packets); - vio->where_in_packet = vio->packets + sizeof(char *) + 4; - vio->end_of_packet = vio->where_in_packet + - uint4korr(vio->packets + sizeof(char *)); - vio->packets = *(char **)vio->packets; - } - if (vio->where_in_packet + size > vio->end_of_packet) - size = vio->end_of_packet - vio->where_in_packet; - memcpy(buf, vio->where_in_packet, size); - vio->where_in_packet += size; - return (size); -} - -int vio_write(Vio * vio, const gptr buf, int size) -{ - DBUG_ENTER("vio_write"); - char *packet; - if (vio->reading) - { - vio->reading = 0; - vio_reset(vio); - } - if ((packet = alloc_root(&vio->root, sizeof(char*) + 4 + size))) - { - *vio->last_packet = packet; - vio->last_packet = (char **)packet; - *((char **)packet) = 0; /* Set forward link to 0 */ - packet += sizeof(char *); - int4store(packet, size); - memcpy(packet + 4, buf, size); - } - else - size= -1; - DBUG_RETURN(size); -} - -int vio_blocking(Vio * vio, my_bool set_blocking_mode, my_bool *old_mode) -{ - return (0); -} - -my_bool -vio_is_blocking(Vio * vio) -{ - return(0); -} - -int vio_fastsend(Vio * vio) -{ - return(0); -} - -int vio_keepalive(Vio* vio, my_bool set_keep_alive) -{ - return (0); -} - - -my_bool -vio_should_retry(Vio * vio __attribute__((unused))) -{ - int en = socket_errno; - return (en == SOCKET_EAGAIN || en == SOCKET_EINTR || - en == SOCKET_EWOULDBLOCK); -} - - -int vio_close(Vio * vio) -{ - return(0); -} - - -const char *vio_description(Vio * vio) -{ - return "embedded vio"; -} - -enum enum_vio_type vio_type(Vio* vio) -{ - return VIO_CLOSED; -} - -my_socket vio_fd(Vio* vio) -{ - return 0; -} - - -my_bool vio_peer_addr(Vio * vio, char *buf, uint16 *port) -{ - return(0); -} - - -void vio_in_addr(Vio *vio, struct in_addr *in) -{ -} - -my_bool vio_poll_read(Vio *vio,uint timeout) -{ - return 0; -} - - -void vio_timeout(Vio *vio __attribute__((unused)), - uint timeout __attribute__((unused))) -{ -} -#endif /* HAVE_VIO */ diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 70ac4ce46c5..05e5ff59b55 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -46,11 +46,7 @@ #define INADDR_NONE -1 #endif -static my_bool mysql_client_init=0; -uint mysql_port=0; -my_string mysql_unix_port=0; - -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS) +#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41) #if defined(MSDOS) || defined(__WIN__) #define ERRNO WSAGetLastError() @@ -62,252 +58,27 @@ my_string mysql_unix_port=0; #define closesocket(A) close(A) #endif -static void mysqld_once_init(void); -static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields, - uint field_count); -static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, - ulong *lengths); -static void end_server(MYSQL *mysql); -static void read_user_name(char *name); -static void append_wild(char *to,char *end,const char *wild); -static int send_file_to_server(MYSQL *mysql,const char *filename); -static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, - const char *from, ulong length); - -#define init_sigpipe_variables -#define set_sigpipe(mysql) -#define reset_sigpipe(mysql) - -/***************************************************************************** -** read a packet from server. Give error message if socket was down -** or packet is an error message -*****************************************************************************/ +void free_old_query(MYSQL *mysql); +my_bool STDCALL +emb_advanced_command(MYSQL *mysql, enum enum_server_command command, + const char *header, ulong header_length, + const char *arg, ulong arg_length, my_bool skip_check); -ulong -net_safe_read(MYSQL *mysql) -{ - NET *net= &mysql->net; - uint len=0; - //init_sigpipe_variables - /* Don't give sigpipe errors if the client doesn't want them */ - set_sigpipe(mysql); - if (net->vio != 0) - len=my_net_read(net); - reset_sigpipe(mysql); - if (len == packet_error || len == 0) - { - DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d", - vio_description(net->vio),len)); - end_server(mysql); - net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ? - CR_NET_PACKET_TOO_LARGE: - CR_SERVER_LOST); - strmov(net->last_error,ER(net->last_errno)); - return(packet_error); - } - if (net->read_pos[0] == 255) - { - - if (len > 3) - { - char *pos=(char*) net->read_pos+1; - if (mysql->protocol_version > 9) - { /* New client protocol */ - net->last_errno=uint2korr(pos); - pos+=2; - len-=2; - } - else - { - net->last_errno=CR_UNKNOWN_ERROR; - len--; - } - (void) strmake(net->last_error,(char*) pos, - min(len,sizeof(net->last_error)-1)); - } - else - { - net->last_errno=CR_UNKNOWN_ERROR; - (void) strmov(net->last_error,ER(net->last_errno)); - } - DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno, - net->last_error)); - return(packet_error); - } - return len; -} +/* From client.c */ +void mysql_read_default_options(struct st_mysql_options *options, + const char *filename,const char *group); +MYSQL * STDCALL +cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, + const char *passwd, const char *db, + uint port, const char *unix_socket,ulong client_flag); - -/* Get the length of next field. Change parameter to point at fieldstart */ -static ulong -net_field_length(uchar **packet) -{ - reg1 uchar *pos= *packet; - if (*pos < 251) - { - (*packet)++; - return (ulong) *pos; - } - if (*pos == 251) - { - (*packet)++; - return NULL_LENGTH; - } - if (*pos == 252) - { - (*packet)+=3; - return (ulong) uint2korr(pos+1); - } - if (*pos == 253) - { - (*packet)+=4; - return (ulong) uint3korr(pos+1); - } - (*packet)+=9; /* Must be 254 when here */ - return (ulong) uint4korr(pos+1); -} - -/* Same as above, but returns ulonglong values */ - -static my_ulonglong -net_field_length_ll(uchar **packet) -{ - reg1 uchar *pos= *packet; - if (*pos < 251) - { - (*packet)++; - return (my_ulonglong) *pos; - } - if (*pos == 251) - { - (*packet)++; - return (my_ulonglong) NULL_LENGTH; - } - if (*pos == 252) - { - (*packet)+=3; - return (my_ulonglong) uint2korr(pos+1); - } - if (*pos == 253) - { - (*packet)+=4; - return (my_ulonglong) uint3korr(pos+1); - } - (*packet)+=9; /* Must be 254 when here */ -#ifdef NO_CLIENT_LONGLONG - return (my_ulonglong) uint4korr(pos+1); -#else - return (my_ulonglong) uint8korr(pos+1); -#endif -} - - -static void free_rows(MYSQL_DATA *cur) -{ - if (cur) - { - free_root(&cur->alloc,MYF(0)); - my_free((gptr) cur,MYF(0)); - } -} - - -int -simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, - ulong length, my_bool skipp_check) -{ - NET *net= &mysql->net; - int result= -1; - - /* Check that we are calling the client functions in right order */ - if (mysql->status != MYSQL_STATUS_READY) - { - strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - goto end; - } - - /* Clear result variables */ - mysql->net.last_error[0]=0; - mysql->net.last_errno=0; - mysql->info=0; - mysql->affected_rows= ~(my_ulonglong) 0; - - /* Clear receive buffer and vio packet list */ - net_clear(net); - vio_reset(net->vio); - - result = lib_dispatch_command(command, net, arg,length); - if (!skipp_check) - result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ? - -1 : 0); - end: - return result; -} - - -static void free_old_query(MYSQL *mysql) -{ - DBUG_ENTER("free_old_query"); - if (mysql->fields) - free_root(&mysql->field_alloc,MYF(0)); - init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */ - mysql->fields=0; - mysql->field_count=0; /* For API */ - DBUG_VOID_RETURN; -} +void STDCALL cli_mysql_close(MYSQL *mysql); #ifdef HAVE_GETPWUID struct passwd *getpwuid(uid_t); char* getlogin(void); #endif -#if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) -static void read_user_name(char *name) -{ - DBUG_ENTER("read_user_name"); - if (geteuid() == 0) - (void) strmov(name,"root"); /* allow use of surun */ - else - { -#ifdef HAVE_GETPWUID - struct passwd *skr; - const char *str; -/*#ifdef __cplusplus - extern "C" struct passwd *getpwuid(uid_t); - extern "C" { char* getlogin(void); } -#else - char * getlogin(); - struct passwd *getpwuid(uid_t); -#endif -*/ - if ((str=getlogin()) == NULL) - { - if ((skr=getpwuid(geteuid())) != NULL) - str=skr->pw_name; - else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) && - !(str=getenv("LOGIN"))) - str="UNKNOWN_USER"; - } - (void) strmake(name,str,USERNAME_LENGTH); -#elif HAVE_CUSERID - (void) cuserid(name); -#else - strmov(name,"UNKNOWN_USER"); -#endif - } - DBUG_VOID_RETURN; -} - -#else /* If MSDOS || VMS */ - -static void read_user_name(char *name) -{ - char *str=getenv("USER"); - strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */ -} - -#endif - #ifdef __WIN__ static my_bool is_NT(void) { @@ -316,468 +87,95 @@ static my_bool is_NT(void) } #endif -/* -** Expand wildcard to a sql string -*/ - -static void -append_wild(char *to, char *end, const char *wild) -{ - end-=5; /* Some extra */ - if (wild && wild[0]) - { - to=strmov(to," like '"); - while (*wild && to < end) - { - if (*wild == '\\' || *wild == '\'') - *to++='\\'; - *to++= *wild++; - } - if (*wild) /* Too small buffer */ - *to++='%'; /* Nicer this way */ - to[0]='\''; - to[1]=0; - } -} - - - -/************************************************************************** -** Init debugging if MYSQL_DEBUG environment variable is found -**************************************************************************/ - -void STDCALL -mysql_debug(const char *debug) -{ -#ifndef DBUG_OFF - char *env; - if (_db_on_) - return; /* Already using debugging */ - if (debug) - { - DEBUGGER_ON; - DBUG_PUSH(debug); - } - else if ((env = getenv("MYSQL_DEBUG"))) - { - DEBUGGER_ON; - DBUG_PUSH(env); -#if !defined(_WINVER) && !defined(WINVER) - puts("\n-------------------------------------------------------"); - puts("MYSQL_DEBUG found. libmysql started with the following:"); - puts(env); - puts("-------------------------------------------------------\n"); -#else - { - char buff[80]; - strmov(strmov(buff,"libmysql: "),env); - MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK); - } -#endif - } -#endif -} - /************************************************************************** ** Shut down connection **************************************************************************/ -static void -end_server(MYSQL *mysql) +static void end_server(MYSQL *mysql) { DBUG_ENTER("end_server"); - if (mysql->net.vio != 0) - { - end_embedded_connection(&mysql->net); - mysql->net.vio= 0; /* Marker */ - } - net_end(&mysql->net); free_old_query(mysql); DBUG_VOID_RETURN; } +/************************************************************************** +** Connect to sql server +** If host == 0 then use localhost +**************************************************************************/ -void STDCALL -mysql_free_result(MYSQL_RES *result) -{ - DBUG_ENTER("mysql_free_result"); - DBUG_PRINT("enter",("mysql_res: %lx",result)); - if (result) - { - if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) - { - DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows")); - for (;;) - { - uint pkt_len; - if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error) - break; - if (pkt_len == 1 && result->handle->net.read_pos[0] == 254) - break; /* End of data */ - } - result->handle->status=MYSQL_STATUS_READY; - } - free_rows(result->data); - if (result->fields) - free_root(&result->field_alloc,MYF(0)); - if (result->row) - my_free((gptr) result->row,MYF(0)); - my_free((gptr) result,MYF(0)); - } - DBUG_VOID_RETURN; -} - - -/**************************************************************************** -** Get options from my.cnf -****************************************************************************/ - -static const char *default_options[]= -{"port","socket","compress","password","pipe", "timeout", "user", - "init-command", "host", "database", "debug", "return-found-rows", - "ssl_key" ,"ssl_cert" ,"ssl_ca" ,"ssl_capath", - "character-set-dir", "default-character-set", - NullS -}; - -static TYPELIB option_types={array_elements(default_options)-1, - "options",default_options}; - -static void mysql_read_default_options(struct st_mysql_options *options, - const char *filename,const char *group) -{ - int argc; - char *argv_buff[1],**argv; - const char *groups[3]; - DBUG_ENTER("mysql_read_default_options"); - DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL")); - - argc=1; argv=argv_buff; argv_buff[0]= (char*) "client"; - groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; - - load_defaults(filename, groups, &argc, &argv); - if (argc != 1) /* If some default option */ - { - char **option=argv; - while (*++option) - { - /* DBUG_PRINT("info",("option: %s",option[0])); */ - if (option[0][0] == '-' && option[0][1] == '-') - { - char *end=strcend(*option,'='); - char *opt_arg=0; - if (*end) - { - opt_arg=end+1; - *end=0; /* Remove '=' */ - } - switch (find_type(*option+2,&option_types,2)) { - case 1: /* port */ - if (opt_arg) - options->port=atoi(opt_arg); - break; - case 2: /* socket */ - if (opt_arg) - { - my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR)); - options->unix_socket=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 3: /* compress */ - options->compress=1; - break; - case 4: /* password */ - if (opt_arg) - { - my_free(options->password,MYF(MY_ALLOW_ZERO_PTR)); - options->password=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 5: /* pipe */ - options->named_pipe=1; /* Force named pipe */ - break; - case 6: /* timeout */ - if (opt_arg) - options->connect_timeout=atoi(opt_arg); - break; - case 7: /* user */ - if (opt_arg) - { - my_free(options->user,MYF(MY_ALLOW_ZERO_PTR)); - options->user=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 8: /* init-command */ - if (opt_arg) - { - my_free(options->init_command,MYF(MY_ALLOW_ZERO_PTR)); - options->init_command=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 9: /* host */ - if (opt_arg) - { - my_free(options->host,MYF(MY_ALLOW_ZERO_PTR)); - options->host=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 10: /* database */ - if (opt_arg) - { - my_free(options->db,MYF(MY_ALLOW_ZERO_PTR)); - options->db=my_strdup(opt_arg,MYF(MY_WME)); - } - break; - case 11: /* debug */ - mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace"); - break; - case 12: /* return-found-rows */ - options->client_flag|=CLIENT_FOUND_ROWS; - break; - case 13: /* Ignore SSL options */ - case 14: - case 15: - case 16: - break; - case 17: /* charset-lib */ - my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR)); - options->charset_dir = my_strdup(opt_arg, MYF(MY_WME)); - break; - case 18: - my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR)); - options->charset_name = my_strdup(opt_arg, MYF(MY_WME)); - break; - default: - DBUG_PRINT("warning",("unknown option: %s",option[0])); - } - } - } - } - free_defaults(argv); - DBUG_VOID_RETURN; -} - - -/*************************************************************************** -** Change field rows to field structs -***************************************************************************/ - -static MYSQL_FIELD * -unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, - my_bool default_value, my_bool long_flag_protocol) +MYSQL * STDCALL +mysql_connect(MYSQL *mysql,const char *host, + const char *user, const char *passwd) { - MYSQL_ROWS *row; - MYSQL_FIELD *field,*result; - DBUG_ENTER("unpack_fields"); - - field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields); - if (!result) - DBUG_RETURN(0); - - for (row=data->data; row ; row = row->next,field++) + MYSQL *res; + mysql=mysql_init(mysql); /* Make it thread safe */ { - field->table= strdup_root(alloc,(char*) row->data[0]); - field->name= strdup_root(alloc,(char*) row->data[1]); - field->length= (uint) uint3korr(row->data[2]); - field->type= (enum enum_field_types) (uchar) row->data[3][0]; - if (long_flag_protocol) - { - field->flags= uint2korr(row->data[4]); - field->decimals=(uint) (uchar) row->data[4][2]; - } - else + DBUG_ENTER("mysql_connect"); + if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0))) { - field->flags= (uint) (uchar) row->data[4][0]; - field->decimals=(uint) (uchar) row->data[4][1]; + if (mysql->free_me) + my_free((gptr) mysql,MYF(0)); } - if (INTERNAL_NUM_FIELD(field)) - field->flags|= NUM_FLAG; - if (default_value && row->data[5]) - field->def=strdup_root(alloc,(char*) row->data[5]); - else - field->def=0; - field->max_length= 0; + DBUG_RETURN(res); } - free_rows(data); /* Free old data */ - DBUG_RETURN(result); } - -/* Read all rows (fields or data) from server */ - -static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - uint fields) +static inline int mysql_init_charset(MYSQL *mysql) { - uint field,pkt_len; - ulong len; - uchar *cp; - char *to; - MYSQL_DATA *result; - MYSQL_ROWS **prev_ptr,*cur; - NET *net = &mysql->net; - DBUG_ENTER("read_rows"); + char charset_name_buff[16], *charset_name; - if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error) - DBUG_RETURN(0); - if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), - MYF(MY_WME | MY_ZEROFILL)))) + if ((charset_name=mysql->options.charset_name)) { - net->last_errno=CR_OUT_OF_MEMORY; - strmov(net->last_error,ER(net->last_errno)); - DBUG_RETURN(0); + const char *save=charsets_dir; + if (mysql->options.charset_dir) + charsets_dir=mysql->options.charset_dir; + mysql->charset=get_charset_by_name(mysql->options.charset_name, + MYF(MY_WME)); + charsets_dir=save; } - init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ - result->alloc.min_malloc=sizeof(MYSQL_ROWS); - prev_ptr= &result->data; - result->rows=0; - result->fields=fields; - - while (*(cp=net->read_pos) != 254 || pkt_len != 1) + else if (mysql->server_language) { - result->rows++; - if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc, - sizeof(MYSQL_ROWS))) || - !(cur->data= ((MYSQL_ROW) - alloc_root(&result->alloc, - (fields+1)*sizeof(char *)+pkt_len)))) - { - free_rows(result); - net->last_errno=CR_OUT_OF_MEMORY; - strmov(net->last_error,ER(net->last_errno)); - DBUG_RETURN(0); - } - *prev_ptr=cur; - prev_ptr= &cur->next; - to= (char*) (cur->data+fields+1); - for (field=0 ; field < fields ; field++) - { - if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH) - { /* null field */ - cur->data[field] = 0; - } - else - { - cur->data[field] = to; - memcpy(to,(char*) cp,len); to[len]=0; - to+=len+1; - cp+=len; - if (mysql_fields) - { - if (mysql_fields[field].max_length < len) - mysql_fields[field].max_length=len; - } - } - } - cur->data[field]=to; /* End of last field */ - if ((pkt_len=net_safe_read(mysql)) == packet_error) - { - free_rows(result); - DBUG_RETURN(0); - } + charset_name=charset_name_buff; + sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */ + mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME)); } - *prev_ptr=0; /* last pointer is null */ - DBUG_PRINT("exit",("Got %d rows",result->rows)); - DBUG_RETURN(result); -} - - -/* -** Read one row. Uses packet buffer as storage for fields. -** When next packet is read, the previous field values are destroyed -*/ - - -static int -read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) -{ - uint field; - ulong pkt_len,len; - uchar *pos,*prev_pos; + else + mysql->charset=default_charset_info; - if ((pkt_len=net_safe_read(mysql)) == packet_error) - return -1; - if (pkt_len == 1 && mysql->net.read_pos[0] == 254) - return 1; /* End of data */ - prev_pos= 0; /* allowed to write at packet[-1] */ - pos=mysql->net.read_pos; - for (field=0 ; field < fields ; field++) + if (!mysql->charset) { - if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH) - { /* null field */ - row[field] = 0; - *lengths++=0; - } + mysql->net.last_errno=CR_CANT_READ_CHARSET; + strmov(mysql->net.sqlstate, "HY0000"); + if (mysql->options.charset_dir) + sprintf(mysql->net.last_error,ER(mysql->net.last_errno), + charset_name ? charset_name : "unknown", + mysql->options.charset_dir); else { - row[field] = (char*) pos; - pos+=len; - *lengths++=len; + char cs_dir_name[FN_REFLEN]; + get_charsets_dir(cs_dir_name); + sprintf(mysql->net.last_error,ER(mysql->net.last_errno), + charset_name ? charset_name : "unknown", + cs_dir_name); } - if (prev_pos) - *prev_pos=0; /* Terminate prev field */ - prev_pos=pos; + return mysql->net.last_errno; } - row[field]=(char*) prev_pos+1; /* End of last field */ - *prev_pos=0; /* Terminate last field */ return 0; } -/**************************************************************************** -** Init MySQL structure or allocate one -****************************************************************************/ - -MYSQL * STDCALL -mysql_init(MYSQL *mysql) -{ - mysqld_once_init(); - if (!mysql) - { - if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL)))) - return 0; - mysql->free_me=1; - mysql->net.vio = 0; - } - else - bzero((char*) (mysql),sizeof(*(mysql))); - return mysql; -} - - -static void mysqld_once_init() -{ - if (!mysql_client_init) - { - mysql_client_init=1; - my_init(); /* Will init threads */ - init_client_errs(); - mysql_port = MYSQL_PORT; - mysql_debug(NullS); - } -#ifdef THREAD - else - my_thread_init(); /* Init if new thread */ -#endif -} - /************************************************************************** -** Connect to sql server -** If host == 0 then use localhost + Get column lengths of the current row + If one uses mysql_use_result, res->lengths contains the length information, + else the lengths are calculated from the offset between pointers. **************************************************************************/ -MYSQL * STDCALL -mysql_connect(MYSQL *mysql,const char *host, - const char *user, const char *passwd) -{ - MYSQL *res; - mysql=mysql_init(mysql); /* Make it thread safe */ +static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count) +{ + MYSQL_ROW end; + + for (end=column + field_count; column != end ; column++,to++) { - DBUG_ENTER("mysql_connect"); - if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0))) - { - if (mysql->free_me) - my_free((gptr) mysql,MYF(0)); - } - DBUG_RETURN(res); + *to= *column ? strlen(*column) : 0; } } @@ -787,33 +185,39 @@ mysql_connect(MYSQL *mysql,const char *host, ** before calling mysql_real_connect ! */ +static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql); +static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql); +static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql); + +static MYSQL_METHODS embedded_methods= +{ + emb_mysql_read_query_result, + emb_advanced_command, + emb_mysql_store_result, + emb_mysql_use_result, + emb_fetch_lengths +}; + MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, - uint port, const char *unix_socket,uint client_flag) + uint port, const char *unix_socket,ulong client_flag) { - char buff[100],charset_name_buff[16],*end,*host_info, *charset_name; - uint pkt_length; - ulong max_allowed_packet; - NET *net= &mysql->net; + char *db_name; DBUG_ENTER("mysql_real_connect"); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", db ? db : "(Null)", user ? user : "(Null)")); - /* - Check mysql_server_init was called. - This code shouldn't be merged to 4.1 - */ - if (!server_inited) - { - net->last_errno=CR_UNKNOWN_ERROR; - strmov(net->last_error,ER(net->last_errno)); - goto error; - } + if (mysql->options.methods_to_use == MYSQL_OPT_USE_REMOTE_CONNECTION || + (mysql->options.methods_to_use == MYSQL_OPT_GUESS_CONNECTION && + host && strcmp(host,LOCAL_HOST))) + cli_mysql_real_connect(mysql, host, user, + passwd, db, port, unix_socket, client_flag); + + mysql->methods= &embedded_methods; - net->vio = 0; /* If something goes wrong */ /* use default options */ if (mysql->options.my_cnf_file || mysql->options.my_cnf_group) { @@ -826,186 +230,53 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql->options.my_cnf_file=mysql->options.my_cnf_group=0; } - /* Some empty-string-tests are done because of ODBC */ - if (!host || !host[0]) - host=mysql->options.host; - if (!user || !user[0]) - user=mysql->options.user; - if (!passwd) - { - passwd=mysql->options.password; - } if (!db || !db[0]) db=mysql->options.db; + port=0; unix_socket=0; - mysql->reconnect=1; /* Reconnect as default */ - mysql->server_status=SERVER_STATUS_AUTOCOMMIT; - host_info=(char*) ER(CR_EMBEDDED_CONNECTION); - if (my_net_init(net, net->vio)) - { - vio_delete(net->vio); - net->last_errno=CR_OUT_OF_MEMORY; - strmov(net->last_error,ER(net->last_errno)); - goto error; - } - - /* Get version info */ - mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */ - start_embedded_connection(net); - - if ((pkt_length=net_safe_read(mysql)) == packet_error) - goto error; + db_name = db ? my_strdup(db,MYF(MY_WME)) : NULL; - /* Check if version of protocoll matches current one */ - - mysql->protocol_version= net->read_pos[0]; - DBUG_DUMP("packet",(char*) net->read_pos,10); - DBUG_PRINT("info",("mysql protocol version %d, server=%d", - PROTOCOL_VERSION, mysql->protocol_version)); - if (mysql->protocol_version != PROTOCOL_VERSION && - mysql->protocol_version != PROTOCOL_VERSION-1) - { - net->last_errno= CR_VERSION_ERROR; - sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version, - PROTOCOL_VERSION); - goto error; - } - end=strend((char*) net->read_pos+1); - mysql->thread_id=uint4korr(end+1); - end+=5; - strmake(mysql->scramble_buff,end,8); - end+=9; - if (pkt_length >= (uint) (end+1 - (char*) net->read_pos)) - mysql->server_capabilities=uint2korr(end); - if (pkt_length >= (uint) (end+18 - (char*) net->read_pos)) - { - /* New protocol with 16 bytes to describe server characteristics */ - mysql->server_language=end[2]; - mysql->server_status=uint2korr(end+3); - } - - /* Set character set */ - if ((charset_name=mysql->options.charset_name)) - { - const char *save=charsets_dir; - if (mysql->options.charset_dir) - charsets_dir=mysql->options.charset_dir; - mysql->charset=get_charset_by_name(mysql->options.charset_name, - MYF(MY_WME)); - charsets_dir=save; - } - else if (mysql->server_language) - { - charset_name=charset_name_buff; - sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */ - mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME)); - } - else - mysql->charset=default_charset_info; + mysql->thd= create_embedded_thd(client_flag, db_name); - if (!mysql->charset) - { - net->last_errno=CR_CANT_READ_CHARSET; - if (mysql->options.charset_dir) - sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", - mysql->options.charset_dir); - else - { - char cs_dir_name[FN_REFLEN]; - get_charsets_dir(cs_dir_name); - sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", - cs_dir_name); - } - goto error; - } + init_embedded_mysql(mysql, client_flag, db_name); - /* Save connection information */ - if (!user) user=""; - if (!passwd) passwd=""; - host=LOCAL_HOST; - if (!my_multi_malloc(MYF(0), - &mysql->host_info, (uint) strlen(host_info)+1, - &mysql->host, (uint) strlen(host)+1, - &mysql->unix_socket,unix_socket ? - (uint) strlen(unix_socket)+1 : (uint) 1, - &mysql->server_version, - (uint) (end - (char*) net->read_pos), - NullS) || - !(mysql->user=my_strdup(user,MYF(0))) || - !(mysql->passwd=my_strdup(passwd,MYF(0)))) - { - strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY)); + if (mysql_init_charset(mysql)) goto error; - } - strmov(mysql->host_info,host_info); - strmov(mysql->host,host); - if (unix_socket) - strmov(mysql->unix_socket,unix_socket); - else - mysql->unix_socket=0; - strmov(mysql->server_version,(char*) net->read_pos+1); - mysql->port=port; - mysql->client_flag=client_flag | mysql->options.client_flag; - DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d", - mysql->server_version,mysql->server_capabilities, - mysql->server_status)); /* Send client information for access check */ client_flag|=CLIENT_CAPABILITIES; client_flag&= ~CLIENT_COMPRESS; if (db) client_flag|=CLIENT_CONNECT_WITH_DB; - int2store(buff,client_flag); - mysql->client_flag=client_flag; + mysql->server_status= SERVER_STATUS_AUTOCOMMIT; - max_allowed_packet=net->max_packet_size; - int3store(buff+2,max_allowed_packet); - if (user && user[0]) - strmake(buff+5,user,32); - else - read_user_name((char*) buff+5); -#ifdef _CUSTOMCONFIG_ -#include "_cust_libmysql.h"; -#endif - DBUG_PRINT("info",("user: %s",buff+5)); - end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - - if (db) + if (mysql->options.init_commands) { - end=strmov(end+1,db); - mysql->db=my_strdup(db,MYF(MY_WME)); - db=0; - } - if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net)) - goto error; + DYNAMIC_ARRAY *init_commands= mysql->options.init_commands; + char **ptr= (char**)init_commands->buffer; + char **end= ptr + init_commands->elements; - lib_connection_phase(net,2); - - if( net_safe_read(mysql) == packet_error) - goto error; - if (db && mysql_select_db(mysql,db)) - goto error; - if (mysql->options.init_command) - { - my_bool reconnect=mysql->reconnect; - mysql->reconnect=0; - if (mysql_query(mysql,mysql->options.init_command)) - goto error; - mysql_free_result(mysql_use_result(mysql)); - mysql->reconnect=reconnect; + for (; ptr<end; ptr++) + { + MYSQL_RES *res; + if (mysql_query(mysql,*ptr)) + goto error; + if (mysql->fields) + { + if (!(res= mysql_use_result(mysql))) + goto error; + mysql_free_result(res); + } + } } DBUG_PRINT("exit",("Mysql handler: %lx",mysql)); - reset_sigpipe(mysql); DBUG_RETURN(mysql); error: - reset_sigpipe(mysql); - DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error)); + DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno, + mysql->net.last_error)); { /* Free alloced memory */ my_bool free_me=mysql->free_me; @@ -1018,81 +289,22 @@ error: } -/************************************************************************** -** Change user and database -**************************************************************************/ - -my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, - const char *passwd, const char *db) -{ - char buff[512],*pos=buff; - DBUG_ENTER("mysql_change_user"); - - if (!user) - user=""; - if (!passwd) - passwd=""; - - pos=strmov(pos,user)+1; - pos=scramble(pos, mysql->scramble_buff, passwd, - (my_bool) (mysql->protocol_version == 9)); - pos=strmov(pos+1,db ? db : ""); - if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0)) - DBUG_RETURN(1); - - my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); - - mysql->user= my_strdup(user,MYF(MY_WME)); - mysql->passwd=my_strdup(passwd,MYF(MY_WME)); - mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0; - DBUG_RETURN(0); -} - - -/************************************************************************** -** Set current database -**************************************************************************/ - -int STDCALL -mysql_select_db(MYSQL *mysql, const char *db) -{ - int error; - DBUG_ENTER("mysql_select_db"); - DBUG_PRINT("enter",("db: '%s'",db)); - - if ((error=simple_command(mysql,COM_INIT_DB,db,(ulong) strlen(db),0))) - DBUG_RETURN(error); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); - mysql->db=my_strdup(db,MYF(MY_WME)); - DBUG_RETURN(0); -} - - /************************************************************************* ** Send a QUIT to the server and close the connection ** If handle is alloced by mysql connect free it. *************************************************************************/ -void STDCALL -mysql_close(MYSQL *mysql) +void STDCALL mysql_close(MYSQL *mysql) { DBUG_ENTER("mysql_close"); + if (mysql->methods != &embedded_methods) + { + cli_mysql_close(mysql); + DBUG_VOID_RETURN; + } + if (mysql) /* Some simple safety */ { - if (mysql->net.vio != 0) - { - free_old_query(mysql); - mysql->status=MYSQL_STATUS_READY; /* Force command */ - simple_command(mysql,COM_QUIT,"",0,1); - end_server(mysql); - } - my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR)); @@ -1102,10 +314,18 @@ mysql_close(MYSQL *mysql) my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); + if (mysql->options.init_commands) + { + DYNAMIC_ARRAY *init_commands= mysql->options.init_commands; + char **ptr= (char**)init_commands->buffer; + char **end= ptr + init_commands->elements; + for (; ptr<end; ptr++) + my_free(*ptr,MYF(MY_WME)); + delete_dynamic(init_commands); + my_free((char*)init_commands,MYF(MY_WME)); + } /* Clear pointers for better safety */ - mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; bzero((char*) &mysql->options,sizeof(mysql->options)); - mysql->net.vio = 0; #ifdef HAVE_OPENSSL ((VioConnectorFd*)(mysql->connector_fd))->delete(); mysql->connector_fd = 0; @@ -1116,290 +336,43 @@ mysql_close(MYSQL *mysql) DBUG_VOID_RETURN; } - -/************************************************************************** -** Do a query. If query returned rows, free old rows. -** Read data by mysql_store_result or by repeat call of mysql_fetch_row -**************************************************************************/ - -int STDCALL -mysql_query(MYSQL *mysql, const char *query) -{ - return mysql_real_query(mysql,query, (ulong) strlen(query)); -} - -int STDCALL -mysql_send_query(MYSQL* mysql, const char* query, ulong length) -{ - return simple_command(mysql, COM_QUERY, query, length, 1); -} - - -int STDCALL -mysql_read_query_result(MYSQL *mysql) +static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql) { - uchar *pos; - ulong field_count; - MYSQL_DATA *fields; - uint length; - DBUG_ENTER("mysql_read_query_result"); - - if ((length=net_safe_read(mysql)) == packet_error) - DBUG_RETURN(-1); - free_old_query(mysql); /* Free old result */ -get_info: - pos=(uchar*) mysql->net.read_pos; - if ((field_count= net_field_length(&pos)) == 0) - { - mysql->affected_rows= net_field_length_ll(&pos); - mysql->insert_id= net_field_length_ll(&pos); - if (mysql->server_capabilities & CLIENT_TRANSACTIONS) - { - mysql->server_status=uint2korr(pos); pos+=2; - } - if (pos < mysql->net.read_pos+length && net_field_length(&pos)) - mysql->info=(char*) pos; - DBUG_RETURN(0); - } - if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ - { - int error=send_file_to_server(mysql,(char*) pos); - if ((length=net_safe_read(mysql)) == packet_error || error) - DBUG_RETURN(-1); - goto get_info; /* Get info packet */ - } - if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) - mysql->server_status|= SERVER_STATUS_IN_TRANS; - - mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ - if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5))) - DBUG_RETURN(-1); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, - (uint) field_count,0, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)))) - DBUG_RETURN(-1); - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->field_count=field_count; - DBUG_RETURN(0); -} - -/**************************************************************************** -* A modified version of connect(). connect2() allows you to specify -* a timeout value, in seconds, that we should wait until we -* derermine we can't connect to a particular host. If timeout is 0, -* my_connect() will behave exactly like connect(). -* -* Base version coded by Steve Bernacki, Jr. <steve@navinet.net> -*****************************************************************************/ - -int my_connect(my_socket s, const struct sockaddr *name, uint namelen, - uint timeout) -{ -#if defined(__WIN__) || defined(OS2) - return connect(s, (struct sockaddr*) name, namelen); -#else - int flags, res, s_err; - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - time_t start_time, now_time; - - /* If they passed us a timeout of zero, we should behave - * exactly like the normal connect() call does. - */ - - if (timeout == 0) - return connect(s, (struct sockaddr*) name, namelen); - - flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ -#ifdef O_NONBLOCK - fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ -#endif - - res = connect(s, (struct sockaddr*) name, namelen); - s_err = errno; /* Save the error... */ - fcntl(s, F_SETFL, flags); - if ((res != 0) && (s_err != EINPROGRESS)) - { - errno = s_err; /* Restore it */ - return(-1); - } - if (res == 0) /* Connected quickly! */ - return(0); - - /* Otherwise, our connection is "in progress." We can use - * the select() call to wait up to a specified period of time - * for the connection to suceed. If select() returns 0 - * (after waiting howevermany seconds), our socket never became - * writable (host is probably unreachable.) Otherwise, if - * select() returns 1, then one of two conditions exist: - * - * 1. An error occured. We use getsockopt() to check for this. - * 2. The connection was set up sucessfully: getsockopt() will - * return 0 as an error. - * - * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk> - * who posted this method of timing out a connect() in - * comp.unix.programmer on August 15th, 1997. - */ - - FD_ZERO(&sfds); - FD_SET(s, &sfds); - /* - * select could be interrupted by a signal, and if it is, - * the timeout should be adjusted and the select restarted - * to work around OSes that don't restart select and - * implementations of select that don't adjust tv upon - * failure to reflect the time remaining - */ - start_time = time(NULL); - for (;;) - { - tv.tv_sec = (long) timeout; - tv.tv_usec = 0; - if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0) - break; - now_time=time(NULL); - timeout-= (uint) (now_time - start_time); - if (errno != EINTR || (int) timeout <= 0) - return -1; - } - - /* select() returned something more interesting than zero, let's - * see if we have any errors. If the next two statements pass, - * we've got an open socket! - */ - - s_err=0; - if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) - return(-1); - - if (s_err) - { /* getsockopt could succeed */ - errno = s_err; - return(-1); /* but return an error... */ - } - return(0); /* It's all good! */ -#endif -} - - -int STDCALL -mysql_real_query(MYSQL *mysql, const char *query, ulong length) -{ - DBUG_ENTER("mysql_real_query"); - DBUG_PRINT("enter",("handle: %lx",mysql)); - DBUG_PRINT("query",("Query = \"%s\"",query)); - if (mysql_send_query(mysql, query, length)) - DBUG_RETURN(-1); - DBUG_RETURN(mysql_read_query_result(mysql)); -} - - -static int -send_file_to_server(MYSQL *mysql, const char *filename) -{ - int fd, readcount; - char buf[IO_SIZE*15],*tmp_name; - DBUG_ENTER("send_file_to_server"); + if (mysql->net.last_errno) + return -1; - fn_format(buf,filename,"","",4); /* Convert to client format */ - if (!(tmp_name=my_strdup(buf,MYF(0)))) + if (mysql->field_count) { - strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY)); - DBUG_RETURN(-1); - } - if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0) - { - mysql->net.last_errno=EE_FILENOTFOUND; - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_net_write(&mysql->net,"",0); net_flush(&mysql->net); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); + mysql->status=MYSQL_STATUS_GET_RESULT; + mysql->affected_rows= mysql->result->row_count= mysql->result->data->rows; + mysql->result->data_cursor= mysql->result->data->data; } - while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0) - { - if (my_net_write(&mysql->net,buf,readcount)) - { - mysql->net.last_errno=CR_SERVER_LOST; - strmov(mysql->net.last_error,ER(mysql->net.last_errno)); - DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file")); - (void) my_close(fd,MYF(0)); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - } - (void) my_close(fd,MYF(0)); - /* Send empty packet to mark end of file */ - if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) - { - mysql->net.last_errno=CR_SERVER_LOST; - sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - if (readcount < 0) - { - mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */ - sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno); - strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1); - my_free(tmp_name,MYF(0)); - DBUG_RETURN(-1); - } - DBUG_RETURN(0); + return 0; } - /************************************************************************** ** Alloc result struct for buffered results. All rows are read to buffer. ** mysql_data_seek may be used. **************************************************************************/ - -MYSQL_RES * STDCALL -mysql_store_result(MYSQL *mysql) +static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql) { - MYSQL_RES *result; - DBUG_ENTER("mysql_store_result"); + MYSQL_RES *result= mysql->result; + if (!result) + return 0; + + result->methods= mysql->methods; + mysql->result= NULL; + *result->data->prev_ptr= 0; + result->eof= 1; + result->lengths= (ulong*)(result + 1); + mysql->affected_rows= result->row_count= result->data->rows; + result->data_cursor= result->data->data; - if (!mysql->fields) - DBUG_RETURN(0); - if (mysql->status != MYSQL_STATUS_GET_RESULT) - { - strmov(mysql->net.last_error, - ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - DBUG_RETURN(0); - } mysql->status=MYSQL_STATUS_READY; /* server is ready */ - if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ - sizeof(ulong)*mysql->field_count, - MYF(MY_WME | MY_ZEROFILL)))) - { - mysql->net.last_errno=CR_OUT_OF_MEMORY; - strmov(mysql->net.last_error, ER(mysql->net.last_errno)); - DBUG_RETURN(0); - } - result->eof=1; /* Marker for buffered */ - result->lengths=(ulong*) (result+1); - if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count))) - { - my_free((gptr) result,MYF(0)); - DBUG_RETURN(0); - } - mysql->affected_rows= result->row_count= result->data->rows; - result->data_cursor= result->data->data; - result->fields= mysql->fields; - result->field_alloc= mysql->field_alloc; - result->field_count= mysql->field_count; - result->current_field=0; - result->current_row=0; /* Must do a fetch first */ - mysql->fields=0; /* fields is now in result */ - DBUG_RETURN(result); /* Data fetched */ + return result; } - /************************************************************************** ** Alloc struct for use with unbuffered reads. Data is fetched by domand ** when calling to mysql_fetch_row. @@ -1410,694 +383,11 @@ mysql_store_result(MYSQL *mysql) ** have to wait for the client (and will not wait more than 30 sec/packet). **************************************************************************/ -MYSQL_RES * STDCALL -mysql_use_result(MYSQL *mysql) +static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql) { - MYSQL_RES *result; DBUG_ENTER("mysql_use_result"); - - if (!mysql->fields) - DBUG_RETURN(0); - if (mysql->status != MYSQL_STATUS_GET_RESULT) - { - strmov(mysql->net.last_error, - ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); - DBUG_RETURN(0); - } - if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+ - sizeof(ulong)*mysql->field_count, - MYF(MY_WME | MY_ZEROFILL)))) - DBUG_RETURN(0); - result->lengths=(ulong*) (result+1); - if (!(result->row=(MYSQL_ROW) - my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME)))) - { /* Ptrs: to one row */ - my_free((gptr) result,MYF(0)); - DBUG_RETURN(0); - } - result->fields= mysql->fields; - result->field_alloc= mysql->field_alloc; - result->field_count= mysql->field_count; - result->current_field=0; - result->handle= mysql; - result->current_row= 0; - mysql->fields=0; /* fields is now in result */ - mysql->status=MYSQL_STATUS_USE_RESULT; - DBUG_RETURN(result); /* Data is read to be fetched */ -} - - - -/************************************************************************** -** Return next field of the query results -**************************************************************************/ - -MYSQL_FIELD * STDCALL -mysql_fetch_field(MYSQL_RES *result) -{ - if (result->current_field >= result->field_count) - return(NULL); - return &result->fields[result->current_field++]; -} - - -/************************************************************************** -** Return next row of the query results -**************************************************************************/ - -MYSQL_ROW STDCALL -mysql_fetch_row(MYSQL_RES *res) -{ - DBUG_ENTER("mysql_fetch_row"); - if (!res->data) - { /* Unbufferred fetch */ - if (!res->eof) - { - if (!(read_one_row(res->handle,res->field_count,res->row, res->lengths))) - { - res->row_count++; - DBUG_RETURN(res->current_row=res->row); - } - else - { - DBUG_PRINT("info",("end of data")); - res->eof=1; - res->handle->status=MYSQL_STATUS_READY; - } - } - DBUG_RETURN((MYSQL_ROW) NULL); - } - { - MYSQL_ROW tmp; - if (!res->data_cursor) - { - DBUG_PRINT("info",("end of data")); - DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL); - } - tmp = res->data_cursor->data; - res->data_cursor = res->data_cursor->next; - DBUG_RETURN(res->current_row=tmp); - } -} - -/************************************************************************** -** Get column lengths of the current row -** If one uses mysql_use_result, res->lengths contains the length information, -** else the lengths are calculated from the offset between pointers. -**************************************************************************/ - -ulong * STDCALL -mysql_fetch_lengths(MYSQL_RES *res) -{ - ulong *lengths,*prev_length; - byte *start; - MYSQL_ROW column,end; - - if (!(column=res->current_row)) - return 0; /* Something is wrong */ - if (res->data) - { - start=0; - prev_length=0; /* Keep gcc happy */ - lengths=res->lengths; - for (end=column+res->field_count+1 ; column != end ; column++,lengths++) - { - if (!*column) - { - *lengths=0; /* Null */ - continue; - } - if (start) /* Found end of prev string */ - *prev_length= (uint) (*column-start-1); - start= *column; - prev_length=lengths; - } - } - return res->lengths; -} - -/************************************************************************** -** Move to a specific row and column -**************************************************************************/ - -void STDCALL -mysql_data_seek(MYSQL_RES *result, my_ulonglong row) -{ - MYSQL_ROWS *tmp=0; - DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row)); - if (result->data) - for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ; - result->current_row=0; - result->data_cursor = tmp; -} - -/************************************************************************* -** put the row or field cursor one a position one got from mysql_row_tell() -** This doesn't restore any data. The next mysql_fetch_row or -** mysql_fetch_field will return the next row or field after the last used -*************************************************************************/ - -MYSQL_ROW_OFFSET STDCALL -mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row) -{ - MYSQL_ROW_OFFSET return_value=result->data_cursor; - result->current_row= 0; - result->data_cursor= row; - return return_value; -} - - -MYSQL_FIELD_OFFSET STDCALL -mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset) -{ - MYSQL_FIELD_OFFSET return_value=result->current_field; - result->current_field=field_offset; - return return_value; -} - -/***************************************************************************** -** List all databases -*****************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_dbs(MYSQL *mysql, const char *wild) -{ - char buff[255]; - DBUG_ENTER("mysql_list_dbs"); - - append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild); - if (mysql_query(mysql,buff)) - DBUG_RETURN(0); - DBUG_RETURN (mysql_store_result(mysql)); -} - - -/***************************************************************************** -** List all tables in a database -** If wild is given then only the tables matching wild is returned -*****************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_tables(MYSQL *mysql, const char *wild) -{ - char buff[255]; - DBUG_ENTER("mysql_list_tables"); - - append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild); - if (mysql_query(mysql,buff)) - DBUG_RETURN(0); - DBUG_RETURN (mysql_store_result(mysql)); -} - - -/************************************************************************** -** List all fields in a table -** If wild is given then only the fields matching wild is returned -** Instead of this use query: -** show fields in 'table' like "wild" -**************************************************************************/ - -MYSQL_RES * STDCALL -mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) -{ - MYSQL_RES *result; - MYSQL_DATA *query; - char buff[257],*end; - DBUG_ENTER("mysql_list_fields"); - DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); - - LINT_INIT(query); - - end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); - if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) || - !(query = read_rows(mysql,(MYSQL_FIELD*) 0,6))) - DBUG_RETURN(NULL); - - free_old_query(mysql); - if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES), - MYF(MY_WME | MY_ZEROFILL)))) - { - free_rows(query); - DBUG_RETURN(NULL); - } - result->field_alloc=mysql->field_alloc; - mysql->fields=0; - result->field_count = (uint) query->rows; - result->fields= unpack_fields(query,&result->field_alloc, - result->field_count,1, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)); - result->eof=1; - DBUG_RETURN(result); -} - -/* List all running processes (threads) in server */ - -MYSQL_RES * STDCALL -mysql_list_processes(MYSQL *mysql) -{ - MYSQL_DATA *fields; - uint field_count; - uchar *pos; - DBUG_ENTER("mysql_list_processes"); - - LINT_INIT(fields); - if (simple_command(mysql,COM_PROCESS_INFO,"",0,0)) - DBUG_RETURN(0); - free_old_query(mysql); - pos=(uchar*) mysql->net.read_pos; - field_count=(uint) net_field_length(&pos); - if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0,5))) - DBUG_RETURN(NULL); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, - (my_bool) test(mysql->server_capabilities & - CLIENT_LONG_FLAG)))) + if (mysql->options.separate_thread) DBUG_RETURN(0); - mysql->status=MYSQL_STATUS_GET_RESULT; - mysql->field_count=field_count; - DBUG_RETURN(mysql_store_result(mysql)); -} - - -int STDCALL -mysql_create_db(MYSQL *mysql, const char *db) -{ - DBUG_ENTER("mysql_createdb"); - DBUG_PRINT("enter",("db: %s",db)); - DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0)); -} - - -int STDCALL -mysql_drop_db(MYSQL *mysql, const char *db) -{ - DBUG_ENTER("mysql_drop_db"); - DBUG_PRINT("enter",("db: %s",db)); - DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0)); -} - -int STDCALL -mysql_shutdown(MYSQL *mysql) -{ - DBUG_ENTER("mysql_shutdown"); - DBUG_RETURN(simple_command(mysql,COM_SHUTDOWN,"",0,0)); -} - - -int STDCALL -mysql_refresh(MYSQL *mysql,uint options) -{ - uchar bits[1]; - DBUG_ENTER("mysql_refresh"); - bits[0]= (uchar) options; - DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0)); -} - -int STDCALL -mysql_kill(MYSQL *mysql,ulong pid) -{ - char buff[12]; - DBUG_ENTER("mysql_kill"); - int4store(buff,pid); - DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,4,0)); -} - - -int STDCALL -mysql_dump_debug_info(MYSQL *mysql) -{ - DBUG_ENTER("mysql_dump_debug_info"); - DBUG_RETURN(simple_command(mysql,COM_DEBUG,"",0,0)); -} - -const char * STDCALL -mysql_stat(MYSQL *mysql) -{ - DBUG_ENTER("mysql_stat"); - if (simple_command(mysql,COM_STATISTICS,"",0,0)) - return mysql->net.last_error; - mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */ - if (!mysql->net.read_pos[0]) - { - mysql->net.last_errno=CR_WRONG_HOST_INFO; - strmov(mysql->net.last_error, ER(mysql->net.last_errno)); - return mysql->net.last_error; - } - DBUG_RETURN((char*) mysql->net.read_pos); -} - - -int STDCALL -mysql_ping(MYSQL *mysql) -{ - DBUG_ENTER("mysql_ping"); - DBUG_RETURN(simple_command(mysql,COM_PING,"",0,0)); -} - - -const char * STDCALL -mysql_get_server_info(MYSQL *mysql) -{ - return((char*) mysql->server_version); -} - - -const char * STDCALL -mysql_get_host_info(MYSQL *mysql) -{ - return(mysql->host_info); -} - - -uint STDCALL -mysql_get_proto_info(MYSQL *mysql) -{ - return (mysql->protocol_version); -} - -const char * STDCALL -mysql_get_client_info(void) -{ - return MYSQL_SERVER_VERSION; -} - - -int STDCALL -mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) -{ - DBUG_ENTER("mysql_option"); - DBUG_PRINT("enter",("option: %d",(int) option)); - switch (option) { - case MYSQL_OPT_CONNECT_TIMEOUT: - mysql->options.connect_timeout= *(uint*) arg; - break; - case MYSQL_OPT_COMPRESS: - mysql->options.compress=1; /* Remember for connect */ - break; - case MYSQL_OPT_NAMED_PIPE: - mysql->options.named_pipe=1; /* Force named pipe */ - break; - case MYSQL_INIT_COMMAND: - my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.init_command=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_READ_DEFAULT_FILE: - my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_READ_DEFAULT_GROUP: - my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_SET_CHARSET_DIR: - my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME)); - break; - case MYSQL_SET_CHARSET_NAME: - my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR)); - mysql->options.charset_name=my_strdup(arg,MYF(MY_WME)); - break; - default: - DBUG_RETURN(-1); - } - DBUG_RETURN(0); -} - -/**************************************************************************** -** Functions to get information from the MySQL structure -** These are functions to make shared libraries more usable. -****************************************************************************/ - -/* MYSQL_RES */ -my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res) -{ - return res->row_count; -} - -unsigned int STDCALL mysql_num_fields(MYSQL_RES *res) -{ - return res->field_count; -} - -my_bool STDCALL mysql_eof(MYSQL_RES *res) -{ - return res->eof; -} - -MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr) -{ - return &(res)->fields[fieldnr]; -} - -MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res) -{ - return (res)->fields; -} - -MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res) -{ - return res->data_cursor; -} - -uint STDCALL mysql_field_tell(MYSQL_RES *res) -{ - return (res)->current_field; -} - -/* MYSQL */ - -unsigned int STDCALL mysql_field_count(MYSQL *mysql) -{ - return mysql->field_count; -} - -my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql) -{ - return (mysql)->affected_rows; -} - -my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) -{ - return (mysql)->insert_id; -} - -uint STDCALL mysql_errno(MYSQL *mysql) -{ - return (mysql)->net.last_errno; -} - -const char * STDCALL mysql_error(MYSQL *mysql) -{ - return (mysql)->net.last_error; -} - -const char *STDCALL mysql_info(MYSQL *mysql) -{ - return (mysql)->info; -} - -ulong STDCALL mysql_thread_id(MYSQL *mysql) -{ - return (mysql)->thread_id; -} - -const char * STDCALL mysql_character_set_name(MYSQL *mysql) -{ - return mysql->charset->name; -} - - -uint STDCALL mysql_thread_safe(void) -{ -#ifdef THREAD - return 1; -#else - return 0; -#endif -} - -/**************************************************************************** -** Some support functions -****************************************************************************/ - -/* -** Add escape characters to a string (blob?) to make it suitable for a insert -** to should at least have place for length*2+1 chars -** Returns the length of the to string -*/ - -ulong STDCALL -mysql_escape_string(char *to,const char *from,ulong length) -{ - return mysql_sub_escape_string(default_charset_info,to,from,length); -} - -ulong STDCALL -mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, - ulong length) -{ - return mysql_sub_escape_string(mysql->charset,to,from,length); -} - - -static ulong -mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, - const char *from, ulong length) -{ - const char *to_start=to; - const char *end; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(charset_info); -#endif - for (end=from+length; from != end ; from++) - { -#ifdef USE_MB - int l; - if (use_mb_flag && (l = my_ismbchar(charset_info, from, end))) - { - while (l--) - *to++ = *from++; - from--; - continue; - } -#endif - switch (*from) { - case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; - break; - case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; - break; - case '\r': - *to++= '\\'; - *to++= 'r'; - break; - case '\\': - *to++= '\\'; - *to++= '\\'; - break; - case '\'': - *to++= '\\'; - *to++= '\''; - break; - case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; - break; - case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; - break; - default: - *to++= *from; - } - } - *to=0; - return (ulong) (to-to_start); -} - - -char * STDCALL -mysql_odbc_escape_string(MYSQL *mysql, - char *to, ulong to_length, - const char *from, ulong from_length, - void *param, - char * (*extend_buffer) - (void *, char *, ulong *)) -{ - char *to_end=to+to_length-5; - const char *end; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(mysql->charset); -#endif - - for (end=from+from_length; from != end ; from++) - { - if (to >= to_end) - { - to_length = (ulong) (end-from)+512; /* We want this much more */ - if (!(to=(*extend_buffer)(param, to, &to_length))) - return to; - to_end=to+to_length-5; - } -#ifdef USE_MB - { - int l; - if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end))) - { - while (l--) - *to++ = *from++; - from--; - continue; - } - } -#endif - switch (*from) { - case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; - break; - case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; - break; - case '\r': - *to++= '\\'; - *to++= 'r'; - break; - case '\\': - *to++= '\\'; - *to++= '\\'; - break; - case '\'': - *to++= '\\'; - *to++= '\''; - break; - case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; - break; - case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; - break; - default: - *to++= *from; - } - } - return to; -} - -void STDCALL -myodbc_remove_escape(MYSQL *mysql,char *name) -{ - char *to; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(mysql->charset); - char *end; - LINT_INIT(end); - if (use_mb_flag) - for (end=name; *end ; end++) ; -#endif - - for (to=name ; *name ; name++) - { -#ifdef USE_MB - int l; - if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) ) - { - while (l--) - *to++ = *name++; - name--; - continue; - } -#endif - if (*name == '\\' && name[1]) - name++; - *to++= *name; - } - *to=0; + DBUG_RETURN(emb_mysql_store_result(mysql)); } diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index c6615ee971c..c3f757b5f1a 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -1,65 +1,130 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 4.0 Embedded Server Library' -VERSION 4.0 +DESCRIPTION 'MySQL 4.1 Embedded Server Library' +VERSION 4.1 EXPORTS - mysql_server_end - mysql_server_init - mysql_use_result - mysql_thread_safe - mysql_thread_id - mysql_store_result - mysql_stat - mysql_shutdown - mysql_select_db - mysql_row_tell - mysql_row_seek - mysql_real_query - mysql_real_connect - mysql_query - mysql_ping - mysql_options - mysql_num_rows - mysql_num_fields - mysql_list_tables - mysql_list_processes - mysql_list_fields - mysql_list_dbs - mysql_kill - mysql_insert_id - mysql_init - mysql_info - mysql_get_server_info - mysql_get_proto_info - mysql_get_host_info - mysql_get_client_info - mysql_free_result - mysql_field_tell - mysql_field_count - mysql_field_seek - mysql_fetch_row - mysql_fetch_lengths - mysql_fetch_fields - mysql_fetch_field_direct - mysql_fetch_field - mysql_escape_string - mysql_real_escape_string - mysql_error - mysql_errno - mysql_eof - mysql_dump_debug_info - mysql_drop_db - mysql_debug - mysql_data_seek - mysql_create_db - mysql_character_set_name + _dig_vec + bmove_upp + delete_dynamic + free_defaults + getopt_compare_strings + getopt_ull_limit_value + handle_options + init_dynamic_array + insert_dynamic + int2str + is_prefix + list_add + list_delete + load_defaults + max_allowed_packet + my_end + my_getopt_print_errors + my_init + my_malloc + my_memdup + my_no_flags_free + my_path + my_print_help + my_print_variables + my_realloc + my_strdup + my_thread_end + my_thread_init + myodbc_remove_escape + mysql_affected_rows + mysql_autocommit mysql_change_user - mysql_connect + mysql_character_set_name mysql_close - mysql_affected_rows - mysql_thread_init - mysql_thread_end - mysql_send_query + mysql_commit + mysql_data_seek + mysql_debug + mysql_dump_debug_info + mysql_eof + mysql_errno + mysql_error + mysql_escape_string + mysql_fetch_field + mysql_fetch_field_direct + mysql_fetch_fields + mysql_fetch_lengths + mysql_fetch_row + mysql_field_count + mysql_field_seek + mysql_field_tell + mysql_free_result + mysql_get_client_info + mysql_get_host_info + mysql_get_proto_info + mysql_get_server_info + mysql_info + mysql_init + mysql_insert_id + mysql_kill + mysql_list_dbs + mysql_list_fields + mysql_list_processes + mysql_list_tables + mysql_more_results + mysql_next_result + mysql_num_fields + mysql_num_rows + mysql_odbc_escape_string + mysql_options + mysql_ping + mysql_query mysql_read_query_result + mysql_real_connect + mysql_real_escape_string + mysql_real_query mysql_refresh - mysql_odbc_escape_string - myodbc_remove_escape + mysql_rollback + mysql_row_seek + mysql_row_tell + mysql_select_db + mysql_send_query + mysql_shutdown + mysql_ssl_set + mysql_stat + mysql_store_result + mysql_sqlstate + mysql_thread_id + mysql_thread_safe + mysql_use_result + mysql_warning_count + net_buffer_length + set_dynamic + strcend + strcont + strdup_root + strfill + strinstr + strmake + strmov + strxmov + mysql_server_end + mysql_server_init + get_tty_password + sql_protocol_typelib + mysql_get_server_version + mysql_sqlstate + charsets_dir + disabled_my_option + my_charset_latin1 + init_alloc_root + my_progname + get_charset_by_csname + print_defaults + find_type + strxnmov + strend + my_fopen + my_fclose + unpack_filename + str2int + int10_to_str + longlong10_to_str + my_snprintf_8bit + alloc_root + free_root + my_read |