Commit d101d144 authored by Sergei Golubchik's avatar Sergei Golubchik

WL#4903 Plugin Service API part I

(mysql-next-mr backport)
parent d3bf417d
......@@ -311,6 +311,7 @@ ADD_SUBDIRECTORY(extra)
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(sql)
ADD_SUBDIRECTORY(libmysql)
ADD_SUBDIRECTORY(libservices)
ADD_SUBDIRECTORY(tests)
IF(WITH_EMBEDDED_SERVER)
ADD_SUBDIRECTORY(libmysqld)
......
......@@ -23,7 +23,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
@readline_topdir@ sql-common scripts \
@pstack_dir@ \
@pstack_dir@ libservices \
@sql_union_dirs@ unittest \
@sql_server@ @man_dirs@ tests \
netware @libmysqld_dirs@ \
......@@ -32,7 +32,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
DIST_SUBDIRS = . include Docs zlib \
cmd-line-utils sql-common scripts \
pstack \
pstack libservices \
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
vio sql man tests \
netware libmysqld \
......
......@@ -2946,7 +2946,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
man/Makefile BUILD/Makefile vio/Makefile dnl
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
sql/Makefile sql/share/Makefile dnl
sql/sql_builtin.cc sql-common/Makefile dnl
sql/sql_builtin.cc sql-common/Makefile libservices/Makefile dnl
dbug/Makefile scripts/Makefile include/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl
support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl
......
......@@ -21,7 +21,8 @@ HEADERS_GEN_MAKE = my_config.h
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
my_list.h my_alloc.h typelib.h mysql/plugin.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_xml.h mysql_embed.h \
my_xml.h mysql_embed.h mysql/services.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
......@@ -36,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
my_handler.h my_time.h \
my_handler.h my_time.h service_versions.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
atomic/solaris.h \
......
......@@ -250,16 +250,10 @@ extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
/*
LEX_STRING -- a pair of a C-string and its length.
(it's part of the plugin API as a MYSQL_LEX_STRING)
*/
#ifndef _my_plugin_h
/* This definition must match the one given in mysql/plugin.h */
struct st_mysql_lex_string
{
char *str;
size_t length;
};
#endif
#include <mysql/plugin.h>
typedef struct st_mysql_lex_string LEX_STRING;
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
......
......@@ -683,6 +683,8 @@ extern void my_error _VARARGS((int nr,myf MyFlags, ...));
extern void my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...))
ATTRIBUTE_FORMAT(printf, 2, 4);
extern void my_printv_error(uint error, const char *format, myf MyFlags,
va_list ap);
extern int my_error_register(const char** (*get_errmsgs) (),
int first, int last);
extern const char **my_error_unregister(int first, int last);
......
/* Copyright (C) 2005 MySQL AB
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
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
......@@ -16,12 +16,6 @@
#ifndef _my_plugin_h
#define _my_plugin_h
/* size_t */
#include <stdlib.h>
typedef struct st_mysql MYSQL;
/*
On Windows, exports from DLL need to be declared
*/
......@@ -39,15 +33,7 @@ class Item;
#define MYSQL_THD void*
#endif
#ifndef _m_string_h
/* This definition must match the one given in m_string.h */
struct st_mysql_lex_string
{
char *str;
unsigned int length;
};
#endif /* _m_string_h */
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
#include <mysql/services.h>
#define MYSQL_XIDDATASIZE 128
/**
......@@ -70,7 +56,7 @@ typedef struct st_mysql_xid MYSQL_XID;
Plugin API. Common for all plugin types.
*/
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
/*
The allowable types of plugins
......@@ -126,7 +112,8 @@ enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
SHOW_always_last
};
struct st_mysql_show_var {
......@@ -750,54 +737,6 @@ int thd_killed(const MYSQL_THD thd);
*/
unsigned long thd_get_thread_id(const MYSQL_THD thd);
/**
Allocate memory in the connection's local memory pool
@details
When properly used in place of @c my_malloc(), this can significantly
improve concurrency. Don't use this or related functions to allocate
large chunks of memory. Use for temporary storage only. The memory
will be freed automatically at the end of the statement; no explicit
code is required to prevent memory leaks.
@see alloc_root()
*/
void *thd_alloc(MYSQL_THD thd, unsigned int size);
/**
@see thd_alloc()
*/
void *thd_calloc(MYSQL_THD thd, unsigned int size);
/**
@see thd_alloc()
*/
char *thd_strdup(MYSQL_THD thd, const char *str);
/**
@see thd_alloc()
*/
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size);
/**
@see thd_alloc()
*/
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size);
/**
Create a LEX_STRING in this connection's local memory pool
@param thd user thread connection handle
@param lex_str pointer to LEX_STRING object to be initialized
@param str initializer to be copied into lex_str
@param size length of str, in bytes
@param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object,
instead of using lex_str value
@return NULL on failure, or pointer to the LEX_STRING object
@see thd_alloc()
*/
MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
/**
Get the XID for this connection's transaction
......@@ -818,64 +757,6 @@ void mysql_query_cache_invalidate4(MYSQL_THD thd,
const char *key, unsigned int key_length,
int using_trx);
/**
Get the value of user variable as an integer.
This function will return the value of variable @a name as an
integer. If the original value of the variable is not an integer,
the value will be converted into an integer.
@param name user variable name
@param value pointer to return the value
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_int(const char *name,
long long int *value, int *null_value);
/**
Get the value of user variable as a double precision float number.
This function will return the value of variable @a name as real
number. If the original value of the variable is not a real number,
the value will be converted into a real number.
@param name user variable name
@param value pointer to return the value
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_real(const char *name,
double *value, int *null_value);
/**
Get the value of user variable as a string.
This function will return the value of variable @a name as
string. If the original value of the variable is not a string,
the value will be converted into a string.
@param name user variable name
@param value pointer to the value buffer
@param len length of the value buffer
@param precision precision of the value if it is a float number
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_str(const char *name,
char *value, unsigned long len,
unsigned int precision, int *null_value);
#ifdef __cplusplus
}
#endif
......
#include <mysql/services.h>
#include <mysql/service_my_snprintf.h>
#include <stdarg.h>
#include <stdlib.h>
extern struct my_snprintf_service_st {
size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
} *my_snprintf_service;
size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
#include <mysql/service_thd_alloc.h>
#include <stdlib.h>
typedef struct st_mysql MYSQL;
struct st_mysql_lex_string
{
char *str;
unsigned int length;
size_t length;
};
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
extern struct thd_alloc_service_st {
void *(*thd_alloc_func)(void*, unsigned int);
void *(*thd_calloc_func)(void*, unsigned int);
char *(*thd_strdup_func)(void*, const char *);
char *(*thd_strmake_func)(void*, const char *, unsigned int);
void *(*thd_memdup_func)(void*, const void*, unsigned int);
MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
const char *, unsigned int, int);
} *thd_alloc_service;
void *thd_alloc(void* thd, unsigned int size);
void *thd_calloc(void* thd, unsigned int size);
char *thd_strdup(void* thd, const char *str);
char *thd_strmake(void* thd, const char *str, unsigned int size);
void *thd_memdup(void* thd, const void* str, unsigned int size);
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
struct st_mysql_xid {
long formatID;
long gtrid_length;
......@@ -17,7 +44,8 @@ enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
SHOW_always_last
};
struct st_mysql_show_var {
const char *name;
......@@ -107,9 +135,9 @@ struct st_mysql_information_schema
{
int interface_version;
};
struct Mysql_replication {
int interface_version;
};
struct Mysql_replication {
int interface_version;
};
struct st_mysql_value
{
int (*value_type)(struct st_mysql_value *);
......@@ -130,22 +158,7 @@ void thd_inc_row_count(void* thd);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
void *thd_alloc(void* thd, unsigned int size);
void *thd_calloc(void* thd, unsigned int size);
char *thd_strdup(void* thd, const char *str);
char *thd_strmake(void* thd, const char *str, unsigned int size);
void *thd_memdup(void* thd, const void* str, unsigned int size);
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
void mysql_query_cache_invalidate4(void* thd,
const char *key, unsigned int key_length,
int using_trx);
int get_user_var_int(const char *name,
long long int *value, int *null_value);
int get_user_var_real(const char *name,
double *value, int *null_value);
int get_user_var_str(const char *name,
char *value, unsigned long len,
unsigned int precision, int *null_value);
#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 */
/**
@file
my_snprintf service
Portable and limited vsnprintf() implementation.
This is a portable, limited vsnprintf() implementation, with some
extra features. "Portable" means that it'll produce identical result
on all platforms (for example, on Windows and Linux system printf %e
formats the exponent differently, on different systems %p either
prints leading 0x or not, %s may accept null pointer or crash on
it). "Limited" means that it does not support all the C89 features.
But it supports few extensions, not in any standard.
my_vsnprintf(to, n, fmt, ap)
@param[out] to A buffer to store the result in
@param[in] n Store up to n-1 characters, followed by an end 0
@param[in] fmt printf-like format string
@param[in] ap Arguments
@return a number of bytes written to a buffer *excluding* terminating '\0'
@post
The syntax of a format string is generally the same:
% <flag> <width> <precision> <length modifier> <format>
where everithing but the format is optional.
Three one-character flags are regognized:
'0' has the standard zero-padding semantics;
'-' is parsed, but silently ignored;
'`' (backtick) is only supported for strings (%s) and means that the
string will be quoted according to MySQL identifier quoting rules.
Both <width> and <precision> can be specified as numbers or '*'.
<length modifier> can be 'l', 'll', or 'z'.
Supported formats are 's' (null pointer is accepted, printed as
"(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x',
'X', 'p' (works as 0x%x).
Standard syntax for positional arguments $n is supported.
Extensions:
Flag '`' (backtick): see above.
Format 'b': binary buffer, prints exactly <precision> bytes from the
argument, without stopping at '\0'.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <stdlib.h>
extern struct my_snprintf_service_st {
size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
} *my_snprintf_service;
#ifdef MYSQL_DYNAMIC_PLUGIN
#define my_vsnprintf my_snprintf_service->my_vsnprintf_type
#define my_snprintf my_snprintf_service->my_snprintf_type
#else
size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
#endif
#ifdef __cplusplus
}
#endif
#define MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
#endif
#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 */
/**
@file
This service provdes functions to allocate memory in a connection local
memory pool. The memory allocated there will be automatically freed at the
end of the statement, don't use it for allocations that should live longer
than that. For short living allocations this is more efficient than
using my_malloc and friends, and automatic "garbage collection" allows not
to think about memory leaks.
The pool is best for small to medium objects, don't use it for large
allocations - they are better served with my_malloc.
*/
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
struct st_mysql_lex_string
{
char *str;
size_t length;
};
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
extern struct thd_alloc_service_st {
void *(*thd_alloc_func)(MYSQL_THD, unsigned int);
void *(*thd_calloc_func)(MYSQL_THD, unsigned int);
char *(*thd_strdup_func)(MYSQL_THD, const char *);
char *(*thd_strmake_func)(MYSQL_THD, const char *, unsigned int);
void *(*thd_memdup_func)(MYSQL_THD, const void*, unsigned int);
MYSQL_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD, MYSQL_LEX_STRING *,
const char *, unsigned int, int);
} *thd_alloc_service;
#ifdef MYSQL_DYNAMIC_PLUGIN
#define thd_alloc(thd,size) (thd_alloc_service->thd_alloc_func((thd), (size)))
#define thd_calloc(thd,size) (thd_alloc_service->thd_calloc_func((thd), (size)))
#define thd_strdup(thd,str) (thd_alloc_service->thd_strdup_func((thd), (str)))
#define thd_strmake(thd,str,size) \
(thd_alloc_service->thd_strmake_func((thd), (str), (size)))
#define thd_memdup(thd,str,size) \
(thd_alloc_service->thd_memdup_func((thd), (str), (size)))
#define thd_make_lex_string(thd, lex_str, str, size, allocate_lex_string) \
(thd_alloc_service->thd_make_lex_string_func((thd), (lex_str), (str), \
(size), (allocate_lex_string)))
#else
/**
Allocate memory in the connection's local memory pool
@details
When properly used in place of @c my_malloc(), this can significantly
improve concurrency. Don't use this or related functions to allocate
large chunks of memory. Use for temporary storage only. The memory
will be freed automatically at the end of the statement; no explicit
code is required to prevent memory leaks.
@see alloc_root()
*/
void *thd_alloc(MYSQL_THD thd, unsigned int size);
/**
@see thd_alloc()
*/
void *thd_calloc(MYSQL_THD thd, unsigned int size);
/**
@see thd_alloc()
*/
char *thd_strdup(MYSQL_THD thd, const char *str);
/**
@see thd_alloc()
*/
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size);
/**
@see thd_alloc()
*/
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size);
/**
Create a LEX_STRING in this connection's local memory pool
@param thd user thread connection handle
@param lex_str pointer to LEX_STRING object to be initialized
@param str initializer to be copied into lex_str
@param size length of str, in bytes
@param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object,
instead of using lex_str value
@return NULL on failure, or pointer to the LEX_STRING object
@see thd_alloc()
*/
MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
#endif
#ifdef __cplusplus
}
#endif
#define MYSQL_SERVICE_THD_ALLOC_INCLUDED
#endif
#ifndef MYSQL_SERVICES_INCLUDED
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 */
#ifdef __cplusplus
extern "C" {
#endif
#include <mysql/service_my_snprintf.h>
#include <mysql/service_thd_alloc.h>
#ifdef __cplusplus
}
#endif
#define MYSQL_SERVICES_INCLUDED
#endif
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 */
#ifdef _WIN32
#define SERVICE_VERSION __declspec(dllexport) void *
#else
#define SERVICE_VERSION void *
#endif
#define VERSION_my_snprintf 0x0100
#define VERSION_thd_alloc 0x0100
# Copyright (C) 2006 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; version 2 of the License.
#
# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
How to create a new service
^^^^^^^^^^^^^^^^^^^^^^^^^^^
A "service" is a set of C functions in a structure that a
service dynamic linker uses when a dynamic plugin is loaded.
If you want to export C++ class you need to provide an
extern "C" function that will create a new instance of your class,
and put it in a service.
Data structures are not part of the service structure, but they are part
of the API you create and usually need to be declared in the same
service_*.h file.
To turn a set of functions (foo_func1, foo_func2)
into a service "foo" you need to
1. create a new file include/mysql/service_foo.h
2. the template is
==================================================================
#ifndef MYSQL_SERVICE_FOO_INCLUDED
/* standard GPL header */
/**
@file
*exhaustive* description of the interface you provide.
This file is the main user documentation of the new service
*/
#ifdef __cplusplus
extern "C" {
#endif
extern struct foo_service_st {
int (*foo_func1_type)(...); /* fix the prototype as appropriate */
void (*foo_func2_type)(...); /* fix the prototype as appropriate */
} *foo_service;
#ifdef MYSQL_DYNAMIC_PLUGIN
#define foo_func1(...) foo_service->foo_func1_type(...)
#define foo_func2(...) foo_service->foo_func2_type(...)
#else
int foo_func1_type(...); /* fix the prototype as appropriate */
void foo_func2_type(...); /* fix the prototype as appropriate */
#endif
#ifdef __cplusplus
}
#endif
#define MYSQL_SERVICE_FOO_INCLUDED
#endif
==================================================================
the service_foo.h file should be self-contained, if it needs system headers -
include them in it, e.g. if you use size_t - #include <stdlib.h>
it should also declare all the accompanying data structures, as necessary
(e.g. thd_alloc_service declares MYSQL_LEX_STRING).
3. add the new file to include/Makefile.am (pkginclude_HEADERS)
4. add the new file to include/mysql/services.h
5. increase the minor plugin ABI version in include/mysql/plugin.h
(MYSQL_PLUGIN_INTERFACE_VERSION = MYSQL_PLUGIN_INTERFACE_VERSION+1)
6. add the version of your service to include/service_versions.h:
==================================================================
#define VERSION_foo 0x0100
==================================================================
7. create a new file libservices/foo_service.h using the following template:
==================================================================
/* GPL header */
#include <service_versions.h>
SERVICE_VERSION *foo_service= (void*)VERSION_foo;
==================================================================
8. add the new file to libservices/CMakeLists.txt (MYSQLSERVICES_SOURCES)
9. add the new file to libservices/Makefile.am (libmysqlservices_a_SOURCES)
10. and finally, register your service for dynamic linking in
sql/sql_plugin_services.h
10.1 fill in the service structure:
==================================================================
static struct foo_service_st foo_handler = {
foo_func1,
foo_func2
}
==================================================================
10.2 and add it to the list of services
==================================================================
{ "foo_service", VERSION_foo, &foo_handler }
==================================================================
that's all.
# Copyright 2009 Sun Microsystems, Inc.
#
# 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; version 2 of the License.
#
# 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
AM_CPPFLAGS = -I$(top_srcdir)/include
pkglib_LIBRARIES = libmysqlservices.a
libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c
EXTRA_DIST = CMakeLists.txt
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 <service_versions.h>
SERVICE_VERSION my_snprintf_service= (void*)VERSION_my_snprintf;
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 <service_versions.h>
SERVICE_VERSION *thd_alloc_service= (void*)VERSION_thd_alloc;
......@@ -12,6 +12,15 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE;
SELECT * FROM t1;
a
DROP TABLE t1;
set global example_ulong_var=500;
set global example_enum_var= e1;
show status like 'example%';
Variable_name Value
example_func_example enum_var is 0, ulong_var is 500, really
show variables like 'example%';
Variable_name Value
example_enum_var e1
example_ulong_var 500
UNINSTALL PLUGIN example;
UNINSTALL PLUGIN EXAMPLE;
ERROR 42000: PLUGIN EXAMPLE does not exist
......
......@@ -22,6 +22,12 @@ SELECT * FROM t1;
DROP TABLE t1;
# a couple of tests for variables
set global example_ulong_var=500;
set global example_enum_var= e1;
show status like 'example%';
show variables like 'example%';
UNINSTALL PLUGIN example;
--error 1305
UNINSTALL PLUGIN EXAMPLE;
......
......@@ -125,6 +125,29 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...)
DBUG_VOID_RETURN;
}
/*
Error with va_list
SYNOPSIS
my_printv_error()
error Errno
format Format string
MyFlags Flags
... variable list
*/
void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
{
char ebuff[ERRMSGSIZE];
DBUG_ENTER("my_printv_error");
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
error, MyFlags, errno, format));
(void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap);
(*error_handler_hook)(error, ebuff, MyFlags);
DBUG_VOID_RETURN;
}
/*
Give message using error_handler_hook
......
......@@ -26,7 +26,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
EXTRA_LTLIBRARIES = libdaemon_example.la
pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@
libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
libdaemon_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
libdaemon_example_la_SOURCES = daemon_example.cc
......
......@@ -45,7 +45,7 @@ SET (SQL_SOURCE
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
filesort.cc gstream.cc
ha_partition.cc
handler.cc hash_filo.cc hash_filo.h
handler.cc hash_filo.cc hash_filo.h sql_plugin_services.h
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
item_create.cc item_func.cc item_geofunc.cc item_row.cc
item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc
......
......@@ -82,7 +82,7 @@ mysqld_LDADD = libndb.la \
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h \
item_xmlfunc.h \
item_xmlfunc.h sql_plugin_services.h \
item_create.h item_subselect.h item_row.h \
mysql_priv.h item_geofunc.h sql_bitmap.h \
procedure.h sql_class.h sql_lex.h sql_list.h \
......
......@@ -28,6 +28,16 @@
#ifndef MYSQL_CLIENT
/*
the following #define adds server-only members to enum_mysql_show_type,
that is defined in mysql/plugin.h
it has to be before mysql/plugin.h is included.
*/
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
SHOW_KEY_CACHE_LONGLONG, SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS
#include <my_global.h>
#include <mysql_version.h>
#include <mysql_embed.h>
......
......@@ -16,6 +16,8 @@
#ifndef REPLICATION_H
#define REPLICATION_H
typedef struct st_mysql MYSQL;
#ifdef __cplusplus
extern "C" {
#endif
......@@ -483,6 +485,64 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
*/
void thd_exit_cond(MYSQL_THD thd, const char *old_msg);
/**
Get the value of user variable as an integer.
This function will return the value of variable @a name as an
integer. If the original value of the variable is not an integer,
the value will be converted into an integer.
@param name user variable name
@param value pointer to return the value
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_int(const char *name,
long long int *value, int *null_value);
/**
Get the value of user variable as a double precision float number.
This function will return the value of variable @a name as real
number. If the original value of the variable is not a real number,
the value will be converted into a real number.
@param name user variable name
@param value pointer to return the value
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_real(const char *name,
double *value, int *null_value);
/**
Get the value of user variable as a string.
This function will return the value of variable @a name as
string. If the original value of the variable is not a string,
the value will be converted into a string.
@param name user variable name
@param value pointer to the value buffer
@param len length of the value buffer
@param precision precision of the value if it is a float number
@param null_value if not NULL, the function will set it to true if
the value of variable is null, set to false if not
@retval 0 Success
@retval 1 Variable not found
*/
int get_user_var_str(const char *name,
char *value, unsigned long len,
unsigned int precision, int *null_value);
#ifdef __cplusplus
}
......
......@@ -272,12 +272,7 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
if (!thd)
thd= current_thd;
const char* old_msg = thd->proc_info;
safe_mutex_assert_owner(mutex);
thd->mysys_var->current_mutex = mutex;
thd->mysys_var->current_cond = cond;
thd->proc_info = msg;
return old_msg;
return thd->enter_cond(cond, mutex, msg);
}
extern "C"
......@@ -286,18 +281,7 @@ void thd_exit_cond(MYSQL_THD thd, const char *old_msg)
if (!thd)
thd= current_thd;
/*
Putting the mutex unlock in thd_exit_cond() ensures that
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
locked (if that would not be the case, you'll get a deadlock if someone
does a THD::awake() on you).
*/
pthread_mutex_unlock(thd->mysys_var->current_mutex);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex = 0;
thd->mysys_var->current_cond = 0;
thd->proc_info = old_msg;
pthread_mutex_unlock(&thd->mysys_var->mutex);
thd->exit_cond(old_msg);
return;
}
......
......@@ -25,7 +25,6 @@
#include "log.h"
#include "rpl_tblmap.h"
#include "replication.h"
/**
An interface that is used to take an action when
......@@ -1886,11 +1885,28 @@ class THD :public Statement,
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
const char* msg)
{
return thd_enter_cond(this, cond, mutex, msg);
const char* old_msg = proc_info;
safe_mutex_assert_owner(mutex);
mysys_var->current_mutex = mutex;
mysys_var->current_cond = cond;
proc_info = msg;
return old_msg;
}
inline void exit_cond(const char* old_msg)
{
thd_exit_cond(this, old_msg);
/*
Putting the mutex unlock in thd->exit_cond() ensures that
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
locked (if that would not be the case, you'll get a deadlock if someone
does a THD::awake() on you).
*/
pthread_mutex_unlock(mysys_var->current_mutex);
pthread_mutex_lock(&mysys_var->mutex);
mysys_var->current_mutex = 0;
mysys_var->current_cond = 0;
proc_info = old_msg;
pthread_mutex_unlock(&mysys_var->mutex);
return;
}
inline time_t query_start() { query_start_used=1; return start_time; }
inline void set_time()
......
/* Copyright (C) 2005 MySQL AB
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
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
......@@ -99,7 +99,9 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_REPLICATION_INTERFACE_VERSION,
};
static bool initialized= 0;
/* support for Services */
#include "sql_plugin_services.h"
/*
A mutex LOCK_plugin must be acquired before accessing the
......@@ -113,6 +115,8 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
static bool reap_needed= false;
static int plugin_array_version=0;
static bool initialized= 0;
/*
write-lock on LOCK_system_variables_hash is required before modifying
the following variables/structures
......@@ -225,6 +229,22 @@ extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
#endif /* EMBEDDED_LIBRARY */
static void report_error(int where_to, uint error, ...)
{
va_list args;
if (where_to & REPORT_TO_USER)
{
va_start(args, error);
my_printv_error(error, ER(error), MYF(0), args);
va_end(args);
}
if (where_to & REPORT_TO_LOG)
{
va_start(args, error);
error_log_print(ERROR_LEVEL, ER(error), args);
va_end(args);
}
}
/****************************************************************************
Value type thunks, allows the C world to play in the C++ world
......@@ -345,7 +365,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
char dlpath[FN_REFLEN];
uint plugin_dir_len, dummy_errors, dlpathlen;
uint plugin_dir_len, dummy_errors, dlpathlen, i;
struct st_plugin_dl *tmp, plugin_dl;
void *sym;
DBUG_ENTER("plugin_dl_add");
......@@ -360,10 +380,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
system_charset_info, 1) ||
plugin_dir_len + dl->length + 1 >= FN_REFLEN)
{
if (report & REPORT_TO_USER)
my_error(ER_UDF_NO_PATHS, MYF(0));
if (report & REPORT_TO_LOG)
sql_print_error("%s", ER_DEFAULT(ER_UDF_NO_PATHS));
report_error(report, ER_UDF_NO_PATHS);
DBUG_RETURN(0);
}
/* If this dll is already loaded just increase ref_count. */
......@@ -388,21 +405,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (*errmsg == ':') errmsg++;
if (*errmsg == ' ') errmsg++;
}
if (report & REPORT_TO_USER)
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, errno, errmsg);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dlpath, errno, errmsg);
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
DBUG_RETURN(0);
}
/* Determine interface version */
if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY),
plugin_interface_version_sym);
report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
DBUG_RETURN(0);
}
plugin_dl.version= *(int *)sym;
......@@ -411,29 +421,42 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
(plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
"plugin interface version mismatch");
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dlpath, 0,
"plugin interface version mismatch");
report_error(report, ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
"plugin interface version mismatch");
DBUG_RETURN(0);
}
/* link the services in */
for (i= 0; i < array_elements(list_of_services); i++)
{
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
{
uint ver= (uint)(intptr)*(void**)sym;
if (ver > list_of_services[i].version ||
(ver >> 8) < (list_of_services[i].version >> 8))
{
char buf[MYSQL_ERRMSG_SIZE];
my_snprintf(buf, sizeof(buf),
"service '%s' interface version mismatch",
list_of_services[i].name);
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
DBUG_RETURN(0);
}
*(void**)sym= list_of_services[i].service;
}
}
/* Find plugin declarations */
if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY),
plugin_declarations_sym);
report_error(report, ER_CANT_FIND_DL_ENTRY, MYF(0),
plugin_declarations_sym);
DBUG_RETURN(0);
}
if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
{
int i;
uint sizeof_st_plugin;
struct st_mysql_plugin *old, *cur;
char *ptr= (char *)sym;
......@@ -443,11 +466,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
else
{
#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
DBUG_RETURN(0);
#else
/*
......@@ -469,10 +488,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (!cur)
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), plugin_dl.dl.length);
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
DBUG_RETURN(0);
}
/*
......@@ -494,10 +510,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), plugin_dl.dl.length);
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
DBUG_RETURN(0);
}
plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
......@@ -508,19 +521,13 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
{
free_plugin_mem(&plugin_dl);
if (report & REPORT_TO_USER)
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
report_error(report, ER_OUTOFMEMORY, sizeof(struct st_plugin_dl));
DBUG_RETURN(0);
}
DBUG_RETURN(tmp);
#else
DBUG_ENTER("plugin_dl_add");
if (report & REPORT_TO_USER)
my_error(ER_FEATURE_DISABLED, MYF(0), "plugin", "HAVE_DLOPEN");
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_FEATURE_DISABLED), "plugin", "HAVE_DLOPEN");
report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN");
DBUG_RETURN(0);
#endif
}
......@@ -636,7 +643,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
/*
For debugging, we do an additional malloc which allows the
memory manager and/or valgrind to track locked references and
double unlocks to aid resolving reference counting.problems.
double unlocks to aid resolving reference counting problems.
*/
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
DBUG_RETURN(NULL);
......@@ -719,10 +726,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
DBUG_ENTER("plugin_add");
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
if (report & REPORT_TO_USER)
my_error(ER_UDF_EXISTS, MYF(0), name->str);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_UDF_EXISTS), name->str);
report_error(report, ER_UDF_EXISTS, name->str);
DBUG_RETURN(TRUE);
}
/* Clear the whole struct to catch future extensions. */
......@@ -749,10 +753,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
strxnmov(buf, sizeof(buf) - 1, "API version for ",
plugin_type_names[plugin->type].str,
" plugin is too different", NullS);
if (report & REPORT_TO_USER)
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dl->str, 0, buf);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dl->str, 0, buf);
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
goto err;
}
tmp.plugin= plugin;
......@@ -781,10 +782,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
DBUG_RETURN(FALSE);
}
}
if (report & REPORT_TO_USER)
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
if (report & REPORT_TO_LOG)
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY), name->str);
report_error(report, ER_CANT_FIND_DL_ENTRY, name->str);
err:
plugin_dl_del(dl);
DBUG_RETURN(TRUE);
......
......@@ -35,16 +35,6 @@ class sys_var;
#define INITIAL_LEX_PLUGIN_LIST_SIZE 16
/*
the following #define adds server-only members to enum_mysql_show_type,
that is defined in plugin.h
*/
#define SHOW_FUNC SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \
SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, \
SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH, \
SHOW_LONGLONG_STATUS
#include <mysql/plugin.h>
#undef SHOW_FUNC
typedef enum enum_mysql_show_type SHOW_TYPE;
typedef struct st_mysql_show_var SHOW_VAR;
......
/* Copyright (C) 2009 Sun Microsystems, Inc.
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; version 2 of the License.
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 */
/* support for Services */
#include <service_versions.h>
struct st_service_ref {
const char *name;
uint version;
void *service;
};
static struct my_snprintf_service_st my_snprintf_handler = {
my_snprintf,
my_vsnprintf
};
static struct thd_alloc_service_st thd_alloc_handler= {
thd_alloc,
thd_calloc,
thd_strdup,
thd_strmake,
thd_memdup,
thd_make_lex_string
};
static struct st_service_ref list_of_services[]=
{
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
{ "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }
};
......@@ -34,7 +34,7 @@ noinst_HEADERS = ha_example.h
EXTRA_LTLIBRARIES = ha_example.la
pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
ha_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_example_la_SOURCES = ha_example.cc
......
/* Copyright (C) 2003 MySQL AB
/* Copyright (C) 2003 MySQL AB, 2009 Sun Microsystems, Inc.
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
......@@ -921,6 +921,24 @@ static struct st_mysql_sys_var* example_system_variables[]= {
NULL
};
// this is an example of SHOW_FUNC and of my_snprintf() service
static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
char *buf)
{
var->type= SHOW_CHAR;
var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes
my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE,
"enum_var is %u, ulong_var is %lu, %.6b", // %b is MySQL extension
srv_enum_var, srv_ulong_var, "really");
return 0;
}
static struct st_mysql_show_var func_status[]=
{
{"example_func_example", (char *)show_func_example, SHOW_FUNC},
{0,0,SHOW_UNDEF}
};
mysql_declare_plugin(example)
{
MYSQL_STORAGE_ENGINE_PLUGIN,
......@@ -932,7 +950,7 @@ mysql_declare_plugin(example)
example_init_func, /* Plugin Init */
example_done_func, /* Plugin Deinit */
0x0001 /* 0.1 */,
NULL, /* status variables */
func_status, /* status variables */
example_system_variables, /* system variables */
NULL /* config options */
}
......
......@@ -34,7 +34,7 @@ IF(NOT SOURCE_SUBLIBS)
#The dll is linked to the mysqld executable
SET(dyn_libname ha_${libname})
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
TARGET_LINK_LIBRARIES (${dyn_libname} mysqld)
TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld)
IF(${engine}_LIBS)
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
......
......@@ -472,6 +472,8 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
/**
Produces output string according to a format string
See the detailed documentation around my_snprintf_service_st
@param cs string charset
@param to buffer where processed string will be place
@param n size of buffer
......
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