Commit 6b303f84 authored by hf@deer.(none)'s avatar hf@deer.(none)

Including client code into libmysqld

Merging 
parents 902984a8 1b1a126a
......@@ -622,3 +622,7 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
libmysqld/client.c
libmysqld/client_settings.h
libmysqld/libmysql.c
libmysqld/pack.c
......@@ -328,7 +328,7 @@ static void get_replace_column(struct st_query *q);
static void free_replace_column();
/* Disable functions that only exist in MySQL 4.0 */
#if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY)
#if MYSQL_VERSION_ID < 40000
void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
......
......@@ -129,11 +129,22 @@ typedef struct st_mysql_data {
unsigned int fields;
MYSQL_ROWS *data;
MEM_ROOT alloc;
#ifdef EMBEDDED_LIBRARY
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
MYSQL_ROWS **prev_ptr;
#endif
} MYSQL_DATA;
enum mysql_option
{
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION
};
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
......@@ -165,18 +176,10 @@ struct st_mysql_options {
a read that is replication-aware
*/
my_bool no_master_reads;
#ifdef EMBEDDED_LIBRARY
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
my_bool separate_thread;
#endif
};
enum mysql_option
{
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT
enum mysql_option methods_to_use;
};
enum mysql_status
......@@ -199,8 +202,7 @@ enum mysql_rpl_type
MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
};
#ifndef EMBEDDED_LIBRARY
struct st_mysql_methods;
typedef struct st_mysql
{
......@@ -245,34 +247,14 @@ typedef struct st_mysql
struct st_mysql* last_used_con;
LIST *stmts; /* list of all statements */
} MYSQL;
#else
struct st_mysql_res;
typedef struct st_mysql
{
const struct st_mysql_methods *methods;
struct st_mysql_res *result;
void *thd;
struct charset_info_st *charset;
unsigned int server_language;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc;
my_ulonglong affected_rows;
unsigned int field_count;
struct st_mysql_options options;
enum mysql_status status;
my_bool free_me; /* If free in mysql_close */
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
unsigned int last_errno;
unsigned int server_status;
char *last_error; /* Used by embedded server */
char *last_error;
char sqlstate[SQLSTATE_LENGTH+1]; /* Used by embedded server */
} MYSQL;
#endif
typedef struct st_mysql_res {
my_ulonglong row_count;
MYSQL_FIELD *fields;
......@@ -371,12 +353,10 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
unsigned int port,
const char *unix_socket,
unsigned long clientflag);
void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length);
/* perform query on master */
......@@ -437,8 +417,6 @@ MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
const char *wild);
MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
const char *arg);
void STDCALL mysql_free_result(MYSQL_RES *result);
......@@ -559,6 +537,25 @@ typedef struct st_mysql_stmt
} MYSQL_STMT;
#define mysql_close(sock) (*(sock)->methods->close)(sock)
#define mysql_read_query_result(mysql) (*(mysql)->methods->read_query_result)(mysql)
#define mysql_store_result(mysql) (*(mysql)->methods->store_result)(mysql)
#define mysql_use_result(mysql) (*(mysql)->methods->use_result)(mysql)
typedef struct st_mysql_methods
{
void STDCALL (*close)(MYSQL *sock);
my_bool STDCALL (*read_query_result)(MYSQL *mysql);
my_bool STDCALL (*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);
MYSQL_RES * STDCALL (*store_result)(MYSQL *mysql);
MYSQL_RES * STDCALL (*use_result)(MYSQL *mysql);
} MYSQL_METHODS;
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
unsigned long length);
int STDCALL mysql_execute(MYSQL_STMT * stmt);
......@@ -613,9 +610,9 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
They are not for general usage
*/
my_bool
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
unsigned long length, my_bool skip_check);
#define simple_command(mysql, command, arg, length, skip_check) \
(*(mysql)->methods->advanced_command)(mysql, command, \
NullS, 0, arg, length, skip_check)
unsigned long net_safe_read(MYSQL* mysql);
void mysql_once_init(void);
......
......@@ -130,7 +130,7 @@ typedef struct st_vio Vio;
#define MAX_BLOB_WIDTH 8192 /* Default width for blob */
typedef struct st_net {
#ifndef EMBEDDED_LIBRARY
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY)
Vio* vio;
unsigned char *buff,*buff_end,*write_pos,*read_pos;
my_socket fd; /* For Perl DBI/dbd */
......@@ -234,7 +234,8 @@ void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
my_bool net_realloc(NET *net, unsigned long length);
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY /* To be removed by HF */
my_bool net_flush(NET *net);
#else
#define net_flush(A)
......@@ -339,6 +340,7 @@ void my_thread_end(void);
#ifdef _global_h
ulong STDCALL net_field_length(uchar **packet);
my_ulonglong net_field_length_ll(uchar **packet);
char *net_store_length(char *pkg, ulonglong length);
#endif
#ifdef __cplusplus
......
......@@ -19,11 +19,11 @@
#ifdef EMBEDDED_LIBRARY
/* Things we don't need in the embedded version of MySQL */
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_DLOPEN /* No udf functions */
#undef HAVE_OPENSSL
#undef HAVE_VIO
#undef HAVE_ISAM
#undef HAVE_SMEM /* No shared memory */
......
......@@ -27,9 +27,6 @@ my_ulonglong net_field_length_ll(uchar **packet);
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
my_bool default_value, uint server_capabilities);
my_bool 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);
void free_rows(MYSQL_DATA *cur);
MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
uint field_count);
......@@ -38,6 +35,8 @@ void fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count);
void free_old_query(MYSQL *mysql);
void end_server(MYSQL *mysql);
my_bool mysql_reconnect(MYSQL *mysql);
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group);
#ifdef __cplusplus
}
#endif
......
......@@ -220,7 +220,7 @@ enum SSL_type
};
#ifndef EMBEDDED_LIBRARY
/* HFTODO - hide this if we don't want client in embedded server */
/* This structure is for every connection on both sides */
struct st_vio
{
......@@ -263,5 +263,4 @@ struct st_vio
#endif /* HAVE_SMEM */
#endif /* HAVE_VIO */
};
#endif /* EMBEDDED_LIBRARY */
#endif /* vio_violite_h_ */
......@@ -14,12 +14,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
extern uint mysql_port;
extern my_string mysql_unix_port;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS | \
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION)
sig_handler pipe_sig_handler(int sig __attribute__((unused)));
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list);
void read_user_name(char *name);
......@@ -39,3 +40,4 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename);
#define set_sigpipe(mysql)
#define reset_sigpipe(mysql)
#endif
......@@ -58,12 +58,19 @@
#endif
#include <sql_common.h>
#include "client_settings.h"
ulong net_buffer_length=8192;
ulong max_allowed_packet= 1024L*1024L*1024L;
ulong net_read_timeout= NET_READ_TIMEOUT;
ulong net_write_timeout= NET_WRITE_TIMEOUT;
#ifdef EMBEDDED_LIBRARY
#undef net_flush
my_bool net_flush(NET *net);
#endif
#if defined(MSDOS) || defined(__WIN__)
/* socket_errno is defined in my_global.h for all platforms */
#define perror(A)
......@@ -85,19 +92,6 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list);
/*
Initialize the MySQL library
SYNOPSIS
mysql_once_init()
NOTES
Can't be static on NetWare
This function is called by mysql_init() and indirectly called
by mysql_real_query(), so one should never have to call this from an
outside program.
*/
static my_bool mysql_client_init= 0;
static my_bool org_my_init_done= 0;
......@@ -145,7 +139,7 @@ void mysql_once_init(void)
#endif
}
#ifndef EMBEDDED_LIBRARY
int STDCALL mysql_server_init(int argc __attribute__((unused)),
char **argv __attribute__((unused)),
char **groups __attribute__((unused)))
......@@ -163,6 +157,8 @@ void STDCALL mysql_server_end()
mysql_thread_end();
}
#endif /*EMBEDDED_LIBRARY*/
my_bool STDCALL mysql_thread_init()
{
#ifdef THREAD
......@@ -183,17 +179,6 @@ void STDCALL mysql_thread_end()
Let the user specify that we don't want SIGPIPE; This doesn't however work
with threaded applications as we can have multiple read in progress.
*/
#if !defined(__WIN__) && defined(SIGPIPE) && !defined(THREAD)
#define init_sigpipe_variables sig_return old_signal_handler=(sig_return) 0
#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE,pipe_sig_handler)
#define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler);
#else
#define init_sigpipe_variables
#define set_sigpipe(mysql)
#define reset_sigpipe(mysql)
#endif
static MYSQL* spawn_init(MYSQL* parent, const char* host,
unsigned int port,
const char* user,
......@@ -856,7 +841,6 @@ STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
return 0;
}
/**************************************************************************
Return next field of the query results
**************************************************************************/
......@@ -1762,39 +1746,6 @@ static void store_param_type(NET *net, uint type)
net->write_pos+=2;
}
/*
Store the length of parameter data
(Same function as in sql/net_pkg.cc)
*/
char *
net_store_length(char *pkg, ulong length)
{
uchar *packet=(uchar*) pkg;
if (length < 251)
{
*packet=(uchar) length;
return (char*) packet+1;
}
/* 251 is reserved for NULL */
if (length < 65536L)
{
*packet++=252;
int2store(packet,(uint) length);
return (char*) packet+2;
}
if (length < 16777216L)
{
*packet++=253;
int3store(packet,(ulong) length);
return (char*) packet+3;
}
*packet++=254;
int8store(packet, (ulonglong) length);
return (char*) packet+9;
}
/****************************************************************************
Functions to store parameter data from a prepared statement.
......@@ -1994,8 +1945,9 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
mysql->last_used_con= mysql;
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
if (advanced_command(mysql, COM_EXECUTE, buff, MYSQL_STMT_HEADER, packet,
length, 1) ||
if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff,
MYSQL_STMT_HEADER, packet,
length, 1) ||
mysql_read_query_result(mysql))
{
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
......@@ -2287,8 +2239,9 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
Note that we don't get any ok packet from the server in this case
This is intentional to save bandwidth.
*/
if (advanced_command(mysql, COM_LONG_DATA, extra_data,
MYSQL_LONG_DATA_HEADER, data, length, 1))
if ((*mysql->methods->advanced_command)(mysql, COM_LONG_DATA, extra_data,
MYSQL_LONG_DATA_HEADER, data,
length, 1))
{
set_stmt_errmsg(stmt, mysql->net.last_error,
mysql->net.last_errno, mysql->net.sqlstate);
......
......@@ -32,7 +32,7 @@ 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
......@@ -57,8 +57,6 @@ sqlsources = derror.cc field.cc field_conv.cc filesort.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc
EXTRA_DIST = lib_vio.c
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
libmysqld_a_SOURCES=
......@@ -74,7 +72,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
......@@ -115,11 +114,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.%
......@@ -26,6 +26,4 @@ C_MODE_START
extern void lib_connection_phase(NET *net, int phase);
extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
extern void *create_embedded_thd(int client_flag, char *db);
extern my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skipp_check);
C_MODE_END
......@@ -10,7 +10,7 @@ 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@
LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @bdb_libs_with_path@ @LIBDL@ $(CXXLDFLAGS)
mysqltest_SOURCES = mysqltest.c
......
......@@ -47,9 +47,10 @@ 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;};
my_bool simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg,
ulong length, my_bool skipp_check)
my_bool
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)
{
my_bool result= 1;
THD *thd=(THD *) mysql->thd;
......@@ -67,13 +68,14 @@ my_bool simple_command(MYSQL *mysql,enum enum_server_command command,
mysql->affected_rows= ~(my_ulonglong) 0;
thd->store_globals(); // Fix if more than one connect
result= dispatch_command(command, thd, (char *) arg, length + 1);
result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
if (!skipp_check)
if (!skip_check)
result= thd->net.last_errno ? -1 : 0;
mysql->last_error= thd->net.last_error;
mysql->last_errno= thd->net.last_errno;
mysql->net.last_errno= thd->net.last_errno;
mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
return result;
}
......@@ -144,7 +146,6 @@ char **copy_arguments(int argc, char **argv)
extern "C"
{
ulong max_allowed_packet, net_buffer_length;
char ** copy_arguments_ptr= 0;
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
......@@ -281,21 +282,6 @@ void STDCALL mysql_server_end()
my_end(0);
}
my_bool STDCALL mysql_thread_init()
{
#ifdef THREAD
return my_thread_init();
#else
return 0;
#endif
}
void STDCALL mysql_thread_end()
{
#ifdef THREAD
my_thread_end();
#endif
}
} /* extern "C" */
C_MODE_START
......@@ -454,11 +440,6 @@ send_eof(THD *thd, bool no_flush)
{
}
uint STDCALL mysql_warning_count(MYSQL *mysql)
{
return ((THD *)mysql->thd)->total_warn_count;
}
void Protocol_simple::prepare_for_resend()
{
MYSQL_ROWS *cur;
......
/* 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.
*/
#ifdef DUMMY
#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_net.h>
#include <m_string.h>
#include <assert.h>
#ifndef __WIN__
#define HANDLE void *
#endif
struct st_vio
{
enum enum_vio_type type; /* Type of connection */
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;
vio->type = type;
}
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;
}
int create_vio(NET *net, int separate_thread)
{
Vio * v = net->vio;
if (!v)
{
v = vio_new(0, separate_thread ? VIO_CLOSED : VIO_TYPE_TCPIP, 0);
net->vio = v;
}
return !v;
}
void set_thd(Vio *v, void *thd)
{
if (v)
{
v -> dest_thd = thd;
}
}
#endif /* HAVE_VIO */
#endif /* DUMMY */
......@@ -46,16 +46,6 @@
#define INADDR_NONE -1
#endif
static my_bool mysql_client_init=0;
uint mysql_port=0;
my_string mysql_unix_port=0;
const char *not_error_sqlstate= "00000";
const char *sql_protocol_names_lib[] =
{ "TCP", "SOCKET", "PIPE", "MEMORY",NullS };
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
sql_protocol_names_lib};
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | CLIENT_PROTOCOL_41)
#if defined(MSDOS) || defined(__WIN__)
......@@ -68,35 +58,19 @@ TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
#define closesocket(A) close(A)
#endif
void mysqld_once_init(void);
static void end_server(MYSQL *mysql);
static void append_wild(char *to,char *end,const char *wild);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
void free_old_query(MYSQL *mysql);
my_bool
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);
#define init_sigpipe_variables
#define set_sigpipe(mysql)
#define reset_sigpipe(mysql)
static void free_rows(MYSQL_DATA *cur)
{
if (cur)
{
free_root(&cur->alloc,MYF(0));
my_free((gptr) cur,MYF(0));
}
}
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;
}
/* 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);
#ifdef HAVE_GETPWUID
struct passwd *getpwuid(uid_t);
......@@ -111,300 +85,17 @@ 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");
free_old_query(mysql);
DBUG_VOID_RETURN;
}
void STDCALL
mysql_free_result(MYSQL_RES *result)
{
DBUG_ENTER("mysql_free_result");
DBUG_PRINT("enter",("mysql_res: %lx",result));
if (result)
{
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-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile",
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher","protocol", "shared_memory_base_name",
NullS
};
static TYPELIB option_types={array_elements(default_options)-1,
"options",default_options};
static int add_init_command(struct st_mysql_options *options, const char *cmd)
{
char *tmp;
if (!options->init_commands)
{
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
MYF(MY_WME));
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
}
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
insert_dynamic(options->init_commands, (gptr)&tmp))
{
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
return 1;
}
return 0;
}
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 '=' */
}
/* Change all '_' in variable name to '-' */
for (end= *option ; *(end= strcend(end,'_')) ; )
*end= '-';
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->protocol = MYSQL_PROTOCOL_PIPE;
break;
case 20: /* connect_timeout */
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 */
add_init_command(options,opt_arg);
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:
case 26:
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;
case 19: /* Interactive-timeout */
case 21: /* client_local_files */
case 22:
case 23: /* Replication options */
case 24:
case 25:
case 27: /* Protocol */
case 28: /* Shared memory */
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
}
}
}
free_defaults(argv);
DBUG_VOID_RETURN;
}
/****************************************************************************
** 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;
}
else
bzero((char*) (mysql),sizeof(*(mysql)));
return mysql;
}
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
......@@ -475,9 +166,23 @@ static inline int mysql_init_charset(MYSQL *mysql)
** before calling mysql_real_connect !
*/
static void STDCALL emb_mysql_close(MYSQL *mysql);
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_close,
emb_mysql_read_query_result,
emb_advanced_command,
emb_mysql_store_result,
emb_mysql_use_result,
};
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd __attribute__((unused)), const char *db,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag)
{
char *db_name;
......@@ -487,6 +192,16 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
db ? db : "(Null)",
user ? user : "(Null)"));
if (mysql->options.methods_to_use == MYSQL_OPT_USE_REMOTE_CONNECTION)
cli_mysql_real_connect(mysql, host, user,
passwd, db, port, unix_socket, client_flag);
if ((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;
/* use default options */
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
{
......@@ -541,11 +256,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
}
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
reset_sigpipe(mysql);
DBUG_RETURN(mysql);
error:
reset_sigpipe(mysql);
DBUG_PRINT("error",("message: %u (%s)",mysql->last_errno,mysql->last_error));
{
/* Free alloced memory */
......@@ -558,67 +271,12 @@ error:
DBUG_RETURN(0);
}
/**************************************************************************
** Change user and database
**************************************************************************/
my_bool STDCALL mysql_change_user(MYSQL *mysql __attribute__((unused)), const char *user __attribute__((unused)),
const char *passwd __attribute__((unused)), const char *db __attribute__((unused)))
{
#ifdef DUMMY
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);
#endif
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);
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)
static void STDCALL emb_mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
if (mysql) /* Some simple safety */
......@@ -654,20 +312,7 @@ 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));
}
my_bool STDCALL
mysql_read_query_result(MYSQL *mysql)
static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql)
{
if (mysql->last_errno)
return -1;
......@@ -682,151 +327,11 @@ mysql_read_query_result(MYSQL *mysql)
return 0;
}
/****************************************************************************
* A modified version of connect(). my_connect() 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>
*****************************************************************************/
my_bool 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) != 0;
#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) != 0;
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_send_query(MYSQL* mysql, const char* query, ulong length)
{
DBUG_ENTER("mysql_send_query");
if (mysql->options.separate_thread)
{
return -1;
}
mysql->result= NULL;
free_old_query(mysql); /* Free old result */
DBUG_RETURN(simple_command(mysql, COM_QUERY, query, length, 1));
}
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->options.separate_thread)
{
return -1;
}
mysql->result= NULL;
free_old_query(mysql); /* Free old result */
if (simple_command(mysql, COM_QUERY, query, length, 1))
DBUG_RETURN(-1);
DBUG_RETURN(mysql_read_query_result(mysql));
}
/**************************************************************************
** 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= mysql->result;
if (!result)
......@@ -853,781 +358,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)
{
DBUG_ENTER("mysql_use_result");
if (mysql->options.separate_thread)
DBUG_RETURN(0);
DBUG_RETURN(mysql_store_result(mysql));
}
/**************************************************************************
** 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");
{
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;
MYSQL_ROW column,end;
if (!(column=res->current_row))
return 0; /* Something is wrong */
if (res->data)
{
lengths=res->lengths;
for (end=column+res->field_count; column != end ; column++,lengths++)
{
*lengths= *column ? strlen(*column) : 0;
}
}
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 __attribute__((unused)), const char *table __attribute__((unused)), const char *wild __attribute__((unused)))
{
#ifdef DUMMY
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);
#endif
return 0;
}
/* List all running processes (threads) in server */
MYSQL_RES * STDCALL
mysql_list_processes(MYSQL *mysql __attribute__((unused)))
{
#ifdef FOR_THE_FUTURE
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))))
DBUG_RETURN(0);
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
DBUG_RETURN(mysql_store_result(mysql));
#endif /* FOR_THE_FUTURE */
return 0;
}
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)
{
#ifdef DUMMY
DBUG_ENTER("mysql_stat");
if (simple_command(mysql,COM_STATISTICS,"",0,0))
return mysql->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->sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error, ER(mysql->net.last_errno));
return mysql->net.last_error;
}
DBUG_RETURN((char*) mysql->net.read_pos);
#endif
return (char *)mysql;
}
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 __attribute__((unused)))
{
return MYSQL_SERVER_VERSION;
}
ulong STDCALL
mysql_get_server_version(MYSQL *mysql __attribute__((unused)))
{
return MYSQL_VERSION_ID;
}
const char * STDCALL
mysql_get_host_info(MYSQL *mysql __attribute__((unused)))
{
return "localhost";
}
uint STDCALL
mysql_get_proto_info(MYSQL *mysql __attribute__((unused)))
{
return 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_USE_RESULT:
mysql->options.separate_thread=1; /* Use separate thread for query execution*/
break;
case MYSQL_OPT_NAMED_PIPE:
mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
if (!arg || test(*(uint*) arg))
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
else
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
break;
case MYSQL_INIT_COMMAND:
add_init_command(&mysql->options,arg);
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;
case MYSQL_OPT_PROTOCOL:
mysql->options.protocol= *(uint*) arg;
break;
case MYSQL_SHARED_MEMORY_BASE_NAME:
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->last_errno;
}
const char *STDCALL mysql_sqlstate(MYSQL *mysql)
{
return mysql->sqlstate;
}
const char * STDCALL mysql_error(MYSQL *mysql)
{
return mysql->last_error;
}
const char *STDCALL mysql_info(MYSQL *mysql __attribute__((unused)))
{
#ifdef DUMMY
return (mysql)->info;
#endif
return 0;
}
ulong STDCALL mysql_thread_id(MYSQL *mysql __attribute__((unused)))
{
#ifdef DUMMY
return (mysql)->thread_id;
#endif
return 0;
}
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
}
MYSQL_RES *STDCALL mysql_warnings(MYSQL *mysql)
{
uint warning_count;
DBUG_ENTER("mysql_warnings");
/* Save warning count as mysql_real_query may change this */
warning_count= mysql_warning_count(mysql);
if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
DBUG_RETURN(0);
DBUG_RETURN(mysql_store_result(mysql));
}
/****************************************************************************
** 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;
}
/********************************************************************
Transactional APIs
*********************************************************************/
/*
Commit the current transaction
*/
my_bool STDCALL mysql_commit(MYSQL * mysql)
{
DBUG_ENTER("mysql_commit");
DBUG_RETURN((my_bool) mysql_real_query(mysql, "commit", 6));
}
/*
Rollback the current transaction
*/
my_bool STDCALL mysql_rollback(MYSQL * mysql)
{
DBUG_ENTER("mysql_rollback");
DBUG_RETURN((my_bool) mysql_real_query(mysql, "rollback", 8));
}
/*
Set autocommit to either true or false
*/
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
{
DBUG_ENTER("mysql_autocommit");
DBUG_PRINT("enter", ("mode : %d", auto_mode));
if (auto_mode) /* set to true */
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16));
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16));
}
/********************************************************************
Multi query execution + SPs APIs
*********************************************************************/
/*
Returns if there are any more query results exists to be read using
mysql_next_result()
*/
my_bool STDCALL mysql_more_results(MYSQL *mysql)
{
my_bool res;
DBUG_ENTER("mysql_more_results");
res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ?
1: 0);
DBUG_PRINT("exit",("More results exists ? %d", res));
DBUG_RETURN(res);
}
/*
Reads and returns the next query results
*/
my_bool STDCALL mysql_next_result(MYSQL *mysql)
{
DBUG_ENTER("mysql_next_result");
mysql->last_error[0]= 0;
mysql->last_errno= 0;
strmov(mysql->sqlstate, not_error_sqlstate);
mysql->affected_rows= ~(my_ulonglong) 0;
if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
DBUG_RETURN(mysql_read_query_result(mysql));
DBUG_RETURN(0);
}
my_bool STDCALL
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
const char *key __attribute__((unused)),
const char *cert __attribute__((unused)),
const char *ca __attribute__((unused)),
const char *capath __attribute__((unused)),
const char *cipher __attribute__((unused)))
{
return 0;
DBUG_RETURN(emb_mysql_store_result(mysql));
}
......@@ -38,7 +38,26 @@
#include <my_global.h>
#include "mysql.h"
#ifdef EMBEDDED_LIBRARY
#undef MYSQL_SERVER
#ifndef MYSQL_CLIENT
#define MYSQL_CLIENT
#endif
#define CLI_MYSQL_REAL_CONNECT cli_mysql_real_connect
#undef net_flush
my_bool net_flush(NET *net);
#else /*EMBEDDED_LIBRARY*/
#define CLI_MYSQL_REAL_CONNECT mysql_real_connect
#endif /*EMBEDDED_LIBRARY*/
#if !defined(MYSQL_SERVER) && (defined(__WIN__) || defined(_WIN32) || defined(_WIN64))
#include <winsock.h>
#include <odbcinst.h>
#endif /* !defined(MYSQL_SERVER) && (defined(__WIN__) ... */
......@@ -572,8 +591,8 @@ void free_rows(MYSQL_DATA *cur)
}
}
my_bool
advanced_command(MYSQL *mysql, enum enum_server_command command,
static my_bool
cli_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)
{
......@@ -635,13 +654,6 @@ end:
return result;
}
my_bool
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
ulong length, my_bool skip_check)
{
return advanced_command(mysql, command, NullS, 0, arg, length, skip_check);
}
void free_old_query(MYSQL *mysql)
{
DBUG_ENTER("free_old_query");
......@@ -759,8 +771,8 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
return 0;
}
static void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
{
int argc;
char *argv_buff[1],**argv;
......@@ -1278,6 +1290,7 @@ mysql_init(MYSQL *mysql)
#ifdef HAVE_SMEM
mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
#endif
mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
return mysql;
}
......@@ -1409,10 +1422,24 @@ error:
before calling mysql_real_connect !
*/
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,ulong client_flag)
static void STDCALL cli_mysql_close(MYSQL *mysql);
static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql);
static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql);
static MYSQL_RES * STDCALL cli_mysql_use_result(MYSQL *mysql);
static MYSQL_METHODS client_methods=
{
cli_mysql_close,
cli_mysql_read_query_result,
cli_advanced_command,
cli_mysql_store_result,
cli_mysql_use_result
};
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)
{
char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
char *end,*host_info,*charset_name;
......@@ -1441,6 +1468,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
user ? user : "(Null)"));
/* Don't give sigpipe errors if the client doesn't want them */
mysql->methods= &client_methods;
set_sigpipe(mysql);
net->vio = 0; /* If something goes wrong */
mysql->client_flag=0; /* For handshake */
......@@ -2112,8 +2140,7 @@ static void mysql_close_free(MYSQL *mysql)
}
void STDCALL
mysql_close(MYSQL *mysql)
static void STDCALL cli_mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
if (mysql) /* Some simple safety */
......@@ -2165,8 +2192,7 @@ mysql_close(MYSQL *mysql)
DBUG_VOID_RETURN;
}
my_bool STDCALL mysql_read_query_result(MYSQL *mysql)
static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
......@@ -2283,8 +2309,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length)
mysql_data_seek may be used.
**************************************************************************/
MYSQL_RES * STDCALL
mysql_store_result(MYSQL *mysql)
static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql)
{
MYSQL_RES *result;
DBUG_ENTER("mysql_store_result");
......@@ -2339,8 +2364,7 @@ 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 cli_mysql_use_result(MYSQL *mysql)
{
MYSQL_RES *result;
DBUG_ENTER("mysql_use_result");
......@@ -2477,6 +2501,10 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
#endif
case MYSQL_OPT_USE_REMOTE_CONNECTION:
case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
case MYSQL_OPT_GUESS_CONNECTION:
mysql->options.methods_to_use= option;
break;
default:
DBUG_RETURN(1);
......
/* Copyright (C) 2000-2003 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 */
#include <my_global.h>
#include <mysql_com.h>
#include <mysql.h>
......@@ -62,3 +78,30 @@ my_ulonglong net_field_length_ll(uchar **packet)
#endif
}
char *
net_store_length(char *pkg, ulonglong length)
{
uchar *packet=(uchar*) pkg;
if (length < LL(251))
{
*packet=(uchar) length;
return (char*) packet+1;
}
/* 251 is reserved for NULL */
if (length < LL(65536))
{
*packet++=252;
int2store(packet,(uint) length);
return (char*) packet+2;
}
if (length < LL(16777216))
{
*packet++=253;
int3store(packet,(ulong) length);
return (char*) packet+3;
}
*packet++=254;
int8store(packet,length);
return (char*) packet+8;
}
......@@ -31,3 +31,4 @@
#define mysql_rpl_probe(mysql) 0
#undef HAVE_SMEM
#undef _CUSTOMCONFIG_
......@@ -30,7 +30,10 @@
3 byte length & 1 byte package-number.
*/
#ifndef EMBEDDED_LIBRARY
/*
HFTODO this must be hidden if we don't want client capabilities in
embedded library
*/
#ifdef __WIN__
#include <winsock.h>
#endif
......@@ -46,6 +49,17 @@
#include <signal.h>
#include <errno.h>
#ifdef EMBEDDED_LIBRARY
#undef net_flush
extern "C" {
my_bool net_flush(NET *net);
}
#endif /*EMBEDDED_LIBRARY */
/*
The following handles the differences when this is linked between the
client and the server.
......@@ -959,5 +973,3 @@ my_net_read(NET *net)
return len;
}
#endif /* #ifndef EMBEDDED_LIBRARY */
......@@ -235,7 +235,6 @@ net_printf(THD *thd, uint errcode, ...)
DBUG_VOID_RETURN;
}
/*
Return ok to the client.
......@@ -350,40 +349,6 @@ send_eof(THD *thd, bool no_flush)
}
#endif /* EMBEDDED_LIBRARY */
/****************************************************************************
Store a field length in logical packet
This is used to code the string length for normal protocol
****************************************************************************/
char *
net_store_length(char *pkg, ulonglong length)
{
uchar *packet=(uchar*) pkg;
if (length < LL(251))
{
*packet=(uchar) length;
return (char*) packet+1;
}
/* 251 is reserved for NULL */
if (length < LL(65536))
{
*packet++=252;
int2store(packet,(uint) length);
return (char*) packet+2;
}
if (length < LL(16777216))
{
*packet++=253;
int3store(packet,(ulong) length);
return (char*) packet+3;
}
*packet++=254;
int8store(packet,length);
return (char*) packet+8;
}
/*
Faster net_store_length when we know length is a 32 bit integer
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment