├── NEWS ├── AUTHORS ├── Makefile.am ├── tests ├── Makefile.am ├── Makefile.in └── memc_test.cmp ├── .gitignore ├── src ├── Makefile.am ├── version.c ├── increment.c ├── decrement.c ├── libmemcached_config.h.in ├── common.h ├── delete.c ├── replace.c ├── prepend.c ├── add.c ├── append.c ├── get.c ├── get_cas.c ├── args.c ├── set.c └── stats.c ├── configure.ac ├── docs ├── memc_udf_version.pod ├── memc_list_behaviors.pod ├── memc_list_hash_types.pod ├── memc_libmemcached_version.pod ├── memc_list_distribution_types.pod ├── memc_servers_set.pod ├── memc_decrement.pod ├── memc_increment.pod ├── memc_behavior_get.pod ├── memc_servers_behavior_get.pod ├── memc_stats.pod ├── memc_append.pod ├── memc_prepend.pod ├── memc_behavior_set.pod ├── memc_servers_behavior_set.pod ├── memc_get.pod ├── memc_set.pod ├── Makefile.am └── Makefile.in ├── config ├── ac_libmemcached.m4 ├── ac_mysql.m4 ├── bootstrap ├── missing └── install-sh ├── sql ├── trigger_fun.sql └── install_functions.sql ├── benchmarks └── benchmark.pl ├── ChangeLog ├── utils └── install.pl ├── INSTALL └── README.md /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Patrick Galbraith, patg@patg.net 2 | Brian Aker, brian@tangent.org 3 | Trond Norbye, trond.norbye@sun.com 4 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = 2 | SUBDIRS = src tests docs 3 | EXTRA_DIST = utils sql benchmarks config/bootstrap config/ac_mysql.m4 4 | 5 | test: all 6 | cd tests; make test; cd .. 7 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = 2 | LDADDS = 3 | LIBS = 4 | 5 | EXTRA_DIST = memc_test.cmp memc_test.sql 6 | 7 | 8 | record: 9 | cat memc_test.sql | mysql > memc_test.cmp 10 | 11 | test: testapp 12 | cat memc_test.sql | mysql > memc_test.res 13 | diff memc_test.cmp memc_test.res 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = common.h 2 | INCLUDES = -I$(top_builddir)/include $(MYSQL_INC) 3 | 4 | lib_LTLIBRARIES = libmemcached_functions_mysql.la 5 | libmemcached_functions_mysql_la_SOURCES = args.c add.c get.c set.c prepend.c replace.c increment.c decrement.c append.c delete.c servers.c version.c stats.c get_cas.c 6 | libmemcached_functions_mysql_la_LDFLAGS = -module 7 | # had to add this back 8 | libmemcached_functions_mysql_la_LIBADD = $(DEPS_LIBS) 9 | 10 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT(src/get.c) 2 | AC_CONFIG_AUX_DIR(config) 3 | AM_CONFIG_HEADER(src/libmemcached_config.h) 4 | 5 | AM_INIT_AUTOMAKE("memcached_functions_mysql", 1.1 ) 6 | 7 | AC_PROG_CC 8 | AC_PROG_LIBTOOL 9 | LIBTOOL="$LIBTOOL --preserve-dup-deps" 10 | AC_SUBST(LIBTOOL)dnl 11 | 12 | sinclude(config/ac_mysql.m4) 13 | MYSQL_CONFIG_TEST 14 | 15 | AC_SUBST(MYSQL_CONFIG) 16 | AC_SUBST(MYSQL_INC) 17 | AC_SUBST(MYSQL_LIB) 18 | 19 | sinclude(config/ac_libmemcached.m4) 20 | LIBMEMCACHED_CONFIG_TEST 21 | 22 | AC_SUBST(DEPS_CFLAGS) 23 | AC_SUBST(DEPS_LIBS) 24 | 25 | AC_C_CONST 26 | AC_TYPE_SIZE_T 27 | AC_CHECK_HEADERS(limits.h syslimits.h) 28 | AC_OUTPUT(Makefile src/Makefile tests/Makefile docs/Makefile) 29 | -------------------------------------------------------------------------------- /docs/memc_udf_version.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_udf_version 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_udf_version() is a UDF used to obtain the version string of 14 | the Memcached Functions for MySQL 15 | 16 | =head1 RETURN 17 | 18 | NULL 19 | 20 | =head1 USAGE 21 | 22 | memc_udf_version() 23 | 24 | =head1 HOME 25 | 26 | To find out more information please check: 27 | L 28 | L 29 | 30 | =head1 INSTALL 31 | 32 | CREATE FUNCTION memc_udf_version RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 33 | 34 | =head1 AUTHOR 35 | 36 | Patrick Galbraith, Epatg@patg.netE 37 | 38 | =head1 SEE ALSO 39 | 40 | memc_libmemcached_version() 41 | 42 | =cut 43 | 44 | -------------------------------------------------------------------------------- /docs/memc_list_behaviors.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_list_behaviors 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_list_behaviors() is a UDF used to display behavior values used by 14 | the memc_servers_behavior_set() UDF 15 | This function takes no values. 16 | 17 | =head1 RETURN 18 | 19 | NULL 20 | 21 | =head1 HOME 22 | 23 | To find out more information please check: 24 | L 25 | L 26 | 27 | =head1 INSTALL 28 | 29 | CREATE FUNCTION memc_list_behaviors RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 30 | 31 | =head1 AUTHOR 32 | 33 | Patrick Galbraith, Epatg@patg.netE 34 | Brian Aker, Ebrian@tangent.orgE 35 | 36 | =head1 SEE ALSO 37 | 38 | memc_servers_set(), memc_servers_behavior_set() 39 | 40 | =cut 41 | 42 | -------------------------------------------------------------------------------- /docs/memc_list_hash_types.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_list_hash_types 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_list_hash_types() is a UDF used to display hash algorithm types 14 | the memc_behavior_set() UDF will take to set MEMCACHE_BEHAVIOR_HASH 15 | 16 | =head1 RETURN 17 | 18 | NULL 19 | 20 | =head1 HOME 21 | 22 | To find out more information please check: 23 | L 24 | L 25 | 26 | =head1 INSTALL 27 | 28 | CREATE FUNCTION memc_list_hash_types RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 29 | 30 | =head1 AUTHOR 31 | 32 | Patrick Galbraith, Epatg@patg.netE 33 | Brian Aker, Ebrian@tangent.orgE 34 | 35 | =head1 SEE ALSO 36 | 37 | memc_servers_set(), memc_servers_behavior_set(), memc_behavior_set() 38 | 39 | =cut 40 | 41 | -------------------------------------------------------------------------------- /docs/memc_libmemcached_version.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_libmemcached_version 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_libmemcached_version() is a UDF used to obtain the version string of the 14 | libmemcached library the Memcached Functions for MySQL were compiled/linked 15 | against 16 | 17 | =head1 RETURN 18 | 19 | NULL 20 | 21 | =head1 USAGE 22 | 23 | memc_libmemcached_version() 24 | 25 | =head1 HOME 26 | 27 | To find out more information please check: 28 | L 29 | L 30 | 31 | =head1 INSTALL 32 | 33 | CREATE FUNCTION memc_libmemcached_version RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 34 | 35 | =head1 AUTHOR 36 | 37 | Patrick Galbraith, Epatg@patg.netE 38 | 39 | =head1 SEE ALSO 40 | 41 | memc_udf_version() 42 | 43 | =cut 44 | 45 | -------------------------------------------------------------------------------- /docs/memc_list_distribution_types.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_list_distribution_types 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_list_distribution_types() is a UDF used to display 14 | distribution algorithm types. The memc_behavior_set() can set this 15 | value for the behavior MEMCACHED_BEHAVIOR_DISTRIBUTION 16 | 17 | This function takes no values 18 | 19 | =head1 RETURN 20 | 21 | NULL 22 | 23 | =head1 HOME 24 | 25 | To find out more information please check: 26 | L 27 | L 28 | 29 | =head1 INSTALL 30 | 31 | CREATE FUNCTION memc_list_distribution_types RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 32 | 33 | =head1 AUTHOR 34 | 35 | Patrick Galbraith, Epatg@patg.netE 36 | Brian Aker, Ebrian@tangent.orgE 37 | 38 | =head1 SEE ALSO 39 | 40 | memc_servers_set(), memc_servers_behavior_set() 41 | 42 | =cut 43 | 44 | -------------------------------------------------------------------------------- /docs/memc_servers_set.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_servers_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_servers_set() is a UDF used to set which memcached server you 14 | wish your memcached UDFs to interact with / connect to. The only 15 | argument is a string of comma-separated memcached servers, 16 | hostname/ip:port (if port). 17 | 18 | =head1 RETURN 19 | 20 | NULL 21 | 22 | =head1 USAGE 23 | 24 | memc_servers_set('localhost:11211') 25 | 26 | =head1 HOME 27 | 28 | To find out more information please check: 29 | L 30 | L 31 | 32 | =head1 INSTALL 33 | 34 | CREATE FUNCTION memc_servers_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 35 | 36 | =head1 AUTHOR 37 | 38 | Patrick Galbraith, Epatg@patg.netE 39 | Brian Aker, Ebrian@tangent.orgE 40 | 41 | =head1 SEE ALSO 42 | 43 | memc_servers_set(), memc_servers_behavior_set() 44 | 45 | =cut 46 | 47 | -------------------------------------------------------------------------------- /docs/memc_decrement.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_decrement 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_decrement() is a UDF used to decrement an integer value stored in 14 | memcached server from within MySQL. You first argument you must pass a 15 | key value for the integer stored. The second argument can be can either 16 | pass a data value to decrement by, or default is 1. 17 | 18 | =head1 RETURN 19 | 20 | NULL 21 | 22 | =head1 USAGE 23 | 24 | memc_decrement('keyfoo') <-- decrements by 1 25 | memc_decrement('keyfoo', 3) <-- decrements by 3 26 | 27 | =head1 HOME 28 | 29 | To find out more information please check: 30 | L 31 | L 32 | 33 | =head1 INSTALL 34 | 35 | CREATE FUNCTION memc_decrement RETURNS INT SONAME "libmemcached_functions_mysql.so"; 36 | 37 | =head1 AUTHOR 38 | 39 | Patrick Galbraith, Epatg@patg.netE 40 | Brian Aker, Ebrian@tangent.orgE 41 | 42 | =head1 SEE ALSO 43 | 44 | memc_increment() 45 | 46 | =cut 47 | 48 | -------------------------------------------------------------------------------- /docs/memc_increment.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_increment 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_increment() is a UDF used to increment an integer value stored in 14 | memcached server from within MySQL. You first argument you must pass a 15 | key value for the integer stored. The second argument can be can either 16 | pass a data value to increment by, or default is 1. 17 | 18 | =head1 RETURN 19 | 20 | NULL 21 | 22 | =head1 USAGE 23 | 24 | memc_increment('keyfoo') <-- increments object stored as keyfoo by 1 25 | memc_increment('keyfoo', 3) <-- increments object stored as keyfoo by 3 26 | 27 | =head1 HOME 28 | 29 | To find out more information please check: 30 | L 31 | L 32 | 33 | =head1 INSTALL 34 | 35 | CREATE FUNCTION memc_increment RETURNS INT SONAME "libmemcached_functions_mysql.so"; 36 | 37 | =head1 AUTHOR 38 | 39 | Patrick Galbraith, Epatg@patg.netE 40 | Brian Aker, Ebrian@tangent.orgE 41 | 42 | =head1 SEE ALSO 43 | 44 | memc_decrement() 45 | 46 | =cut 47 | 48 | -------------------------------------------------------------------------------- /docs/memc_behavior_get.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_behavior_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_behavior_get() is a UDF used to retrieve the behavior of a connection 14 | to a memcached server from within MySQL. An alias to this function is memc_servers_behavior_get(); 15 | 16 | =head1 RETURN 17 | 18 | NULL 19 | 20 | =head1 USAGE 21 | 22 | select memc_behavior_get('MEMCACHED_BEHAVIOR_SUPPORT_CAS'); 23 | 24 | or with SET: 25 | 26 | set @setval = memc_behavior_get('MEMCACHED_BEHAVIOR_SUPPORT_CAS'); 27 | select @setval; 28 | 29 | 30 | =head1 HOME 31 | 32 | To find out more information please check: 33 | L 34 | L 35 | 36 | =head1 INSTALL 37 | 38 | CREATE FUNCTION memc_behavior_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 39 | 40 | =head1 AUTHOR 41 | 42 | Patrick Galbraith, Epatg@patg.netE 43 | Brian Aker, Ebrian@tangent.orgE 44 | 45 | =head1 SEE ALSO 46 | 47 | memc_set(), memc_behavior_get(), memc_behavior_set(), memc_behavior_set(), memc_list_behaviors() 48 | 49 | =cut 50 | 51 | -------------------------------------------------------------------------------- /docs/memc_servers_behavior_get.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_servers_behavior_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_servers_behavior_get() is a UDF used to retrieve the behavior of a connection 14 | to a memcached server from within MySQL. An alias to this function is memc_behavior_get(); 15 | 16 | =head1 RETURN 17 | 18 | NULL 19 | 20 | =head1 USAGE 21 | 22 | select memc_servers_behavior_get('MEMCACHED_BEHAVIOR_SUPPORT_CAS'); 23 | 24 | or with SET: 25 | 26 | set @setval = memc_behavior_get('MEMCACHED_BEHAVIOR_SUPPORT_CAS'); 27 | select @setval; 28 | 29 | 30 | =head1 HOME 31 | 32 | To find out more information please check: 33 | L 34 | L 35 | 36 | =head1 INSTALL 37 | 38 | CREATE FUNCTION memc_servers_behavior_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 39 | 40 | =head1 AUTHOR 41 | 42 | Patrick Galbraith, Epatg@patg.netE 43 | Brian Aker, Ebrian@tangent.orgE 44 | 45 | =head1 SEE ALSO 46 | 47 | memc_servers_set(), memc_behavior_get(), memc_servers_behavior_set(), memc_behavior_set(), memc_list_behaviors() 48 | 49 | =cut 50 | 51 | -------------------------------------------------------------------------------- /docs/memc_stats.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | memc_stats('hostname1,hostname2'); 12 | 13 | memc_stat_get_keys(); 14 | 15 | =head1 DESCRIPTION 16 | 17 | memc_stats() is a UDF used to retrieve the statistics of memcached server (one or more) state 18 | 19 | memc_stat_get_keys() is a UDF used to retrieve the various memcached state keys 20 | 21 | memc_stat_get_value() is a UDF used to retrieve a specific memcached state key from a specific server 22 | 23 | =head1 RETURN 24 | 25 | NULL 26 | 27 | =head1 HOME 28 | 29 | To find out more information please check: 30 | L 31 | L 32 | 33 | =head1 INSTALL 34 | 35 | CREATE FUNCTION memc_stats RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 36 | CREATE FUNCTION memc_stat_get_keys RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 37 | CREATE FUNCTION memc_stat_get_value RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 38 | 39 | =head1 AUTHOR 40 | 41 | Patrick Galbraith, Epatg@patg.netE 42 | Brian Aker, Ebrian@tangent.orgE 43 | 44 | =head1 SEE ALSO 45 | 46 | memc_set(), memc_delete()... 47 | 48 | =cut 49 | 50 | -------------------------------------------------------------------------------- /docs/memc_append.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_append 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_append() is a UDF used to prepend content to the end of an 14 | existing individual value from the memcached server from within 15 | MySQL. The first argument you must pass in a key value. The second 16 | aregument must be a data value which you wish to append to the end 17 | of your existing value stored in memcached. 18 | 19 | memc_append_by_key() is a UDF that does the same thing as 20 | memc_append() with and additional (1st arg) master key. 21 | 22 | =head1 RETURN 23 | 24 | 25 | =head1 USAGE 26 | 27 | memc_append('keyfoo', ' this will be appended to the end of object'); 28 | memc_append('master keyA', 'keyfoo', ' this will be appended to the end of object'); 29 | 30 | NULL 31 | 32 | =head1 HOME 33 | 34 | To find out more information please check: 35 | L 36 | L 37 | 38 | =head1 INSTALL 39 | 40 | CREATE FUNCTION memc_append RETURNS INT SONAME "libmemcached_functions_mysql.so"; 41 | CREATE FUNCTION memc_append_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 42 | 43 | =head1 AUTHOR 44 | 45 | Patrick Galbraith, Epatg@patg.netE 46 | Brian Aker, Ebrian@tangent.orgE 47 | 48 | =head1 SEE ALSO 49 | 50 | memc_prepend() 51 | 52 | =cut 53 | 54 | -------------------------------------------------------------------------------- /docs/memc_prepend.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_prepend 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_prepend() is a UDF used to prepend content to the beginning 14 | of an existing individual value from the memcached server from within 15 | MySQL. The first argument you must pass in a key value. The second 16 | aregument must be a data value which you wish to prepend to the end 17 | of your existing value stored in memcached. 18 | 19 | memc_prepend_by_key() functions the same as memc_prepend() with the addition 20 | requirement of a master key supplied (1st arg) 21 | 22 | =head1 RETURN 23 | 24 | NULL 25 | 26 | =head1 USAGE 27 | 28 | memc_prepend('keyfoo', 'this will be prepended to beginning of object') 29 | memc_prepend_by_key('masterA', 'keyfoo', 'this will be prepended to beginning of object') 30 | 31 | 32 | =head1 HOME 33 | 34 | To find out more information please check: 35 | L 36 | L 37 | 38 | =head1 INSTALL 39 | 40 | CREATE FUNCTION memc_prepend RETURNS INT SONAME "libmemcached_functions_mysql.so"; 41 | CREATE FUNCTION memc_prepend_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 42 | 43 | =head1 AUTHOR 44 | 45 | Patrick Galbraith, Epatg@patg.netE 46 | Brian Aker, Ebrian@tangent.orgE 47 | 48 | =head1 SEE ALSO 49 | 50 | memc_append() 51 | 52 | =cut 53 | 54 | -------------------------------------------------------------------------------- /config/ac_libmemcached.m4: -------------------------------------------------------------------------------- 1 | dnl --------------------------------------------------------------------------- 2 | dnl Macro: LIBMEMCACHED_CONFIG_TEST 3 | dnl --------------------------------------------------------------------------- 4 | AC_DEFUN([LIBMEMCACHED_CONFIG_TEST], [ 5 | LIBS="-lmemcached" 6 | AC_ARG_WITH(libmemcached, 7 | [ --with-libmemcached Specify libmemcached location], 8 | [ 9 | if test -n "$withval" 10 | then 11 | CFLAGS="-I${withval}/include $CFLAGS" 12 | LDFLAGS="-L${withval}/lib $LDFLAGS" 13 | 14 | if test "`uname -s`" = "SunOS" 15 | then 16 | LDFLAGS="$LDFLAGS -Wl,-R${withval}/lib" 17 | else 18 | LDFLAGS="$LDFLAGS -Wl,--rpath -Wl,${withval}/lib" 19 | fi 20 | fi 21 | ]) 22 | 23 | AC_MSG_CHECKING([for libmemcached >= 0.17]) 24 | AC_RUN_IFELSE([ 25 | AC_LANG_PROGRAM([ 26 | #include 27 | #include 28 | #include "libmemcached/memcached.h" 29 | ], [ 30 | char *dot = strrchr(LIBMEMCACHED_VERSION_STRING, '.'); 31 | if ((atoi(LIBMEMCACHED_VERSION_STRING)) > 0 || 32 | (dot != NULL && atoi(dot + 1) > 16)) { 33 | return 0; 34 | } 35 | 36 | return 1; 37 | ]) 38 | ],, AC_MSG_ERROR([libmemcached not found])) 39 | AC_MSG_RESULT(yes) 40 | ]) 41 | dnl --------------------------------------------------------------------------- 42 | dnl Macro: LIBMEMCACHED_CONFIG_TEST 43 | dnl --------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- /docs/memc_behavior_set.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_behavior_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_behavior_set() is a UDF used to set the behavior of a connection 14 | to a memcached server from within MySQL. You must pass in a behavior string 15 | (please use memc_list_behaviors() UDF to obtain possible values) and setting 16 | value - quoted (important). 17 | 18 | An alias to this function is memc_servers_behavior_set() 19 | 20 | =head1 RETURN 21 | 22 | NULL 23 | 24 | =head1 USAGE 25 | 26 | boolean: 27 | 28 | select memc_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', 1); 29 | 30 | or with SET: 31 | 32 | set @setval = memc_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', 1); 33 | select @setval; 34 | 35 | canonical: 36 | 37 | select memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_MD5' ); 38 | 39 | numeric: 40 | 41 | select memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE', 60000); 42 | 43 | =head1 HOME 44 | 45 | To find out more information please check: 46 | L 47 | L 48 | 49 | =head1 INSTALL 50 | 51 | CREATE FUNCTION memc_behavior_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 52 | 53 | =head1 AUTHOR 54 | 55 | Patrick Galbraith, Epatg@patg.netE 56 | Brian Aker, Ebrian@tangent.orgE 57 | 58 | =head1 SEE ALSO 59 | 60 | memc_set(), memc_list_behaviors() 61 | 62 | =cut 63 | 64 | -------------------------------------------------------------------------------- /docs/memc_servers_behavior_set.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_servers_behavior_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_servers_behavior_set() is a UDF used to set the behavior of a connection 14 | to a memcached server from within MySQL. You must pass in a behavior string 15 | (please use memc_list_behaviors() UDF to obtain possible values) and setting 16 | value - quoted (important). 17 | 18 | An alias to this function is memc_behavior_set() 19 | 20 | =head1 RETURN 21 | 22 | NULL 23 | 24 | =head1 USAGE 25 | 26 | boolean: 27 | 28 | select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', 1); 29 | 30 | or with SET: 31 | 32 | set @setval = memc_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', 1); 33 | select @setval; 34 | 35 | canonical: 36 | 37 | select memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_MD5' ); 38 | 39 | numeric: 40 | 41 | select memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE', 60000); 42 | 43 | =head1 HOME 44 | 45 | To find out more information please check: 46 | L 47 | L 48 | 49 | =head1 INSTALL 50 | 51 | CREATE FUNCTION memc_servers_behavior_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 52 | 53 | =head1 AUTHOR 54 | 55 | Patrick Galbraith, Epatg@patg.netE 56 | Brian Aker, Ebrian@tangent.orgE 57 | 58 | =head1 SEE ALSO 59 | 60 | memc_servers_set(), memc_list_behaviors() 61 | 62 | =cut 63 | 64 | -------------------------------------------------------------------------------- /src/version.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "common.h" 15 | #define BRIAN_LIKES_LOOP 1; 16 | 17 | 18 | 19 | my_bool memc_udf_version_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 20 | char *memc_udf_version(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error); 21 | 22 | my_bool memc_udf_version_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 23 | { 24 | char *version_string; 25 | /* this is how to fail */ 26 | if (args->arg_count > 0) 27 | { 28 | strncpy(message, "This function requires no arguments: memc_udf_version()", MYSQL_ERRMSG_SIZE); 29 | return 1; 30 | } 31 | 32 | version_string= calloc(1, VERSION_STRING_LENGTH + 1); 33 | strncpy(version_string, VERSION_STRING, VERSION_STRING_LENGTH); 34 | initid->ptr= version_string; 35 | 36 | return 0; 37 | } 38 | 39 | /* 40 | memc_servers_set 41 | get cached object, takes hash-key arg 42 | */ 43 | char *memc_udf_version(__attribute__ ((unused)) UDF_INIT *initid, 44 | __attribute__ ((unused)) UDF_ARGS *args, 45 | __attribute__ ((unused)) char *result, 46 | __attribute__ ((unused)) unsigned long *length, 47 | __attribute__ ((unused)) char *is_null, 48 | __attribute__ ((unused)) char *error) 49 | { 50 | char *version_string= initid->ptr; 51 | *length= VERSION_STRING_LENGTH; 52 | return (version_string); 53 | } 54 | -------------------------------------------------------------------------------- /docs/memc_get.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_get, memc_mget 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_get() is a UDF used to fetch an individual value from the memcached 14 | server from within MySQL. You must pass in a key to fetch the object. 15 | 16 | memc_get_by_key() is a UDF used to fetch an individual value from the memcached 17 | server from within MySQL. You must pass in a master key, as well as a key to fetch 18 | the object. 19 | 20 | memcached_mget() 21 | is used to select multiple keys at once. For multiple key 22 | operations it is always faster to use this function. This function always 23 | works asynchronously. memcached_fetch() is then used to retrieve any keys 24 | found. No error is given on keys that are not found. 25 | 26 | =head1 RETURN 27 | 28 | Data stored in Memcached keyed by supplied hash value 29 | 30 | =head1 USAGE 31 | 32 | memc_get('keyfoo') <-- fetches object stored as 'keyfoo' 33 | memc_get_by_key('masterA', 'keyfoo') <-- fetches object stored as 'keyfoo' 34 | 35 | =head1 HOME 36 | 37 | To find out more information please check: 38 | L 39 | L 40 | 41 | =head1 INSTALL 42 | 43 | CREATE FUNCTION memc_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 44 | CREATE FUNCTION memc_get_by_key RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 45 | 46 | =head1 AUTHOR 47 | 48 | Patrick Galbraith, Epatg@patg.netE 49 | Brian Aker, Ebrian@tangent.orgE 50 | 51 | =head1 SEE ALSO 52 | 53 | memc_set(), memc_set_by_key(), memc_delete()... 54 | 55 | =cut 56 | 57 | -------------------------------------------------------------------------------- /config/ac_mysql.m4: -------------------------------------------------------------------------------- 1 | dnl --------------------------------------------------------------------------- 2 | dnl Macro: MYSQL_CONFIG 3 | dnl --------------------------------------------------------------------------- 4 | AC_DEFUN([MYSQL_CONFIG_TEST], [ 5 | AC_ARG_WITH(mysql, 6 | [[ --with-mysql[=mysql_config] 7 | Support for the MySQL.]], 8 | [ 9 | if test -n "$withval"; then 10 | if test "$withval" = "yes"; then 11 | AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], "no", [$PATH:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/mysql/bin]) 12 | if test "x$MYSQL_CONFIG" == "xno"; then 13 | AC_MSG_ERROR(["could not find mysql_config"]) 14 | fi 15 | else 16 | AC_MSG_CHECKING(for mysql_config) 17 | MYSQL_CONFIG="$withval" 18 | if test ! -f "$MYSQL_CONFIG"; then 19 | AC_MSG_ERROR(["could not find mysql_config 2 : $MYSQL_CONFIG"]) 20 | fi 21 | AC_MSG_RESULT([$MYSQL_CONFIG]) 22 | fi 23 | else 24 | AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], "no", [$PATH:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/mysql/bin]) 25 | if test "x$MYSQL_CONFIG" == "xno"; then 26 | AC_MSG_ERROR(["could not find mysql_config"]) 27 | fi 28 | fi 29 | ], 30 | [ 31 | AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], "no", [$PATH]) 32 | if test "x$MYSQL_CONFIG" == "xno"; then 33 | AC_MSG_ERROR(["could not find mysql_config"]) 34 | fi 35 | ]) 36 | 37 | AC_DEFINE([MYSQL_ENABLED], [1], [Enables MySQL]) 38 | MYSQL_INC="`$MYSQL_CONFIG --cflags`" 39 | MYSQL_LIB="`$MYSQL_CONFIG --libmysqld-libs`" 40 | ]) 41 | 42 | dnl --------------------------------------------------------------------------- 43 | dnl Macro: MYSQL_CONFIG 44 | dnl --------------------------------------------------------------------------- 45 | -------------------------------------------------------------------------------- /sql/trigger_fun.sql: -------------------------------------------------------------------------------- 1 | drop table if exists urls; 2 | create table urls ( 3 | id int(3) not null, 4 | url varchar(64) not null default '', 5 | primary key (id) 6 | ); 7 | 8 | select memc_servers_set('localhost:11211'); 9 | select memc_set('urls:sequence', 0); 10 | 11 | DELIMITER | 12 | 13 | DROP TRIGGER IF EXISTS url_mem_insert | 14 | CREATE TRIGGER url_mem_insert 15 | BEFORE INSERT ON urls 16 | FOR EACH ROW BEGIN 17 | SET NEW.id= memc_increment('urls:sequence'); 18 | SET @mm= memc_set(concat('urls:',NEW.id), NEW.url); 19 | END | 20 | 21 | DROP TRIGGER IF EXISTS url_mem_update | 22 | CREATE TRIGGER url_mem_update 23 | BEFORE UPDATE ON urls 24 | FOR EACH ROW BEGIN 25 | SET @mm= memc_replace(concat('urls:',OLD.id), NEW.url); 26 | END | 27 | 28 | DROP TRIGGER IF EXISTS url_mem_delete | 29 | CREATE TRIGGER url_mem_delete 30 | BEFORE DELETE ON urls 31 | FOR EACH ROW BEGIN 32 | SET @mm= memc_delete(concat('urls:',OLD.id)); 33 | END | 34 | 35 | DELIMITER ; 36 | 37 | insert into urls (url) values ('http://google.com'); 38 | insert into urls (url) values ('http://lycos.com/'); 39 | insert into urls (url) values ('http://tripod.com/'); 40 | insert into urls (url) values ('http://microsoft.com/'); 41 | insert into urls (url) values ('http://slashdot.org'); 42 | insert into urls (url) values ('http://mysql.com'); 43 | select * from urls; 44 | 45 | select memc_get('urls:1'); 46 | select memc_get('urls:2'); 47 | select memc_get('urls:3'); 48 | select memc_get('urls:4'); 49 | select memc_get('urls:5'); 50 | select memc_get('urls:6'); 51 | 52 | update urls set url= 'http://mysql.com/sun' where url = 'http://mysql.com'; 53 | select url from urls where url = 'http://mysql.com/sun'; 54 | select memc_get('urls:6'); 55 | 56 | delete from urls where url = 'http://microsoft.com/'; 57 | select * from urls where url='http://microsoft.com/'; 58 | select memc_get('urls:4'); 59 | 60 | -------------------------------------------------------------------------------- /src/increment.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_increment_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_increment(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_increment_deinit(UDF_INIT *initid); 17 | 18 | my_bool memc_increment_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 19 | { 20 | unsigned int x; 21 | memcached_return rc; 22 | memc_function_st *container; 23 | 24 | container= prepare_args(args, message, MEMC_INCREMENT, 1, 2); 25 | if (container == NULL) 26 | return 1; 27 | 28 | /* Init the memcached_st we will use for this pass */ 29 | rc= memc_get_servers(&container->memc); 30 | 31 | initid->ptr= (char *)container; 32 | 33 | return 0; 34 | } 35 | 36 | long long memc_increment(UDF_INIT *initid, UDF_ARGS *args, 37 | __attribute__ ((unused)) char *is_null, 38 | __attribute__ ((unused)) char *error) 39 | { 40 | memcached_return rc; 41 | uint64_t value; 42 | memc_function_st *container= (memc_function_st *)initid->ptr; 43 | container->offset= args->arg_count == 2 ? (unsigned int)atoi(args->args[1]) : 1; 44 | 45 | rc= memcached_increment(&container->memc, 46 | args->args[0], (size_t)args->lengths[0], 47 | container->offset, 48 | &value); 49 | 50 | return ((long long)value); 51 | } 52 | 53 | void memc_increment_deinit(UDF_INIT *initid) 54 | { 55 | /* if we allocated initid->ptr, free it here */ 56 | memc_function_st *container= (memc_function_st *)initid->ptr; 57 | 58 | memcached_free(&container->memc); 59 | free(container); 60 | } 61 | -------------------------------------------------------------------------------- /src/decrement.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_decrement_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_decrement(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_decrement_deinit(UDF_INIT *initid); 17 | 18 | my_bool memc_decrement_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 19 | { 20 | unsigned int x; 21 | memcached_return rc; 22 | memc_function_st *container; 23 | 24 | container= prepare_args(args, message, MEMC_DECREMENT, 1, 2); 25 | if (container == NULL) 26 | return 1; 27 | 28 | /* Init the memcached_st we will use for this pass */ 29 | rc= memc_get_servers(&container->memc); 30 | 31 | initid->ptr= (char *)container; 32 | 33 | return 0; 34 | } 35 | 36 | long long memc_decrement(UDF_INIT *initid, UDF_ARGS *args, 37 | __attribute__ ((unused)) char *is_null, 38 | __attribute__ ((unused)) char *error) 39 | { 40 | memcached_return rc; 41 | uint64_t value; 42 | unsigned int offset; 43 | memc_function_st *container= (memc_function_st *)initid->ptr; 44 | container->offset= args->arg_count == 2 ? (unsigned int)atoi(args->args[1]) : 1; 45 | 46 | rc= memcached_decrement(&container->memc, 47 | args->args[0], (size_t)args->lengths[0], 48 | container->offset, 49 | &value); 50 | 51 | return ((long long)value); 52 | } 53 | 54 | void memc_decrement_deinit(UDF_INIT *initid) 55 | { 56 | /* if we allocated initid->ptr, free it here */ 57 | memc_function_st *container= (memc_function_st *)initid->ptr; 58 | 59 | memcached_free(&container->memc); 60 | free(container); 61 | } 62 | -------------------------------------------------------------------------------- /src/libmemcached_config.h.in: -------------------------------------------------------------------------------- 1 | /* src/libmemcached_config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define to 1 if you have the header file. */ 4 | #undef HAVE_DLFCN_H 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_INTTYPES_H 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_LIMITS_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_MEMORY_H 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_STDINT_H 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_STDLIB_H 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_STRINGS_H 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #undef HAVE_STRING_H 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_SYSLIMITS_H 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_SYS_STAT_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_SYS_TYPES_H 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_UNISTD_H 38 | 39 | /* Enables MySQL */ 40 | #undef MYSQL_ENABLED 41 | 42 | /* Name of package */ 43 | #undef PACKAGE 44 | 45 | /* Define to the address where bug reports for this package should be sent. */ 46 | #undef PACKAGE_BUGREPORT 47 | 48 | /* Define to the full name of this package. */ 49 | #undef PACKAGE_NAME 50 | 51 | /* Define to the full name and version of this package. */ 52 | #undef PACKAGE_STRING 53 | 54 | /* Define to the one symbol short name of this package. */ 55 | #undef PACKAGE_TARNAME 56 | 57 | /* Define to the version of this package. */ 58 | #undef PACKAGE_VERSION 59 | 60 | /* Define to 1 if you have the ANSI C header files. */ 61 | #undef STDC_HEADERS 62 | 63 | /* Version number of package */ 64 | #undef VERSION 65 | 66 | /* Define to empty if `const' does not conform to ANSI C. */ 67 | #undef const 68 | 69 | /* Define to `unsigned int' if does not define. */ 70 | #undef size_t 71 | -------------------------------------------------------------------------------- /benchmarks/benchmark.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Simple script (for now) to run against the Memcached UDFs 4 | 5 | use strict; 6 | use Getopt::Long; 7 | use DBI; 8 | use Data::Dumper; 9 | use Time::HiRes qw(gettimeofday tv_interval); 10 | 11 | our $opt_debug; 12 | our $opt_verbose; 13 | our $opt_host; 14 | our $opt_schema; 15 | our $opt_user; 16 | our $opt_password; 17 | our $opt_schema; 18 | our $opt_iterations; 19 | our $opt_help; 20 | 21 | GetOptions ( 22 | 'd|debug' => \$opt_debug, 23 | 'h|host=s' => \$opt_host, 24 | 'i|iterations=s'=> \$opt_iterations, 25 | 'h|help' => \$opt_help, 26 | 'p|password=s' => \$opt_password, 27 | 's|schema=s' => \$opt_schema, 28 | 'u|user=s' => \$opt_user, 29 | 'v|verbose' => \$opt_verbose, 30 | ) or usage(); 31 | 32 | usage() if $opt_help; 33 | 34 | $opt_schema ||= 'test'; 35 | $opt_user ||= 'root'; 36 | $opt_host ||= 'localhost'; 37 | $opt_iterations ||= 1000; 38 | 39 | my $dbh= DBI->connect("DBI:mysql:$opt_schema;mysql_socket=/tmp/mysql1.sock", $opt_user, $opt_password); 40 | 41 | my $sth_set= $dbh->prepare("select memc_set(?, ?)"); 42 | my $sth_get= $dbh->prepare("select memc_get(?)"); 43 | my $sth_del= $dbh->prepare("select memc_delete(?)"); 44 | for (0 .. 1000) { 45 | my $key= 'key' . $_; 46 | my $value= 'value' . $_ x 10 ; 47 | my $t1= [gettimeofday()]; 48 | print "Calling memc_set($key, $value);\n" if $opt_verbose; 49 | $sth_set->execute($key, $value); 50 | my $t2= [gettimeofday()]; 51 | my $elapsed= tv_interval($t1, $t2); 52 | print "memc_set in $elapsed seconds.\n" if $opt_verbose; 53 | $t1= [gettimeofday()]; 54 | print "Calling memc_get($key);\n" if $opt_verbose; 55 | $sth_get->execute($key); 56 | $t2= [gettimeofday()]; 57 | $elapsed= tv_interval($t1, $t2); 58 | print "memc_get in $elapsed seconds.\n" if $opt_verbose; 59 | my $ret= $sth_get->fetch(); 60 | print "returned: $ret->[0]\n" if $opt_verbose; 61 | print "Calling memc_delete($key, $value);\n" if $opt_verbose; 62 | $t1= [gettimeofday()]; 63 | $sth_del->execute($key); 64 | $t2= [gettimeofday()]; 65 | $elapsed= tv_interval($t1, $t2); 66 | print "deleted in $elapsed seconds\n" if $opt_verbose; 67 | } 68 | 69 | 70 | sub usage { 71 | my ($msg)= @_; 72 | print "ERROR: $msg\n\n"; 73 | print < 3 | #define VERSION_STRING "1.1" 4 | #define VERSION_STRING_LENGTH 3 5 | #define MEMC_UDF_MAX_SIZE 256*256 6 | #define ERRMSG_SIZE 1000 7 | 8 | int memc_get_servers(memcached_st *memc); 9 | 10 | typedef struct memc_function_st memc_function_st; 11 | struct memc_function_st { 12 | unsigned int offset; 13 | time_t expiration; 14 | memcached_st memc; 15 | memcached_result_st results; 16 | memcached_string_st *stats_string; 17 | 18 | }; 19 | memc_function_st *prepare_args(UDF_ARGS *args, 20 | char *message, int func_name, 21 | uint min_args, uint max_args); 22 | 23 | #define ERR_MSG "At least %d arguments must be specified: %s "; 24 | 25 | typedef enum { 26 | MEMC_GET, 27 | MEMC_GET_BY_KEY, 28 | MEMC_SET, 29 | MEMC_SET_BY_KEY, 30 | MEMC_ADD, 31 | MEMC_ADD_BY_KEY, 32 | MEMC_REPLACE, 33 | MEMC_REPLACE_BY_KEY, 34 | MEMC_DELETE, 35 | MEMC_DELETE_BY_KEY, 36 | MEMC_APPEND, 37 | MEMC_APPEND_BY_KEY, 38 | MEMC_CAS, 39 | MEMC_CAS_BY_KEY, 40 | MEMC_PREPEND, 41 | MEMC_PREPEND_BY_KEY, 42 | MEMC_STATS, 43 | MEMC_STATS_GET_KEYS, 44 | MEMC_STATS_GET_VALUE, 45 | MEMC_LIST_BEHAVIORS, 46 | MEMC_SERVERS_SET, 47 | MEMC_SERVERS_COUNT, 48 | MEMC_SERVERS_BEHAVIOR_SET, 49 | MEMC_INCREMENT, 50 | MEMC_DECREMENT, 51 | MEMC_PREFIX_SET, 52 | MEMC_PREFIX_GET, 53 | } memcached_udf_function; 54 | 55 | 56 | /* 57 | I would like some dynamic way of doing this - obtaining this from libmemcached 58 | */ 59 | #define BEHAVIORS_STRING "\nMEMCACHED SERVER BEHAVIORS\nMEMCACHED_BEHAVIOR_SUPPORT_CAS\nMEMCACHED_BEHAVIOR_NO_BLOCK\nMEMCACHED_BEHAVIOR_TCP_NODELAY\nMEMCACHED_BEHAVIOR_HASH\nMEMCACHED_BEHAVIOR_CACHE_LOOKUPS\nMEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE\nMEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE\nMEMCACHED_BEHAVIOR_BUFFER_REQUESTS\nMEMCACHED_BEHAVIOR_KETAMA\nMEMCACHED_BEHAVIOR_POLL_TIMEOUT\nMEMCACHED_BEHAVIOR_RETRY_TIMEOUT\nMEMCACHED_BEHAVIOR_DISTRIBUTION\nMEMCACHED_BEHAVIOR_BUFFER_REQUESTS\nMEMCACHED_BEHAVIOR_USER_DATA\nMEMCACHED_BEHAVIOR_SORT_HOSTS\nMEMCACHED_BEHAVIOR_VERIFY_KEY\nMEMCACHED_BEHAVIOR_CONNECT_TIMEOUT\nMEMCACHED_BEHAVIOR_KETAMA_WEIGHTED\nMEMCACHED_BEHAVIOR_KETAMA_HASH\nMEMCACHED_BEHAVIOR_BINARY_PROTOCOL\nMEMCACHED_BEHAVIOR_SND_TIMEOUT\nMEMCACHED_BEHAVIOR_RCV_TIMEOUT\nMEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT\nMEMCACHED_BEHAVIOR_IO_MSG_WATERMARK\nMEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK\n" 60 | #define BEHAVIORS_STRING_LENGTH 895 61 | 62 | #define DISTRIBUTION_TYPES_STRING "\nMEMACHED_DISTRIBUTION_MODULA\nMEMCACHED_DISTRIBUTION_CONSISTENT\nMEMCACHED_DISTRIBUTION_KETAMA" 63 | 64 | #define DISTRIBUTION_TYPES_STRING_LENGTH 96 65 | 66 | #define HASH_TYPES_STRING "\nMEMCACHED_HASH_DEFAULT\nMEMCACHED_HASH_MD5\nMEMCACHED_HASH_CRC\nMEMCACHED_HASH_FNV1_64\nMEMCACHED_HASH_FNV1A_64\nMEMCACHED_HASH_FNV1_32\nMEMCACHED_HASH_FNV1A_32\nMEMCACHED_HASH_JENKINS\nMEMCACHED_HASH_HSIEH\nMEMCACHED_HASH_MURMUR" 67 | 68 | #define HASH_TYPES_STRING_LENGTH 196 69 | 70 | -------------------------------------------------------------------------------- /docs/memc_set.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | memc_set 4 | 5 | =head1 UDF 6 | 7 | Libmemcached User Defined Function for MySQL 8 | 9 | =head1 SYNOPSIS 10 | 11 | =head1 DESCRIPTION 12 | 13 | memc_set('', '') is a UDF used to set an individual value from the memcached 14 | server from within MySQL. You must pass in a key and data value. The key 15 | you use to set the value with will be the key you use to subsequently 16 | retrieve that data with (memc_get('')) 17 | 18 | memc_add() adds an object to the server. If the object is found on the 19 | server an error occurs, otherwise the value is stored. 20 | 21 | memc_prepend() places a segment of data before the last piece of data 22 | stored. Currently expiration and key are not used in the server. 23 | 24 | memc_append() places a segment of data at the end of the last piece of 25 | data stored. Currently expiration and key are not used in the server. 26 | 27 | memc_cas() overwrites data in the server as long as the "cas" value is 28 | still the same in the server. At the point that this note was written 29 | cas is still buggy in memached. 30 | 31 | memc_set_by_key(), memc_add_by_key(), mem_replace_by_key(), memc_prepend_by_key(), 32 | memc_append_by_key_by_key(), memc_cas_by_key() methods all behave in a 33 | similar method as the non key methods. The difference is that they use 34 | their master_key parameter to map objects to particular servers. 35 | 36 | If you are looking for performance, memc_set() with non-blocking IO is 37 | the fastest way to store data on the server. 38 | 39 | =head1 RETURN 40 | 41 | NULL 42 | 43 | =head1 USAGE 44 | 45 | memc_set('keyfoo', 'somevalue hahah'); 46 | memc_set_by_key('master key', 'keyfoo', 'somevalue hahah'); 47 | memc_add('keyfoo', 'somevalue hahah'); 48 | memc_add_by_key('master key', 'keyfoo', 'somevalue hahah'); 49 | memc_replace('keyfoo', 'replaced value'); 50 | memc_replace_by_key('master key', 'keyfoo', 'replaced value'); 51 | 52 | =head1 HOME 53 | 54 | To find out more information please check: 55 | L 56 | L 57 | 58 | =head1 INSTALL 59 | 60 | CREATE FUNCTION memc_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 61 | CREATE FUNCTION memc_set_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 62 | CREATE FUNCTION memc_cas RETURNS INT SONAME "libmemcached_functions_mysql.so"; 63 | CREATE FUNCTION memc_cas_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 64 | CREATE FUNCTION memc_add RETURNS INT SONAME "libmemcached_functions_mysql.so"; 65 | CREATE FUNCTION memc_add_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 66 | CREATE FUNCTION memc_replace RETURNS INT SONAME "libmemcached_functions_mysql.so"; 67 | CREATE FUNCTION memc_replace_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 68 | 69 | =head1 AUTHOR 70 | 71 | Patrick Galbraith, Epatg@patg.netE 72 | Brian Aker, Ebrian@tangent.orgE 73 | 74 | =head1 SEE ALSO 75 | 76 | memc_set(), memc_delete()... 77 | 78 | =cut 79 | 80 | -------------------------------------------------------------------------------- /src/delete.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "common.h" 14 | 15 | my_bool memc_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 16 | long long memc_delete(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 17 | void memc_delete_deinit(UDF_INIT *initid); 18 | my_bool memc_delete_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 19 | long long memc_delete_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 20 | void memc_delete_by_key_deinit(UDF_INIT *initid); 21 | 22 | my_bool memc_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 23 | { 24 | memcached_return rc; 25 | memc_function_st *container; 26 | 27 | container= prepare_args(args, message, MEMC_DELETE, 1, 2); 28 | if (container == NULL) 29 | return 1; 30 | 31 | /* Init the memcached_st we will use for this pass */ 32 | rc= memc_get_servers(&container->memc); 33 | 34 | initid->ptr= (char *)container; 35 | 36 | return 0; 37 | } 38 | 39 | long long memc_delete(UDF_INIT *initid, 40 | UDF_ARGS *args, 41 | __attribute__ ((unused)) char *is_null, 42 | char *error) 43 | { 44 | memcached_return rc; 45 | memc_function_st *container= (memc_function_st *)initid->ptr; 46 | 47 | rc= memcached_delete(&container->memc, 48 | args->args[0], (size_t)args->lengths[0], 49 | container->expiration); 50 | 51 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 52 | } 53 | 54 | void memc_delete_deinit(UDF_INIT *initid) 55 | { 56 | /* if we allocated initid->ptr, free it here */ 57 | memc_function_st *container= (memc_function_st *)initid->ptr; 58 | 59 | memcached_free(&container->memc); 60 | free(container); 61 | } 62 | 63 | my_bool memc_delete_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 64 | { 65 | unsigned int x; 66 | memcached_return rc; 67 | memc_function_st *container; 68 | 69 | container= prepare_args(args, message, MEMC_DELETE_BY_KEY, 2, 3); 70 | if (container == NULL) 71 | return 1; 72 | 73 | /* Init the memcached_st we will use for this pass */ 74 | rc= memc_get_servers(&container->memc); 75 | 76 | initid->ptr= (char *)container; 77 | 78 | return 0; 79 | } 80 | 81 | long long memc_delete_by_key(UDF_INIT *initid, 82 | UDF_ARGS *args, 83 | __attribute__ ((unused)) char *is_null, 84 | char *error) 85 | { 86 | memcached_return rc; 87 | memc_function_st *container= (memc_function_st *)initid->ptr; 88 | 89 | rc= memcached_delete_by_key(&container->memc, 90 | args->args[0], (size_t)args->lengths[0], 91 | args->args[1], (size_t)args->lengths[1], 92 | container->expiration); 93 | 94 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 95 | } 96 | 97 | void memc_delete_by_key_deinit(UDF_INIT *initid) 98 | { 99 | /* if we allocated initid->ptr, free it here */ 100 | memc_function_st *container= (memc_function_st *)initid->ptr; 101 | 102 | memcached_free(&container->memc); 103 | free(container); 104 | } 105 | -------------------------------------------------------------------------------- /config/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Taken from lighthttpd server (BSD). Thanks Jan! 3 | # Run this to generate all the initial makefiles, etc. 4 | 5 | die() { echo "$@"; exit 1; } 6 | 7 | # LIBTOOLIZE=${LIBTOOLIZE:-libtoolize} 8 | LIBTOOLIZE_FLAGS=" --automake --copy --force" 9 | # ACLOCAL=${ACLOCAL:-aclocal} 10 | # AUTOHEADER=${AUTOHEADER:-autoheader} 11 | # AUTOMAKE=${AUTOMAKE:-automake} 12 | AUTOMAKE_FLAGS="--add-missing --copy --force" 13 | # AUTOCONF=${AUTOCONF:-autoconf} 14 | 15 | ARGV0=$0 16 | ARGS="$@" 17 | 18 | 19 | run() { 20 | echo "$ARGV0: running \`$@' $ARGS" 21 | $@ $ARGS 22 | } 23 | 24 | ## jump out if one of the programs returns 'false' 25 | set -e 26 | 27 | ## We do not currently support glibtoolize 28 | if test x$LIBTOOLIZE = x; then 29 | # if test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then 30 | # LIBTOOLIZE=glibtoolize 31 | if test \! "x`which libtoolize-1.5 2> /dev/null | grep -v '^no'`" = x; then 32 | LIBTOOLIZE=libtoolize-1.5 33 | elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then 34 | LIBTOOLIZE=libtoolize 35 | else 36 | echo "libtoolize 1.5.x wasn't found, exiting"; exit 0 37 | fi 38 | fi 39 | 40 | ## suse has aclocal and aclocal-1.9 41 | # detect aclocal 42 | 43 | if test x$ACLOCAL = x; then 44 | for ver in aclocal-1.10 aclocal-1.9 aclocal19 aclocal 45 | do 46 | if test \! "x`which $ver 2> /dev/null | grep -v '^no'`" = x; then 47 | ACLOCAL=$ver 48 | break 49 | fi 50 | done 51 | fi 52 | 53 | if test x$ACLOCAL = x; then 54 | die "Could not locate aclocal, exiting"; 55 | fi 56 | 57 | if test x$AUTOMAKE = x; then 58 | for ver in automake-1.10 automake-1.9 automake19 automake 59 | do 60 | if test \! "x`which $ver 2> /dev/null | grep -v '^no'`" = x; then 61 | AUTOMAKE=$ver 62 | break 63 | fi 64 | done 65 | fi 66 | 67 | if test x$AUTOMAKE = x; then 68 | die "Could not locate automake, exiting"; 69 | fi 70 | 71 | ## macosx has autoconf-2.59 and autoconf-2.60 72 | if test x$AUTOCONF = x; then 73 | if test \! "x`which autoconf-2.59 2> /dev/null | grep -v '^no'`" = x; then 74 | AUTOCONF=autoconf-2.59 75 | elif test \! "x`which autoconf259 2> /dev/null | grep -v '^no'`" = x; then 76 | AUTOCONF=autoconf259 77 | elif test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then 78 | AUTOCONF=autoconf 79 | else 80 | echo "autoconf 2.59+ wasn't found, exiting"; exit 0 81 | fi 82 | fi 83 | 84 | if test x$AUTOHEADER = x; then 85 | if test \! "x`which autoheader-2.59 2> /dev/null | grep -v '^no'`" = x; then 86 | AUTOHEADER=autoheader-2.59 87 | elif test \! "x`which autoheader259 2> /dev/null | grep -v '^no'`" = x; then 88 | AUTOHEADER=autoheader259 89 | elif test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then 90 | AUTOHEADER=autoheader 91 | else 92 | echo "autoconf 2.59+ (autoheader) wasn't found, exiting"; exit 0 93 | fi 94 | fi 95 | 96 | 97 | run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal" 98 | run $AUTOHEADER || die "Can't execute autoheader" 99 | 100 | # --force means overwrite ltmain.sh script if it already exists 101 | run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize" 102 | 103 | # --add-missing instructs automake to install missing auxiliary files 104 | # and --force to overwrite them if they already exist 105 | run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake" 106 | run $AUTOCONF || die "Can't execute autoconf" 107 | -------------------------------------------------------------------------------- /src/replace.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_replace(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_replace_deinit(UDF_INIT *initid); 17 | my_bool memc_replace_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 18 | long long memc_replace_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 19 | void memc_replace_by_key_deinit(UDF_INIT *initid); 20 | 21 | my_bool memc_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 22 | { 23 | unsigned int x; 24 | memcached_return rc; 25 | memc_function_st *container; 26 | 27 | container= prepare_args(args, message, MEMC_REPLACE, 2, 3); 28 | if (container == NULL) 29 | return 1; 30 | 31 | /* Init the memcached_st we will use for this pass */ 32 | rc= memc_get_servers(&container->memc); 33 | 34 | initid->ptr= (char *)container; 35 | 36 | return 0; 37 | } 38 | 39 | long long memc_replace(UDF_INIT *initid, UDF_ARGS *args, 40 | __attribute__ ((unused)) char *is_null, 41 | char *error) 42 | { 43 | memcached_return rc; 44 | memc_function_st *container= (memc_function_st *)initid->ptr; 45 | 46 | if (args->args[1] == NULL) 47 | args->lengths[1]= 0; 48 | 49 | rc= memcached_replace(&container->memc, 50 | args->args[0], (size_t)args->lengths[0], 51 | args->args[1], (size_t)args->lengths[1], 52 | container->expiration, (uint16_t)0); 53 | 54 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 55 | 56 | } 57 | 58 | void memc_replace_deinit(UDF_INIT *initid) 59 | { 60 | /* if we allocated initid->ptr, free it here */ 61 | memc_function_st *container= (memc_function_st *)initid->ptr; 62 | 63 | memcached_free(&container->memc); 64 | free(container); 65 | } 66 | 67 | my_bool memc_replace_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 68 | { 69 | unsigned int x; 70 | memcached_return rc; 71 | memc_function_st *container; 72 | 73 | container= prepare_args(args, message, MEMC_REPLACE_BY_KEY, 3, 4); 74 | if (container == NULL) 75 | return 1; 76 | 77 | /* Init the memcached_st we will use for this pass */ 78 | rc= memc_get_servers(&container->memc); 79 | 80 | initid->ptr= (char *)container; 81 | 82 | return 0; 83 | } 84 | 85 | long long memc_replace_by_key(UDF_INIT *initid, UDF_ARGS *args, 86 | __attribute__ ((unused)) char *is_null, 87 | char *error) 88 | { 89 | memcached_return rc; 90 | memc_function_st *container= (memc_function_st *)initid->ptr; 91 | 92 | if (args->args[2] == NULL) 93 | args->lengths[2]= 0; 94 | 95 | rc= memcached_replace_by_key(&container->memc, 96 | args->args[0], (size_t)args->lengths[0], 97 | args->args[1], (size_t)args->lengths[1], 98 | args->args[2], (size_t)args->lengths[2], 99 | container->expiration, (uint16_t)0); 100 | 101 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 102 | 103 | } 104 | 105 | void memc_replace_by_key_deinit(UDF_INIT *initid) 106 | { 107 | /* if we allocated initid->ptr, free it here */ 108 | memc_function_st *container= (memc_function_st *)initid->ptr; 109 | 110 | memcached_free(&container->memc); 111 | free(container); 112 | } 113 | -------------------------------------------------------------------------------- /src/prepend.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_prepend_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_prepend(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_prepend_deinit(UDF_INIT *initid); 17 | my_bool memc_prepend_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 18 | long long memc_prepend_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 19 | void memc_prepend_by_key_deinit(UDF_INIT *initid); 20 | 21 | my_bool memc_prepend_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 22 | { 23 | memcached_return rc; 24 | memc_function_st *container; 25 | 26 | container= prepare_args(args, message, MEMC_PREPEND, 2, 3); 27 | if (container == NULL) 28 | { 29 | fprintf(stderr, "errors\n"); 30 | return 1; 31 | } 32 | 33 | /* Init the memcached_st we will use for this pass */ 34 | rc= memc_get_servers(&container->memc); 35 | 36 | initid->ptr= (char *)container; 37 | 38 | return 0; 39 | } 40 | 41 | long long memc_prepend(UDF_INIT *initid, UDF_ARGS *args, 42 | __attribute__ ((unused)) char *is_null, 43 | char *error) 44 | { 45 | memcached_return rc; 46 | memc_function_st *container= (memc_function_st *)initid->ptr; 47 | 48 | if (args->args[1] == NULL) 49 | args->lengths[1]= 0; 50 | 51 | rc= memcached_prepend(&container->memc, 52 | args->args[0], (size_t)args->lengths[0], 53 | args->args[1], (size_t)args->lengths[1], 54 | container->expiration, (uint16_t)0); 55 | 56 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 57 | } 58 | 59 | void memc_prepend_deinit(UDF_INIT *initid) 60 | { 61 | /* if we allocated initid->ptr, free it here */ 62 | memc_function_st *container= (memc_function_st *)initid->ptr; 63 | 64 | memcached_free(&container->memc); 65 | free(container); 66 | } 67 | 68 | my_bool memc_prepend_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 69 | { 70 | memcached_return rc; 71 | memc_function_st *container; 72 | 73 | fprintf(stderr, "prepend_by_key_init\n"); 74 | container= prepare_args(args, message, MEMC_PREPEND_BY_KEY, 3, 4); 75 | fprintf(stderr, "prepend_by_key_init\n"); 76 | if (container == NULL) 77 | return 1; 78 | 79 | /* Init the memcached_st we will use for this pass */ 80 | rc= memc_get_servers(&container->memc); 81 | 82 | initid->ptr= (char *)container; 83 | 84 | return 0; 85 | } 86 | 87 | long long memc_prepend_by_key(UDF_INIT *initid, UDF_ARGS *args, 88 | __attribute__ ((unused)) char *is_null, 89 | char *error) 90 | { 91 | memcached_return rc; 92 | memc_function_st *container= (memc_function_st *)initid->ptr; 93 | 94 | if (args->args[2] == NULL) 95 | args->lengths[2]= 0; 96 | 97 | rc= memcached_prepend_by_key(&container->memc, 98 | args->args[0], (size_t)args->lengths[0], 99 | args->args[1], (size_t)args->lengths[1], 100 | args->args[2], (size_t)args->lengths[2], 101 | container->expiration, (uint16_t)0); 102 | 103 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 104 | } 105 | 106 | void memc_prepend_by_key_deinit(UDF_INIT *initid) 107 | { 108 | /* if we allocated initid->ptr, free it here */ 109 | memc_function_st *container= (memc_function_st *)initid->ptr; 110 | 111 | memcached_free(&container->memc); 112 | free(container); 113 | } 114 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = include 2 | 3 | EXTRA_DIST = memc_get.pod\ 4 | memc_set.pod\ 5 | memc_append.pod\ 6 | memc_prepend.pod\ 7 | memc_increment.pod\ 8 | memc_decrement.pod\ 9 | memc_servers_set.pod\ 10 | memc_list_behaviors.pod\ 11 | memc_list_hash_types.pod\ 12 | memc_list_distribution_types.pod\ 13 | memc_servers_behavior_set.pod\ 14 | memc_servers_behavior_get.pod\ 15 | memc_behavior_set.pod\ 16 | memc_behavior_get.pod\ 17 | memc_udf_version.pod\ 18 | memc_libmemcached_version.pod\ 19 | memc_stats.pod 20 | 21 | man_MANS = memc_get.3\ 22 | memc_set.3\ 23 | memc_append.3\ 24 | memc_prepend.3\ 25 | memc_increment.3\ 26 | memc_decrement.3\ 27 | memc_servers_set.3\ 28 | memc_list_behaviors.3\ 29 | memc_list_hash_types.3\ 30 | memc_list_distribution_types.3\ 31 | memc_servers_behavior_set.3\ 32 | memc_servers_behavior_get.3\ 33 | memc_behavior_set.3\ 34 | memc_behavior_get.3\ 35 | memc_udf_version.3\ 36 | memc_libmemcached_version.3\ 37 | memc_stat_get_keys.3\ 38 | memc_stats.3 39 | 40 | memc_get.3: memc_get.pod 41 | pod2man -r "" -s 3 memc_get.pod > memc_get.3 42 | memc_get_by_key.3: memc_get.pod 43 | pod2man -r "" -s 3 memc_get.pod > memc_get_by_key.3 44 | memc_add.3: memc_set.pod 45 | pod2man -r "" -s 3 memc_set.pod > memc_add.3 46 | memc_replace.3: memc_set.pod 47 | pod2man -r "" -s 3 memc_set.pod > memc_replace.3 48 | memc_cas.3: memc_set.pod 49 | pod2man -r "" -s 3 memc_set.pod > memc_cas.3 50 | memc_cas_by_key.3: memc_set.pod 51 | pod2man -r "" -s 3 memc_set.pod > memc_cas_by_key.3 52 | memc_set.3: memc_set.pod 53 | pod2man -r "" -s 3 memc_set.pod > memc_set.3 54 | memc_set_by_key.3: memc_set.pod 55 | pod2man -r "" -s 3 memc_set.pod > memc_set_by_key.3 56 | memc_append.3: memc_append.pod 57 | pod2man -r "" -s 3 memc_append.pod > memc_append.3 58 | memc_append_by_key.3: memc_append.pod 59 | pod2man -r "" -s 3 memc_append.pod > memc_append_by_key.3 60 | memc_prepend.3: memc_prepend.pod 61 | pod2man -r "" -s 3 memc_prepend.pod > memc_prepend.3 62 | memc_prepend_by_key.3: memc_prepend.pod 63 | pod2man -r "" -s 3 memc_prepend.pod > memc_prepend_by_key.3 64 | memc_increment.3: memc_increment.pod 65 | pod2man -r "" -s 3 memc_increment.pod > memc_increment.3 66 | memc_decrement.3: memc_decrement.pod 67 | pod2man -r "" -s 3 memc_decrement.pod > memc_decrement.3 68 | memc_servers_set.3: memc_servers_set.pod 69 | pod2man -r "" -s 3 memc_servers_set.pod > memc_servers_set.3 70 | memc_list_behaviors.3: memc_list_behaviors.pod 71 | pod2man -r "" -s 3 memc_list_behaviors.pod > memc_list_behaviors.3 72 | memc_list_hash_types.3: memc_list_hash_types.pod 73 | pod2man -r "" -s 3 memc_list_hash_types.pod > memc_list_hash_types.3 74 | memc_list_distribution_types.3: memc_list_distribution_types.pod 75 | pod2man -r "" -s 3 memc_list_distribution_types.pod > memc_list_distribution_types.3 76 | memc_servers_behavior_set.3: memc_servers_behavior_set.pod 77 | pod2man -r "" -s 3 memc_servers_behavior_set.pod > memc_servers_behavior_set.3 78 | memc_servers_behavior_get.3: memc_servers_behavior_get.pod 79 | pod2man -r "" -s 3 memc_servers_behavior_get.pod > memc_servers_behavior_get.3 80 | memc_behavior_set.3: memc_behavior_set.pod 81 | pod2man -r "" -s 3 memc_behavior_set.pod > memc_behavior_set.3 82 | memc_behavior_get.3: memc_behavior_get.pod 83 | pod2man -r "" -s 3 memc_behavior_get.pod > memc_behavior_get.3 84 | memc_stats.3: memc_stats.pod 85 | pod2man -r "" -s 3 memc_stats.pod > memc_stats.3 86 | memc_stat_get_keys.3: memc_stats.pod 87 | pod2man -r "" -s 3 memc_stats.pod > memc_stat_get_keys.3 88 | memc_stat_get_value.3: memc_stats.pod 89 | pod2man -r "" -s 3 memc_stats.pod > memc_stat_get_value.3 90 | memc_udf_version.3: memc_stats.pod 91 | pod2man -r "" -s 3 memc_stats.pod > memc_udf_version.3 92 | memc_libmemcached_version.3: memc_stats.pod 93 | pod2man -r "" -s 3 memc_stats.pod > memc_libmemcached_version.3 94 | 95 | 96 | clean: 97 | rm -f *.3 98 | -------------------------------------------------------------------------------- /utils/install.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Simple script (for now) to run against the Memcached UDFs 4 | 5 | use strict; 6 | use Getopt::Long; 7 | use DBI; 8 | use Data::Dumper; 9 | use Carp qw(croak); 10 | 11 | our $opt_debug; 12 | our $opt_verbose; 13 | our $opt_host; 14 | our $opt_schema; 15 | our $opt_user; 16 | our $opt_password; 17 | our $opt_silent; 18 | our $opt_help; 19 | 20 | GetOptions ( 21 | 'd|debug' => \$opt_debug, 22 | 'h|host=s' => \$opt_host, 23 | 'h|help' => \$opt_help, 24 | 'p|password=s' => \$opt_password, 25 | 's|silent' => \$opt_silent, 26 | 'u|user=s' => \$opt_user, 27 | 'v|verbose' => \$opt_verbose, 28 | ) or usage(); 29 | 30 | usage() if $opt_help; 31 | 32 | my $funclist = { 33 | memc_servers_set => 'INT', 34 | memc_set => 'INT', 35 | memc_set_by_key => 'INT', 36 | memc_add => 'INT', 37 | memc_add_by_key => 'INT', 38 | memc_cas => 'INT', 39 | memc_cas_by_key => 'INT', 40 | memc_get => 'STRING', 41 | memc_get_by_key => 'STRING', 42 | memc_delete => 'INT', 43 | memc_delete_by_key => 'INT', 44 | memc_append => 'INT', 45 | memc_append_by_key => 'INT', 46 | memc_prepend => 'INT', 47 | memc_prepend_by_key => 'INT', 48 | memc_increment => 'INT', 49 | memc_decrement => 'INT', 50 | memc_replace => 'INT', 51 | memc_replace_by_key => 'INT', 52 | memc_servers_behavior_set => 'INT', 53 | memc_behavior_get => 'STRING', 54 | memc_servers_behavior_get => 'STRING', 55 | memc_behavior_set => 'INT', 56 | memc_list_behaviors => 'STRING', 57 | memc_list_hash_types => 'STRING', 58 | memc_list_distribution_types => 'STRING', 59 | memc_libmemcached_version => 'STRING', 60 | memc_udf_version => 'STRING', 61 | memc_server_count => 'INT', 62 | memc_stats => 'STRING', 63 | memc_stat_get_value => 'STRING', 64 | memc_stat_get_keys => 'STRING', 65 | }; 66 | 67 | my $types = { 68 | 0 => 'STRING', 69 | 2 => 'INT', 70 | }; 71 | 72 | 73 | $opt_schema ||= 'test'; 74 | $opt_user ||= 'root'; 75 | $opt_host ||= 'localhost'; 76 | my $existing_functions; 77 | 78 | my $dbh= DBI->connect("DBI:mysql:$opt_schema", $opt_user, $opt_password) 79 | or croak "Unable to connect! $DBI::errstr\n"; 80 | 81 | my $sth= $dbh->prepare('select name,ret from mysql.func') 82 | or croak "Unable to fetch functions! $DBI::errstr\n"; 83 | $sth->execute(); 84 | 85 | my $ref= $sth->fetchall_arrayref(); 86 | $sth->finish(); 87 | map {$existing_functions->{$_->[0]} = $types->{$_->[1]}} @$ref; 88 | 89 | for my $func(keys %$funclist) { 90 | my $ans= ''; 91 | unless ($existing_functions->{$func}) { 92 | print "function $func doesn't exist."; 93 | unless ($opt_silent) { 94 | print " Create? [Y|n]\n"; 95 | $ans= ; 96 | chomp($ans); 97 | } 98 | else { 99 | $ans= 'Y'; 100 | } 101 | if ($ans eq 'Y' or $ans eq 'y') { 102 | my $create= 'CREATE FUNCTION ' . $func . 103 | ' RETURNS ' . $funclist->{$func} . 104 | " SONAME 'libmemcached_functions_mysql.so'"; 105 | print "Running: $create\n" unless $opt_silent; 106 | $sth= $dbh->prepare($create); 107 | $sth->execute() or croak "Error: $DBI::errstr\n"; 108 | } 109 | 110 | } 111 | else { 112 | print "function $func does exist\n"; 113 | } 114 | } 115 | 116 | sub usage { 117 | my ($msg)= @_; 118 | print "ERROR: $msg\n\n"; 119 | print < 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_add_deinit(UDF_INIT *initid); 17 | my_bool memc_add_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 18 | long long memc_add_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 19 | void memc_add_by_key_deinit(UDF_INIT *initid); 20 | 21 | my_bool memc_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 22 | { 23 | unsigned int x; 24 | memcached_return rc; 25 | memc_function_st *container; 26 | 27 | container= prepare_args(args, message, MEMC_ADD, 2, 3); 28 | if (container == NULL) 29 | return 1; 30 | 31 | /* Init the memcached_st we will use for this pass */ 32 | rc= memc_get_servers(&container->memc); 33 | 34 | initid->ptr= (char *)container; 35 | 36 | return 0; 37 | } 38 | 39 | long long memc_add(UDF_INIT *initid, UDF_ARGS *args, 40 | __attribute__ ((unused)) char *is_null, 41 | char *error) 42 | { 43 | memcached_return rc; 44 | 45 | memc_function_st *container= (memc_function_st *)initid->ptr; 46 | /* 47 | This seems like a bug I'm trying to work around, but without 48 | this, setting a NULL using a user-defined variable causes segfault 49 | 50 | set @foo=concat('a',':', NULL); 51 | 52 | mysql> select memc_set('a',@foo); 53 | ERROR 2013 (HY000): Lost connection to MySQL server during query 54 | 55 | */ 56 | if (args->args[1] == NULL) 57 | args->lengths[1]= 0; 58 | 59 | rc= memcached_add(&container->memc, 60 | args->args[0], (size_t)args->lengths[0], 61 | args->args[1], (size_t)args->lengths[1], 62 | container->expiration, (uint16_t)0); 63 | 64 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 65 | 66 | } 67 | 68 | void memc_add_deinit(UDF_INIT *initid) 69 | { 70 | /* if we allocated initid->ptr, free it here */ 71 | memc_function_st *container= (memc_function_st *)initid->ptr; 72 | 73 | memcached_free(&container->memc); 74 | free(container); 75 | } 76 | my_bool memc_add_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 77 | { 78 | unsigned int x; 79 | memcached_return rc; 80 | memc_function_st *container; 81 | 82 | container= prepare_args(args, message, MEMC_ADD_BY_KEY, 3, 4); 83 | if (container == NULL) 84 | return 1; 85 | 86 | /* Init the memcached_st we will use for this pass */ 87 | rc= memc_get_servers(&container->memc); 88 | 89 | initid->ptr= (char *)container; 90 | 91 | return 0; 92 | } 93 | 94 | long long memc_add_by_key(UDF_INIT *initid, UDF_ARGS *args, 95 | __attribute__ ((unused)) char *is_null, 96 | char *error) 97 | { 98 | memcached_return rc; 99 | memc_function_st *container= (memc_function_st *)initid->ptr; 100 | 101 | /* 102 | This seems like a bug I'm trying to work around, but without 103 | this, setting a NULL using a user-defined variable causes segfault 104 | 105 | set @foo=concat('a',':', NULL); 106 | 107 | mysql> select memc_set('a',@foo); 108 | ERROR 2013 (HY000): Lost connection to MySQL server during query 109 | 110 | */ 111 | if (args->args[2] == NULL) 112 | args->lengths[2]= 0; 113 | 114 | rc= memcached_add_by_key(&container->memc, 115 | args->args[0], (size_t)args->lengths[0], 116 | args->args[1], (size_t)args->lengths[1], 117 | args->args[2], (size_t)args->lengths[2], 118 | container->expiration, (uint16_t)0); 119 | 120 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 121 | } 122 | 123 | void memc_add_by_key_deinit(UDF_INIT *initid) 124 | { 125 | /* if we allocated initid->ptr, free it here */ 126 | memc_function_st *container= (memc_function_st *)initid->ptr; 127 | 128 | memcached_free(&container->memc); 129 | free(container); 130 | } 131 | -------------------------------------------------------------------------------- /src/append.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_append_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_append(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_append_deinit(UDF_INIT *initid); 17 | my_bool memc_append_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 18 | long long memc_append_by_key_(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 19 | void memc_append_by_key_deinit(UDF_INIT *initid); 20 | 21 | my_bool memc_append_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 22 | { 23 | memcached_return rc; 24 | memc_function_st *container; 25 | 26 | /* this is how to fail */ 27 | container= prepare_args(args, message, MEMC_APPEND, 2, 3); 28 | if (container == NULL) 29 | return 1; 30 | 31 | /* Init the memcached_st we will use for this pass */ 32 | rc= memc_get_servers(&container->memc); 33 | 34 | initid->ptr= (char *)container; 35 | 36 | return 0; 37 | } 38 | 39 | long long memc_append(UDF_INIT *initid, 40 | UDF_ARGS *args, 41 | __attribute__ ((unused)) char *is_null, 42 | __attribute__ ((unused)) char *error) 43 | { 44 | memcached_return rc; 45 | memc_function_st *container= (memc_function_st *)initid->ptr; 46 | /* 47 | This seems like a bug I'm trying to work around, but without 48 | this, setting a NULL using a user-defined variable causes segfault 49 | 50 | set @foo=concat('a',':', NULL); 51 | 52 | mysql> select memc_set('a',@foo); 53 | ERROR 2013 (HY000): Lost connection to MySQL server during query 54 | 55 | */ 56 | if (args->args[1] == NULL) 57 | args->lengths[1]= 0; 58 | 59 | rc= memcached_append(&container->memc, 60 | args->args[0], (size_t)args->lengths[0], 61 | args->args[1], (size_t)args->lengths[1], 62 | container->expiration, (uint16_t)0); 63 | 64 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 65 | } 66 | 67 | void memc_append_deinit(UDF_INIT *initid) 68 | { 69 | /* if we allocated initid->ptr, free it here */ 70 | memc_function_st *container= (memc_function_st *)initid->ptr; 71 | 72 | memcached_free(&container->memc); 73 | free(container); 74 | } 75 | 76 | my_bool memc_append_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 77 | { 78 | memcached_return rc; 79 | memc_function_st *container; 80 | 81 | container= prepare_args(args, message, MEMC_APPEND_BY_KEY, 3, 4); 82 | if (container == NULL) 83 | return 1; 84 | 85 | /* Init the memcached_st we will use for this pass */ 86 | rc= memc_get_servers(&container->memc); 87 | 88 | initid->ptr= (char *)container; 89 | 90 | return 0; 91 | } 92 | 93 | long long memc_append_by_key(UDF_INIT *initid, 94 | UDF_ARGS *args, 95 | __attribute__ ((unused)) char *is_null, 96 | __attribute__ ((unused)) char *error) 97 | { 98 | memcached_return rc; 99 | memc_function_st *container= (memc_function_st *)initid->ptr; 100 | 101 | /* 102 | This seems like a bug I'm trying to work around, but without 103 | this, setting a NULL using a user-defined variable causes segfault 104 | 105 | set @foo=concat('a',':', NULL); 106 | 107 | mysql> select memc_set('a',@foo); 108 | ERROR 2013 (HY000): Lost connection to MySQL server during query 109 | 110 | */ 111 | if (args->args[2] == NULL) 112 | args->lengths[2]= 0; 113 | 114 | rc= memcached_append_by_key(&container->memc, 115 | args->args[0], (size_t)args->lengths[0], 116 | args->args[1], (size_t)args->lengths[1], 117 | args->args[2], (size_t)args->lengths[2], 118 | container->expiration, (uint16_t)0); 119 | 120 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 121 | } 122 | 123 | void memc_append_by_key_deinit(UDF_INIT *initid) 124 | { 125 | /* if we allocated initid->ptr, free it here */ 126 | memc_function_st *container= (memc_function_st *)initid->ptr; 127 | 128 | memcached_free(&container->memc); 129 | free(container); 130 | } 131 | -------------------------------------------------------------------------------- /sql/install_functions.sql: -------------------------------------------------------------------------------- 1 | DROP FUNCTION IF EXISTS memc_add ; 2 | DROP FUNCTION IF EXISTS memc_add_by_key ; 3 | DROP FUNCTION IF EXISTS memc_servers_set ; 4 | DROP FUNCTION IF EXISTS memc_server_count ; 5 | DROP FUNCTION IF EXISTS memc_set ; 6 | DROP FUNCTION IF EXISTS memc_set_by_key ; 7 | DROP FUNCTION IF EXISTS memc_cas ; 8 | DROP FUNCTION IF EXISTS memc_cas_by_key ; 9 | DROP FUNCTION IF EXISTS memc_get ; 10 | DROP FUNCTION IF EXISTS memc_get_by_key ; 11 | DROP FUNCTION IF EXISTS memc_get_cas ; 12 | DROP FUNCTION IF EXISTS memc_get_cas_by_key ; 13 | DROP FUNCTION IF EXISTS memc_delete ; 14 | DROP FUNCTION IF EXISTS memc_delete_by_key ; 15 | DROP FUNCTION IF EXISTS memc_append ; 16 | DROP FUNCTION IF EXISTS memc_append_by_key ; 17 | DROP FUNCTION IF EXISTS memc_prepend ; 18 | DROP FUNCTION IF EXISTS memc_prepend_by_key ; 19 | DROP FUNCTION IF EXISTS memc_increment ; 20 | DROP FUNCTION IF EXISTS memc_decrement ; 21 | DROP FUNCTION IF EXISTS memc_replace ; 22 | DROP FUNCTION IF EXISTS memc_replace_by_key ; 23 | 24 | DROP FUNCTION IF EXISTS memc_servers_behavior_set ; 25 | DROP FUNCTION IF EXISTS memc_servers_behavior_get ; 26 | DROP FUNCTION IF EXISTS memc_behavior_set ; 27 | DROP FUNCTION IF EXISTS memc_behavior_get ; 28 | DROP FUNCTION IF EXISTS memc_list_behaviors ; 29 | DROP FUNCTION IF EXISTS memc_list_hash_types ; 30 | DROP FUNCTION IF EXISTS memc_list_distribution_types ; 31 | 32 | DROP FUNCTION IF EXISTS memc_udf_version ; 33 | DROP FUNCTION IF EXISTS memc_libmemcached_version ; 34 | DROP FUNCTION IF EXISTS memc_stats ; 35 | DROP FUNCTION IF EXISTS memc_stat_get_keys ; 36 | DROP FUNCTION IF EXISTS memc_stat_get_value ; 37 | 38 | CREATE FUNCTION memc_add RETURNS INT SONAME "libmemcached_functions_mysql.so"; 39 | CREATE FUNCTION memc_add_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 40 | CREATE FUNCTION memc_servers_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 41 | CREATE FUNCTION memc_server_count RETURNS INT SONAME "libmemcached_functions_mysql.so"; 42 | CREATE FUNCTION memc_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 43 | CREATE FUNCTION memc_set_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 44 | CREATE FUNCTION memc_cas RETURNS INT SONAME "libmemcached_functions_mysql.so"; 45 | CREATE FUNCTION memc_cas_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 46 | CREATE FUNCTION memc_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 47 | CREATE FUNCTION memc_get_by_key RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 48 | CREATE FUNCTION memc_get_cas RETURNS INT SONAME "libmemcached_functions_mysql.so"; 49 | CREATE FUNCTION memc_get_cas_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 50 | CREATE FUNCTION memc_delete RETURNS INT SONAME "libmemcached_functions_mysql.so"; 51 | CREATE FUNCTION memc_delete_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 52 | CREATE FUNCTION memc_append RETURNS INT SONAME "libmemcached_functions_mysql.so"; 53 | CREATE FUNCTION memc_append_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 54 | CREATE FUNCTION memc_prepend RETURNS INT SONAME "libmemcached_functions_mysql.so"; 55 | CREATE FUNCTION memc_prepend_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 56 | CREATE FUNCTION memc_increment RETURNS INT SONAME "libmemcached_functions_mysql.so"; 57 | CREATE FUNCTION memc_decrement RETURNS INT SONAME "libmemcached_functions_mysql.so"; 58 | CREATE FUNCTION memc_replace RETURNS INT SONAME "libmemcached_functions_mysql.so"; 59 | CREATE FUNCTION memc_replace_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 60 | 61 | CREATE FUNCTION memc_servers_behavior_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 62 | CREATE FUNCTION memc_servers_behavior_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 63 | CREATE FUNCTION memc_behavior_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 64 | CREATE FUNCTION memc_behavior_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 65 | CREATE FUNCTION memc_list_behaviors RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 66 | CREATE FUNCTION memc_list_hash_types RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 67 | CREATE FUNCTION memc_list_distribution_types RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 68 | 69 | CREATE FUNCTION memc_udf_version RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 70 | CREATE FUNCTION memc_libmemcached_version RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 71 | CREATE FUNCTION memc_stats RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 72 | CREATE FUNCTION memc_stat_get_keys RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 73 | CREATE FUNCTION memc_stat_get_value RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 74 | 75 | -------------------------------------------------------------------------------- /src/get.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include "common.h" 14 | 15 | my_bool memc_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 16 | char *memc_get(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error); 17 | void memc_get_deinit(UDF_INIT *initid); 18 | 19 | 20 | my_bool memc_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 21 | { 22 | unsigned int x; 23 | memcached_return rc; 24 | memc_function_st *container; 25 | 26 | 27 | /* this is how to fail */ 28 | if (args->arg_count != 1) 29 | { 30 | strncpy(message, 31 | "one argument must be supplied: memc_get('').", 32 | MYSQL_ERRMSG_SIZE); 33 | return 1; 34 | } 35 | 36 | args->arg_type[0]= STRING_RESULT; 37 | 38 | initid->max_length= MEMC_UDF_MAX_SIZE; 39 | container= calloc(1, sizeof(memc_function_st)); 40 | 41 | /* Init the memcached_st we will use for this pass */ 42 | rc= memc_get_servers(&container->memc); 43 | memcached_result_create(&container->memc, &container->results); 44 | 45 | initid->ptr= (char *)container; 46 | 47 | return 0; 48 | } 49 | 50 | /* 51 | memc_get 52 | get cached object, takes hash-key arg 53 | */ 54 | char *memc_get(UDF_INIT *initid, UDF_ARGS *args, 55 | __attribute__ ((unused)) char *result, 56 | unsigned long *length, 57 | char *is_null, 58 | __attribute__ ((unused)) char *error) 59 | { 60 | /* how do I utilise this? Print out in case of error? */ 61 | memcached_return rc; 62 | /* We'll just hard-code now? */ 63 | 64 | memc_function_st *container= (memc_function_st *)initid->ptr; 65 | 66 | rc= memcached_mget(&container->memc, args->args, (size_t *)args->lengths, 1); 67 | 68 | memcached_fetch_result(&container->memc, &container->results, &rc); 69 | 70 | *length= memcached_result_length(&container->results); 71 | 72 | if (! *length) 73 | { 74 | *is_null= 1; 75 | } 76 | 77 | return memcached_result_value(&container->results); 78 | } 79 | 80 | /* de-init UDF */ 81 | void memc_get_deinit(UDF_INIT *initid) 82 | { 83 | /* if we allocated initid->ptr, free it here */ 84 | memc_function_st *container= (memc_function_st *)initid->ptr; 85 | 86 | memcached_result_free(&container->results); 87 | memcached_free(&container->memc); 88 | free(container); 89 | 90 | return; 91 | } 92 | 93 | my_bool memc_get_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 94 | { 95 | memcached_return rc; 96 | memc_function_st *container; 97 | 98 | /* this is how to fail */ 99 | if (args->arg_count != 2) 100 | { 101 | strncpy(message, 102 | "2 arguments must be supplied: memc_get_by_key('', '')", 103 | MYSQL_ERRMSG_SIZE); 104 | return 1; 105 | } 106 | 107 | args->arg_type[0]= args->arg_type[1]= STRING_RESULT; 108 | 109 | initid->max_length= MEMC_UDF_MAX_SIZE; 110 | container= calloc(1,sizeof(memc_function_st)); 111 | 112 | /* Init the memcached_st we will use for this pass */ 113 | rc= memc_get_servers(&container->memc); 114 | memcached_result_create(&container->memc, &container->results); 115 | 116 | initid->ptr= (char *)container; 117 | 118 | return 0; 119 | } 120 | 121 | /* 122 | memc_ge 123 | get cached object, takes hash-key arg 124 | */ 125 | char *memc_get_by_key(UDF_INIT *initid, UDF_ARGS *args, 126 | __attribute__ ((unused)) char *result, 127 | unsigned long *length, 128 | char *is_null, 129 | __attribute__ ((unused)) char *error) 130 | { 131 | /* how do I utilise this? Print out in case of error? */ 132 | memcached_return rc; 133 | char *value; 134 | char **keys; 135 | size_t *lengths; 136 | keys= args->args; 137 | keys++; 138 | lengths= (size_t*)args->lengths; 139 | lengths++; 140 | 141 | memc_function_st *container= (memc_function_st *)initid->ptr; 142 | 143 | rc= memcached_mget_by_key(&container->memc, 144 | args->args[0], 145 | (size_t )args->lengths[0], 146 | keys, 147 | lengths, 148 | args->arg_count - 1); 149 | 150 | memcached_fetch_result(&container->memc, &container->results, &rc); 151 | *length= memcached_result_length(&container->results); 152 | if (! *length) 153 | { 154 | *is_null= 1; 155 | } 156 | 157 | return (memcached_result_value(&container->results)); 158 | } 159 | 160 | /* de-init UDF */ 161 | void memc_get_by_key_deinit(UDF_INIT *initid) 162 | { 163 | /* if we allocated initid->ptr, free it here */ 164 | memc_function_st *container= (memc_function_st *)initid->ptr; 165 | 166 | memcached_result_free(&container->results); 167 | memcached_free(&container->memc); 168 | free(container); 169 | 170 | return; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /src/get_cas.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include "common.h" 14 | 15 | my_bool memc_get_cas_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 16 | uint64_t memc_get_cas(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 17 | void memc_get_cas_deinit(UDF_INIT *initid); 18 | 19 | my_bool memc_get_cas_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 20 | uint64_t memc_get_cas_by_key(UDF_INIT *initid, UDF_ARGS *args, 21 | __attribute__ ((unused)) char *is_null, 22 | __attribute__ ((unused)) char *error); 23 | void memc_get_cas_by_key_deinit(UDF_INIT *initid); 24 | 25 | 26 | my_bool memc_get_cas_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 27 | { 28 | unsigned int x; 29 | memcached_return rc; 30 | memc_function_st *container; 31 | 32 | 33 | /* this is how to fail */ 34 | if (args->arg_count != 1) 35 | { 36 | strncpy(message, 37 | "one argument must be supplied: memc_get_cas('').", 38 | MYSQL_ERRMSG_SIZE); 39 | return 1; 40 | } 41 | 42 | args->arg_type[0]= STRING_RESULT; 43 | 44 | initid->max_length= MEMC_UDF_MAX_SIZE; 45 | container= calloc(1, sizeof(memc_function_st)); 46 | 47 | /* Init the memcached_st we will use for this pass */ 48 | rc= memc_get_servers(&container->memc); 49 | memcached_result_create(&container->memc, &container->results); 50 | 51 | initid->ptr= (char *)container; 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | memc_get_cas 58 | get cached object, takes hash-key arg 59 | */ 60 | uint64_t memc_get_cas(UDF_INIT *initid, UDF_ARGS *args, 61 | __attribute__ ((unused)) char *is_null, 62 | __attribute__ ((unused)) char *error) 63 | { 64 | uint64_t cas; 65 | char *value; 66 | unsigned long length= 0; 67 | memcached_return rc; 68 | 69 | memc_function_st *container= (memc_function_st *)initid->ptr; 70 | 71 | rc= memcached_mget(&container->memc, args->args, (size_t *)args->lengths, 1); 72 | 73 | memcached_fetch_result(&container->memc, &container->results, &rc); 74 | 75 | length= memcached_result_length(&container->results); 76 | 77 | if (! length) 78 | { 79 | cas= 0; 80 | } 81 | value= memcached_result_value(&container->results); 82 | 83 | cas= memcached_result_cas(&container->results); 84 | return cas; 85 | } 86 | 87 | /* de-init UDF */ 88 | void memc_get_cas_deinit(UDF_INIT *initid) 89 | { 90 | /* if we allocated initid->ptr, free it here */ 91 | memc_function_st *container= (memc_function_st *)initid->ptr; 92 | 93 | memcached_result_free(&container->results); 94 | memcached_free(&container->memc); 95 | free(container); 96 | 97 | return; 98 | } 99 | 100 | my_bool memc_get_cas_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 101 | { 102 | memcached_return rc; 103 | memc_function_st *container; 104 | 105 | /* this is how to fail */ 106 | if (args->arg_count != 2) 107 | { 108 | strncpy(message, 109 | "2 arguments must be supplied: memc_get_cas_by_key('', '')", 110 | MYSQL_ERRMSG_SIZE); 111 | return 1; 112 | } 113 | 114 | args->arg_type[0]= args->arg_type[1]= STRING_RESULT; 115 | 116 | initid->max_length= MEMC_UDF_MAX_SIZE; 117 | container= calloc(1,sizeof(memc_function_st)); 118 | 119 | /* Init the memcached_st we will use for this pass */ 120 | rc= memc_get_servers(&container->memc); 121 | memcached_result_create(&container->memc, &container->results); 122 | 123 | initid->ptr= (char *)container; 124 | 125 | return 0; 126 | } 127 | 128 | /* 129 | memc_get_cas_by_key 130 | get item cas value, takes key arg 131 | */ 132 | uint64_t memc_get_cas_by_key(UDF_INIT *initid, UDF_ARGS *args, 133 | __attribute__ ((unused)) char *is_null, 134 | __attribute__ ((unused)) char *error) 135 | { 136 | /* how do I utilise this? Print out in case of error? */ 137 | memcached_return rc; 138 | unsigned long length= 0; 139 | char *value; 140 | char **keys; 141 | size_t *lengths; 142 | uint64_t cas; 143 | memcached_result_st *results; 144 | 145 | keys= args->args; 146 | keys++; 147 | lengths= (size_t*)args->lengths; 148 | lengths++; 149 | 150 | memc_function_st *container= (memc_function_st *)initid->ptr; 151 | memcached_result_create(&container->memc, &container->results); 152 | 153 | rc= memcached_mget_by_key(&container->memc, 154 | args->args[0], 155 | (size_t )args->lengths[0], 156 | keys, 157 | lengths, 158 | args->arg_count - 1); 159 | 160 | memcached_fetch_result(&container->memc, &container->results, &rc); 161 | length= memcached_result_length(&container->results); 162 | if (! length) 163 | { 164 | cas= 0; 165 | } 166 | value= memcached_result_value(&container->results); 167 | cas= memcached_result_cas(&container->results); 168 | 169 | return cas; 170 | } 171 | 172 | /* de-init UDF */ 173 | void memc_get_cas_by_key_deinit(UDF_INIT *initid) 174 | { 175 | /* if we allocated initid->ptr, free it here */ 176 | memc_function_st *container= (memc_function_st *)initid->ptr; 177 | 178 | memcached_result_free(&container->results); 179 | memcached_free(&container->memc); 180 | free(container); 181 | 182 | return; 183 | } 184 | 185 | -------------------------------------------------------------------------------- /src/args.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | char* memc_error_msg(memcached_udf_function func); 15 | 16 | memc_function_st *prepare_args(UDF_ARGS *args, 17 | char *message, int func, 18 | uint min_args, uint max_args); 19 | 20 | char* memc_error_msg(memcached_udf_function func) 21 | { 22 | switch (func) { 23 | case MEMC_GET: 24 | return "memc_get('')."; 25 | case MEMC_GET_BY_KEY: 26 | return "memc_get_by_key('', '')"; 27 | case MEMC_SET: 28 | return "memc_set(, , )."; 29 | case MEMC_SET_BY_KEY: 30 | return "memc_set_by_key(, , , )."; 31 | case MEMC_ADD: 32 | return "memc_add(, , )."; 33 | case MEMC_ADD_BY_KEY: 34 | return "memc_add_by_key(, , , )."; 35 | case MEMC_REPLACE: 36 | return "memc_replace('', '', )."; 37 | case MEMC_REPLACE_BY_KEY: 38 | return "memc_replace_by_key('', '', '', )."; 39 | case MEMC_DELETE: 40 | return "memc_delete('', )."; 41 | case MEMC_DELETE_BY_KEY: 42 | return "memc_delete_by_key('', '', )."; 43 | case MEMC_APPEND: 44 | return "memcached_append('', '', )."; 45 | case MEMC_APPEND_BY_KEY: 46 | return "memcached_append_by_key('', '', '', )."; 47 | case MEMC_CAS: 48 | return "memc_cas('', '', '', )."; 49 | case MEMC_CAS_BY_KEY: 50 | return "memc_cas_by_key('', '', '', '', )"; 51 | case MEMC_PREPEND: 52 | return "memc_prepend('', '', )."; 53 | 54 | case MEMC_PREPEND_BY_KEY: 55 | return "memcached_prepend_by_key('', '', '', )"; 56 | case MEMC_STATS: 57 | return "memc_stats()"; 58 | case MEMC_STATS_GET_KEYS: 59 | return "memc_stat_get_keys()"; 60 | case MEMC_STATS_GET_VALUE: 61 | return "memc_stat_get_value('', '')"; 62 | case MEMC_SERVERS_SET: 63 | return "memc_servers_set('')"; 64 | case MEMC_SERVERS_COUNT: 65 | return "memc_servers_count('')"; 66 | case MEMC_SERVERS_BEHAVIOR_SET: 67 | return "memc_servers_behavior_set('', '')"; 68 | case MEMC_LIST_BEHAVIORS: 69 | return "memc_list_behaviors()"; 70 | case MEMC_DECREMENT: 71 | return "memc_decrement('', '')"; 72 | case MEMC_INCREMENT: 73 | return "memc_increment('', )"; 74 | case MEMC_PREFIX_SET: 75 | return "memc_prefix_set('')"; 76 | case MEMC_PREFIX_GET: 77 | return "memc_prefix_get()"; 78 | } 79 | } 80 | 81 | 82 | memc_function_st *prepare_args(UDF_ARGS *args, 83 | char *message, int func, 84 | uint min_args, uint max_args) 85 | { 86 | int iter; 87 | memc_function_st *container; 88 | 89 | if (args->arg_count < min_args || args->arg_count > max_args) 90 | { 91 | char msg_buf[200]; 92 | sprintf(msg_buf, "Usage: %s", 93 | memc_error_msg(func), min_args); 94 | fprintf(stderr, "Usage: %s", 95 | memc_error_msg(func), min_args); 96 | 97 | strncpy(message, msg_buf, MYSQL_ERRMSG_SIZE); 98 | return (memc_function_st*)NULL; 99 | } 100 | container= calloc(1, sizeof(memc_function_st)); 101 | 102 | fprintf(stderr, "min args %d max args %d", min_args, max_args); 103 | /* no need to do anything else */ 104 | if (min_args == 0 && max_args == 0) 105 | return container; 106 | 107 | /* 108 | functions like append, prepend, increment, decrement don't 109 | have expiration arg 110 | */ 111 | 112 | 113 | for (iter= 0; iter < min_args; iter++) 114 | args->arg_type[iter]= STRING_RESULT; 115 | 116 | switch(func) { 117 | case MEMC_SET: 118 | case MEMC_SET_BY_KEY: 119 | case MEMC_ADD: 120 | case MEMC_ADD_BY_KEY: 121 | case MEMC_REPLACE: 122 | case MEMC_REPLACE_BY_KEY: 123 | case MEMC_APPEND: 124 | case MEMC_APPEND_BY_KEY: 125 | case MEMC_PREPEND: 126 | case MEMC_PREPEND_BY_KEY: 127 | case MEMC_DELETE: 128 | case MEMC_DELETE_BY_KEY: 129 | { 130 | if (args->arg_count == max_args) 131 | { 132 | if (args->arg_type[max_args - 1] == STRING_RESULT) 133 | { 134 | container->expiration= (time_t)atoi(args->args[max_args -1]); 135 | } 136 | else if (args->arg_type[max_args - 1] == INT_RESULT) 137 | { 138 | container->expiration= *((time_t*)args->args[max_args -1]); 139 | } 140 | else 141 | { 142 | container->expiration= (time_t)0; 143 | } 144 | 145 | } 146 | else 147 | { 148 | container->expiration= (time_t) 0; 149 | } 150 | fprintf(stderr, "expiration %d\n", (int) container->expiration); 151 | } 152 | break; 153 | 154 | case MEMC_INCREMENT: 155 | case MEMC_DECREMENT: 156 | { 157 | if (args->arg_count == max_args) 158 | args->arg_type[max_args - 1] = STRING_RESULT; 159 | } 160 | break; 161 | 162 | default: 163 | break; 164 | } 165 | 166 | fprintf(stderr, "prepare_args finished\n"); 167 | return container; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /src/set.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "common.h" 13 | 14 | my_bool memc_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 15 | long long memc_set(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 16 | void memc_set_deinit(UDF_INIT *initid); 17 | my_bool memc_set_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 18 | long long memc_set_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 19 | void memc_set_by_key_deinit(UDF_INIT *initid); 20 | my_bool memc_cas_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 21 | long long memc_cas(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 22 | void memc_cas_deinit(UDF_INIT *initid); 23 | my_bool memc_cas_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 24 | long long memc_cas_by_key(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 25 | void memc_cas_by_key_deinit(UDF_INIT *initid); 26 | 27 | my_bool memc_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 28 | { 29 | memcached_return rc; 30 | unsigned int count; 31 | memc_function_st *container; 32 | 33 | container= prepare_args(args, message, MEMC_SET, 2, 3); 34 | if (container == NULL) 35 | return 1; 36 | 37 | /* Init the memcached_st we will use for this pass */ 38 | rc= memc_get_servers(&container->memc); 39 | count= memcached_server_count(&container->memc); 40 | 41 | initid->ptr= (char *)container; 42 | 43 | return 0; 44 | } 45 | 46 | long long memc_set(UDF_INIT *initid, UDF_ARGS *args, 47 | char *is_null, 48 | char *error) 49 | { 50 | memcached_return rc; 51 | *is_null= false; 52 | 53 | memc_function_st *container= (memc_function_st *)initid->ptr; 54 | /* 55 | This seems like a bug I'm trying to work around, but without 56 | this, setting a NULL using a user-defined variable causes segfault 57 | 58 | set @foo=concat('a',':', NULL); 59 | 60 | mysql> select memc_set('a',@foo); 61 | ERROR 2013 (HY000): Lost connection to MySQL server during query 62 | 63 | */ 64 | if (args->args[1] == NULL) 65 | args->lengths[1]= 0; 66 | 67 | rc= memcached_set(&container->memc, 68 | args->args[0], (size_t)args->lengths[0], 69 | args->args[1], (size_t)args->lengths[1], 70 | container->expiration, (uint16_t)0); 71 | 72 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 73 | } 74 | 75 | void memc_set_deinit(UDF_INIT *initid) 76 | { 77 | /* if we allocated initid->ptr, free it here */ 78 | memc_function_st *container= (memc_function_st *)initid->ptr; 79 | 80 | memcached_free(&container->memc); 81 | free(container); 82 | } 83 | my_bool memc_set_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 84 | { 85 | memcached_return rc; 86 | memc_function_st *container; 87 | 88 | container= prepare_args(args, message, MEMC_SET_BY_KEY, 3, 4); 89 | if (container == NULL) 90 | return 1; 91 | 92 | /* Init the memcached_st we will use for this pass */ 93 | rc= memc_get_servers(&container->memc); 94 | 95 | initid->ptr= (char *)container; 96 | fprintf(stderr, "1: container->expiration %d", container->expiration); 97 | 98 | return 0; 99 | } 100 | 101 | long long memc_set_by_key(UDF_INIT *initid, UDF_ARGS *args, 102 | __attribute__ ((unused)) char *is_null, 103 | char *error) 104 | { 105 | memcached_return rc; 106 | memc_function_st *container= (memc_function_st *)initid->ptr; 107 | 108 | /* 109 | This seems like a bug I'm trying to work around, but without 110 | this, setting a NULL using a user-defined variable causes segfault 111 | 112 | set @foo=concat('a',':', NULL); 113 | 114 | mysql> select memc_set('a',@foo); 115 | ERROR 2013 (HY000): Lost connection to MySQL server during query 116 | 117 | */ 118 | if (args->args[2] == NULL) 119 | args->lengths[2]= 0; 120 | 121 | rc= memcached_set_by_key(&container->memc, 122 | args->args[0], (size_t)args->lengths[0], 123 | args->args[1], (size_t)args->lengths[1], 124 | args->args[2], (size_t)args->lengths[2], 125 | container->expiration, (uint16_t)0); 126 | 127 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 128 | 129 | } 130 | 131 | void memc_set_by_key_deinit(UDF_INIT *initid) 132 | { 133 | /* if we allocated initid->ptr, free it here */ 134 | memc_function_st *container= (memc_function_st *)initid->ptr; 135 | 136 | memcached_free(&container->memc); 137 | free(container); 138 | } 139 | 140 | my_bool memc_cas_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 141 | { 142 | memcached_return rc; 143 | memc_function_st *container; 144 | 145 | container= prepare_args(args, message, MEMC_CAS, 3, 4); 146 | if (container == NULL) 147 | return 1; 148 | 149 | /* Init the memcached_st we will use for this pass */ 150 | rc= memc_get_servers(&container->memc); 151 | 152 | initid->ptr= (char *)container; 153 | 154 | return 0; 155 | } 156 | 157 | long long memc_cas(UDF_INIT *initid, UDF_ARGS *args, 158 | __attribute__ ((unused)) char *is_null, 159 | char *error) 160 | { 161 | memcached_return rc; 162 | memc_function_st *container= (memc_function_st *)initid->ptr; 163 | 164 | if (args->args[1] == NULL) 165 | args->lengths[1]= 0; 166 | 167 | rc= memcached_cas(&container->memc, 168 | args->args[0], (size_t)args->lengths[0], 169 | args->args[1], (size_t)args->lengths[1], 170 | container->expiration, (uint16_t)0, 171 | (uint64_t) strtol(args->args[2], (char **)NULL, 10)); 172 | 173 | 174 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 175 | } 176 | 177 | void memc_cas_deinit(UDF_INIT *initid) 178 | { 179 | /* if we allocated initid->ptr, free it here */ 180 | memc_function_st *container= (memc_function_st *)initid->ptr; 181 | 182 | memcached_free(&container->memc); 183 | free(container); 184 | } 185 | my_bool memc_cas_by_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 186 | { 187 | memcached_return rc; 188 | memc_function_st *container; 189 | 190 | container= prepare_args(args, message, MEMC_CAS_BY_KEY, 4, 5); 191 | if (container == NULL) 192 | return 1; 193 | 194 | /* Init the memcached_st we will use for this pass */ 195 | rc= memc_get_servers(&container->memc); 196 | 197 | initid->ptr= (char *)container; 198 | 199 | return 0; 200 | } 201 | 202 | long long memc_cas_by_key(UDF_INIT *initid, UDF_ARGS *args, 203 | __attribute__ ((unused)) char *is_null, 204 | char *error) 205 | { 206 | memcached_return rc; 207 | memc_function_st *container= (memc_function_st *)initid->ptr; 208 | 209 | if (args->args[2] == NULL) 210 | args->lengths[2]= 0; 211 | 212 | rc= memcached_cas_by_key(&container->memc, 213 | args->args[0], (size_t)args->lengths[0], 214 | args->args[1], (size_t)args->lengths[1], 215 | args->args[2], (size_t)args->lengths[2], 216 | container->expiration, (uint16_t)0, 217 | (uint64_t) strtol(args->args[3], (char **)NULL, 10)); 218 | 219 | return (rc != MEMCACHED_SUCCESS) ? (long long) 0 : (long long) 1; 220 | } 221 | 222 | void memc_cas_by_key_deinit(UDF_INIT *initid) 223 | { 224 | /* if we allocated initid->ptr, free it here */ 225 | memc_function_st *container= (memc_function_st *)initid->ptr; 226 | 227 | memcached_free(&container->memc); 228 | free(container); 229 | } 230 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | Compilers and Options 71 | ===================== 72 | 73 | Some systems require unusual options for compilation or linking that the 74 | `configure' script does not know about. Run `./configure --help' for 75 | details on some of the pertinent environment variables. 76 | 77 | You can give `configure' initial values for configuration parameters 78 | by setting variables in the command line or in the environment. Here 79 | is an example: 80 | 81 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 82 | 83 | *Note Defining Variables::, for more details. 84 | 85 | Compiling For Multiple Architectures 86 | ==================================== 87 | 88 | You can compile the package for more than one kind of computer at the 89 | same time, by placing the object files for each architecture in their 90 | own directory. To do this, you can use GNU `make'. `cd' to the 91 | directory where you want the object files and executables to go and run 92 | the `configure' script. `configure' automatically checks for the 93 | source code in the directory that `configure' is in and in `..'. 94 | 95 | With a non-GNU `make', it is safer to compile the package for one 96 | architecture at a time in the source code directory. After you have 97 | installed the package for one architecture, use `make distclean' before 98 | reconfiguring for another architecture. 99 | 100 | Installation Names 101 | ================== 102 | 103 | By default, `make install' installs the package's commands under 104 | `/usr/local/bin', include files under `/usr/local/include', etc. You 105 | can specify an installation prefix other than `/usr/local' by giving 106 | `configure' the option `--prefix=PREFIX'. 107 | 108 | You can specify separate installation prefixes for 109 | architecture-specific files and architecture-independent files. If you 110 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 111 | PREFIX as the prefix for installing programs and libraries. 112 | Documentation and other data files still use the regular prefix. 113 | 114 | In addition, if you use an unusual directory layout you can give 115 | options like `--bindir=DIR' to specify different values for particular 116 | kinds of files. Run `configure --help' for a list of the directories 117 | you can set and what kinds of files go in them. 118 | 119 | If the package supports it, you can cause programs to be installed 120 | with an extra prefix or suffix on their names by giving `configure' the 121 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 122 | 123 | Optional Features 124 | ================= 125 | 126 | Some packages pay attention to `--enable-FEATURE' options to 127 | `configure', where FEATURE indicates an optional part of the package. 128 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 129 | is something like `gnu-as' or `x' (for the X Window System). The 130 | `README' should mention any `--enable-' and `--with-' options that the 131 | package recognizes. 132 | 133 | For packages that use the X Window System, `configure' can usually 134 | find the X include and library files automatically, but if it doesn't, 135 | you can use the `configure' options `--x-includes=DIR' and 136 | `--x-libraries=DIR' to specify their locations. 137 | 138 | Specifying the System Type 139 | ========================== 140 | 141 | There may be some features `configure' cannot figure out automatically, 142 | but needs to determine by the type of machine the package will run on. 143 | Usually, assuming the package is built to be run on the _same_ 144 | architectures, `configure' can figure that out, but if it prints a 145 | message saying it cannot guess the machine type, give it the 146 | `--build=TYPE' option. TYPE can either be a short name for the system 147 | type, such as `sun4', or a canonical name which has the form: 148 | 149 | CPU-COMPANY-SYSTEM 150 | 151 | where SYSTEM can have one of these forms: 152 | 153 | OS KERNEL-OS 154 | 155 | See the file `config.sub' for the possible values of each field. If 156 | `config.sub' isn't included in this package, then this package doesn't 157 | need to know the machine type. 158 | 159 | If you are _building_ compiler tools for cross-compiling, you should 160 | use the option `--target=TYPE' to select the type of system they will 161 | produce code for. 162 | 163 | If you want to _use_ a cross compiler, that generates code for a 164 | platform different from the build platform, you should specify the 165 | "host" platform (i.e., that on which the generated programs will 166 | eventually be run) with `--host=TYPE'. 167 | 168 | Sharing Defaults 169 | ================ 170 | 171 | If you want to set default values for `configure' scripts to share, you 172 | can create a site shell script called `config.site' that gives default 173 | values for variables like `CC', `cache_file', and `prefix'. 174 | `configure' looks for `PREFIX/share/config.site' if it exists, then 175 | `PREFIX/etc/config.site' if it exists. Or, you can set the 176 | `CONFIG_SITE' environment variable to the location of the site script. 177 | A warning: not all `configure' scripts look for a site script. 178 | 179 | Defining Variables 180 | ================== 181 | 182 | Variables not defined in a site shell script can be set in the 183 | environment passed to `configure'. However, some packages may run 184 | configure again during the build, and the customized values of these 185 | variables may be lost. In order to avoid this problem, you should set 186 | them in the `configure' command line, using `VAR=value'. For example: 187 | 188 | ./configure CC=/usr/local2/bin/gcc 189 | 190 | causes the specified `gcc' to be used as the C compiler (unless it is 191 | overridden in the site shell script). 192 | 193 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 194 | an Autoconf bug. Until the bug is fixed you can use this workaround: 195 | 196 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 197 | 198 | `configure' Invocation 199 | ====================== 200 | 201 | `configure' recognizes the following options to control how it operates. 202 | 203 | `--help' 204 | `-h' 205 | Print a summary of the options to `configure', and exit. 206 | 207 | `--version' 208 | `-V' 209 | Print the version of Autoconf used to generate the `configure' 210 | script, and exit. 211 | 212 | `--cache-file=FILE' 213 | Enable the cache: use and save the results of the tests in FILE, 214 | traditionally `config.cache'. FILE defaults to `/dev/null' to 215 | disable caching. 216 | 217 | `--config-cache' 218 | `-C' 219 | Alias for `--cache-file=config.cache'. 220 | 221 | `--quiet' 222 | `--silent' 223 | `-q' 224 | Do not print messages saying which checks are being made. To 225 | suppress all normal output, redirect it to `/dev/null' (any error 226 | messages will still be shown). 227 | 228 | `--srcdir=DIR' 229 | Look for the package's source code in directory DIR. Usually 230 | `configure' can determine that directory automatically. 231 | 232 | `configure' also accepts some other, not widely useful, options. Run 233 | `configure --help' for more details. 234 | 235 | -------------------------------------------------------------------------------- /tests/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.10 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 5 | # 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 6 | # This Makefile.in is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | @SET_MAKE@ 16 | VPATH = @srcdir@ 17 | pkgdatadir = $(datadir)/@PACKAGE@ 18 | pkglibdir = $(libdir)/@PACKAGE@ 19 | pkgincludedir = $(includedir)/@PACKAGE@ 20 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 21 | install_sh_DATA = $(install_sh) -c -m 644 22 | install_sh_PROGRAM = $(install_sh) -c 23 | install_sh_SCRIPT = $(install_sh) -c 24 | INSTALL_HEADER = $(INSTALL_DATA) 25 | transform = $(program_transform_name) 26 | NORMAL_INSTALL = : 27 | PRE_INSTALL = : 28 | POST_INSTALL = : 29 | NORMAL_UNINSTALL = : 30 | PRE_UNINSTALL = : 31 | POST_UNINSTALL = : 32 | build_triplet = @build@ 33 | host_triplet = @host@ 34 | subdir = tests 35 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 36 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 37 | am__aclocal_m4_deps = $(top_srcdir)/config/ac_mysql.m4 \ 38 | $(top_srcdir)/config/ac_libmemcached.m4 \ 39 | $(top_srcdir)/configure.ac 40 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 41 | $(ACLOCAL_M4) 42 | mkinstalldirs = $(install_sh) -d 43 | CONFIG_HEADER = $(top_builddir)/src/libmemcached_config.h 44 | CONFIG_CLEAN_FILES = 45 | SOURCES = 46 | DIST_SOURCES = 47 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 48 | ACLOCAL = @ACLOCAL@ 49 | AMTAR = @AMTAR@ 50 | AR = @AR@ 51 | AUTOCONF = @AUTOCONF@ 52 | AUTOHEADER = @AUTOHEADER@ 53 | AUTOMAKE = @AUTOMAKE@ 54 | AWK = @AWK@ 55 | CC = @CC@ 56 | CCDEPMODE = @CCDEPMODE@ 57 | CFLAGS = @CFLAGS@ 58 | CPP = @CPP@ 59 | CPPFLAGS = @CPPFLAGS@ 60 | CXX = @CXX@ 61 | CXXCPP = @CXXCPP@ 62 | CXXDEPMODE = @CXXDEPMODE@ 63 | CXXFLAGS = @CXXFLAGS@ 64 | CYGPATH_W = @CYGPATH_W@ 65 | DEFS = @DEFS@ 66 | DEPDIR = @DEPDIR@ 67 | DEPS_CFLAGS = @DEPS_CFLAGS@ 68 | DEPS_LIBS = @DEPS_LIBS@ 69 | ECHO = @ECHO@ 70 | ECHO_C = @ECHO_C@ 71 | ECHO_N = @ECHO_N@ 72 | ECHO_T = @ECHO_T@ 73 | EGREP = @EGREP@ 74 | EXEEXT = @EXEEXT@ 75 | F77 = @F77@ 76 | FFLAGS = @FFLAGS@ 77 | GREP = @GREP@ 78 | INSTALL = @INSTALL@ 79 | INSTALL_DATA = @INSTALL_DATA@ 80 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 81 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 82 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 83 | LDFLAGS = @LDFLAGS@ 84 | LIBOBJS = @LIBOBJS@ 85 | LIBS = 86 | LIBTOOL = @LIBTOOL@ 87 | LN_S = @LN_S@ 88 | LTLIBOBJS = @LTLIBOBJS@ 89 | MAKEINFO = @MAKEINFO@ 90 | MKDIR_P = @MKDIR_P@ 91 | MYSQL_CONFIG = @MYSQL_CONFIG@ 92 | MYSQL_INC = @MYSQL_INC@ 93 | MYSQL_LIB = @MYSQL_LIB@ 94 | OBJEXT = @OBJEXT@ 95 | PACKAGE = @PACKAGE@ 96 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 97 | PACKAGE_NAME = @PACKAGE_NAME@ 98 | PACKAGE_STRING = @PACKAGE_STRING@ 99 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 100 | PACKAGE_VERSION = @PACKAGE_VERSION@ 101 | PATH_SEPARATOR = @PATH_SEPARATOR@ 102 | RANLIB = @RANLIB@ 103 | SET_MAKE = @SET_MAKE@ 104 | SHELL = @SHELL@ 105 | STRIP = @STRIP@ 106 | VERSION = @VERSION@ 107 | abs_builddir = @abs_builddir@ 108 | abs_srcdir = @abs_srcdir@ 109 | abs_top_builddir = @abs_top_builddir@ 110 | abs_top_srcdir = @abs_top_srcdir@ 111 | ac_ct_CC = @ac_ct_CC@ 112 | ac_ct_CXX = @ac_ct_CXX@ 113 | ac_ct_F77 = @ac_ct_F77@ 114 | am__include = @am__include@ 115 | am__leading_dot = @am__leading_dot@ 116 | am__quote = @am__quote@ 117 | am__tar = @am__tar@ 118 | am__untar = @am__untar@ 119 | bindir = @bindir@ 120 | build = @build@ 121 | build_alias = @build_alias@ 122 | build_cpu = @build_cpu@ 123 | build_os = @build_os@ 124 | build_vendor = @build_vendor@ 125 | builddir = @builddir@ 126 | datadir = @datadir@ 127 | datarootdir = @datarootdir@ 128 | docdir = @docdir@ 129 | dvidir = @dvidir@ 130 | exec_prefix = @exec_prefix@ 131 | host = @host@ 132 | host_alias = @host_alias@ 133 | host_cpu = @host_cpu@ 134 | host_os = @host_os@ 135 | host_vendor = @host_vendor@ 136 | htmldir = @htmldir@ 137 | includedir = @includedir@ 138 | infodir = @infodir@ 139 | install_sh = @install_sh@ 140 | libdir = @libdir@ 141 | libexecdir = @libexecdir@ 142 | localedir = @localedir@ 143 | localstatedir = @localstatedir@ 144 | mandir = @mandir@ 145 | mkdir_p = @mkdir_p@ 146 | oldincludedir = @oldincludedir@ 147 | pdfdir = @pdfdir@ 148 | prefix = @prefix@ 149 | program_transform_name = @program_transform_name@ 150 | psdir = @psdir@ 151 | sbindir = @sbindir@ 152 | sharedstatedir = @sharedstatedir@ 153 | srcdir = @srcdir@ 154 | sysconfdir = @sysconfdir@ 155 | target_alias = @target_alias@ 156 | top_build_prefix = @top_build_prefix@ 157 | top_builddir = @top_builddir@ 158 | top_srcdir = @top_srcdir@ 159 | INCLUDES = 160 | LDADDS = 161 | EXTRA_DIST = memc_test.cmp memc_test.sql 162 | all: all-am 163 | 164 | .SUFFIXES: 165 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 166 | @for dep in $?; do \ 167 | case '$(am__configure_deps)' in \ 168 | *$$dep*) \ 169 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ 170 | && exit 0; \ 171 | exit 1;; \ 172 | esac; \ 173 | done; \ 174 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ 175 | cd $(top_srcdir) && \ 176 | $(AUTOMAKE) --gnu tests/Makefile 177 | .PRECIOUS: Makefile 178 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 179 | @case '$?' in \ 180 | *config.status*) \ 181 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ 182 | *) \ 183 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ 184 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ 185 | esac; 186 | 187 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 188 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 189 | 190 | $(top_srcdir)/configure: $(am__configure_deps) 191 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 192 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 193 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 194 | 195 | mostlyclean-libtool: 196 | -rm -f *.lo 197 | 198 | clean-libtool: 199 | -rm -rf .libs _libs 200 | tags: TAGS 201 | TAGS: 202 | 203 | ctags: CTAGS 204 | CTAGS: 205 | 206 | 207 | distdir: $(DISTFILES) 208 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 209 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 210 | list='$(DISTFILES)'; \ 211 | dist_files=`for file in $$list; do echo $$file; done | \ 212 | sed -e "s|^$$srcdirstrip/||;t" \ 213 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 214 | case $$dist_files in \ 215 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 216 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 217 | sort -u` ;; \ 218 | esac; \ 219 | for file in $$dist_files; do \ 220 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 221 | if test -d $$d/$$file; then \ 222 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 223 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 224 | cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ 225 | fi; \ 226 | cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ 227 | else \ 228 | test -f $(distdir)/$$file \ 229 | || cp -p $$d/$$file $(distdir)/$$file \ 230 | || exit 1; \ 231 | fi; \ 232 | done 233 | check-am: all-am 234 | check: check-am 235 | all-am: Makefile 236 | installdirs: 237 | install: install-am 238 | install-exec: install-exec-am 239 | install-data: install-data-am 240 | uninstall: uninstall-am 241 | 242 | install-am: all-am 243 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 244 | 245 | installcheck: installcheck-am 246 | install-strip: 247 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 248 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 249 | `test -z '$(STRIP)' || \ 250 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install 251 | mostlyclean-generic: 252 | 253 | clean-generic: 254 | 255 | distclean-generic: 256 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 257 | 258 | maintainer-clean-generic: 259 | @echo "This command is intended for maintainers to use" 260 | @echo "it deletes files that may require special tools to rebuild." 261 | clean: clean-am 262 | 263 | clean-am: clean-generic clean-libtool mostlyclean-am 264 | 265 | distclean: distclean-am 266 | -rm -f Makefile 267 | distclean-am: clean-am distclean-generic 268 | 269 | dvi: dvi-am 270 | 271 | dvi-am: 272 | 273 | html: html-am 274 | 275 | info: info-am 276 | 277 | info-am: 278 | 279 | install-data-am: 280 | 281 | install-dvi: install-dvi-am 282 | 283 | install-exec-am: 284 | 285 | install-html: install-html-am 286 | 287 | install-info: install-info-am 288 | 289 | install-man: 290 | 291 | install-pdf: install-pdf-am 292 | 293 | install-ps: install-ps-am 294 | 295 | installcheck-am: 296 | 297 | maintainer-clean: maintainer-clean-am 298 | -rm -f Makefile 299 | maintainer-clean-am: distclean-am maintainer-clean-generic 300 | 301 | mostlyclean: mostlyclean-am 302 | 303 | mostlyclean-am: mostlyclean-generic mostlyclean-libtool 304 | 305 | pdf: pdf-am 306 | 307 | pdf-am: 308 | 309 | ps: ps-am 310 | 311 | ps-am: 312 | 313 | uninstall-am: 314 | 315 | .MAKE: install-am install-strip 316 | 317 | .PHONY: all all-am check check-am clean clean-generic clean-libtool \ 318 | distclean distclean-generic distclean-libtool distdir dvi \ 319 | dvi-am html html-am info info-am install install-am \ 320 | install-data install-data-am install-dvi install-dvi-am \ 321 | install-exec install-exec-am install-html install-html-am \ 322 | install-info install-info-am install-man install-pdf \ 323 | install-pdf-am install-ps install-ps-am install-strip \ 324 | installcheck installcheck-am installdirs maintainer-clean \ 325 | maintainer-clean-generic mostlyclean mostlyclean-generic \ 326 | mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am 327 | 328 | 329 | record: 330 | cat memc_test.sql | mysql > memc_test.cmp 331 | 332 | test: testapp 333 | cat memc_test.sql | mysql > memc_test.res 334 | diff memc_test.cmp memc_test.res 335 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 336 | # Otherwise a system limit (for SysV at least) may be exceeded. 337 | .NOEXPORT: 338 | -------------------------------------------------------------------------------- /src/stats.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Patrick Galbraith, Brian Aker 2 | 3 | See COPYING file found with distribution for license. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include "common.h" 14 | 15 | my_bool memc_stats_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 16 | char *memc_stats(UDF_INIT *initid, UDF_ARGS *args, 17 | char *result, 18 | unsigned long *length, 19 | char *is_null, 20 | char *error); 21 | void memc_stats_deinit(UDF_INIT *initid); 22 | my_bool memc_stat_get_keys_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 23 | char *memc_stat_get_keys(UDF_INIT *initid, UDF_ARGS *args, 24 | char *result, 25 | unsigned long *length, 26 | char *is_null, char *error); 27 | void memc_stat_get_keys_deinit(UDF_INIT *initid); 28 | my_bool memc_stat_get_value_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 29 | char *memc_stat_get_value(UDF_INIT *initid, UDF_ARGS *args, 30 | __attribute__ ((unused)) char *result, 31 | unsigned long *length, 32 | __attribute__ ((unused)) char *is_null, 33 | char *error); 34 | void memc_stat_get_value_deinit(UDF_INIT *initid); 35 | 36 | my_bool memc_stats_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 37 | { 38 | unsigned int x; 39 | memcached_return rc; 40 | memc_function_st *container; 41 | 42 | /* this is how to fail */ 43 | if (args->arg_count != 1) 44 | { 45 | strncpy(message, 46 | "1 argument required: servers, comma-separated: memc_stats()", 47 | MYSQL_ERRMSG_SIZE); 48 | return 1; 49 | } 50 | 51 | args->arg_type[0]= STRING_RESULT; 52 | 53 | initid->max_length= MEMC_UDF_MAX_SIZE; 54 | container= calloc(1, sizeof(memc_function_st)); 55 | 56 | /* Init the memcached_st we will use for this pass */ 57 | rc= memc_get_servers(&container->memc); 58 | 59 | /* Now setup the string */ 60 | container->stats_string= memcached_string_create(&container->memc, NULL, 1024); 61 | 62 | initid->ptr= (char *)container; 63 | 64 | return 0; 65 | } 66 | 67 | char *memc_stats(UDF_INIT *initid, UDF_ARGS *args, 68 | __attribute__ ((unused)) char *result, 69 | unsigned long *length, 70 | __attribute__ ((unused)) char *is_null, 71 | __attribute__ ((unused)) char *error) 72 | { 73 | /* how do I utilise this? Print out in case of error? */ 74 | /* We'll just hard-code now? */ 75 | unsigned int x; 76 | memcached_return rc; 77 | char buf[100]; 78 | 79 | memcached_stat_st *stat; 80 | memcached_server_st *servers; 81 | memcached_server_st *server_list; 82 | 83 | memc_function_st *container= (memc_function_st *)initid->ptr; 84 | memcached_string_reset(container->stats_string); 85 | 86 | servers= memcached_servers_parse(args->args[0]); 87 | memcached_server_push(&container->memc, servers); 88 | memcached_server_list_free(servers); 89 | 90 | stat= memcached_stat(&container->memc, NULL, &rc); 91 | 92 | if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) 93 | { 94 | sprintf(error, "Failure to communicate with servers (%s)\n", 95 | memcached_strerror(&container->memc, rc)); 96 | *length= strlen(error); 97 | return(error); 98 | } 99 | 100 | server_list= memcached_server_list(&container->memc); 101 | 102 | sprintf(buf, "Listing %u Server\n\n", memcached_server_count(&container->memc)); 103 | memcached_string_append(container->stats_string, buf, strlen(buf)); 104 | for (x= 0; x < memcached_server_count(&container->memc); x++) 105 | { 106 | char **list; 107 | char **ptr; 108 | 109 | list= memcached_stat_get_keys(&container->memc, &stat[x], &rc); 110 | 111 | sprintf(buf, "Server: %s (%u)\n", 112 | memcached_server_name(&container->memc, server_list[x]), 113 | memcached_server_port(&container->memc, server_list[x])); 114 | 115 | 116 | memcached_string_append(container->stats_string, buf, strlen(buf)); 117 | 118 | for (ptr= list; *ptr; ptr++) 119 | { 120 | memcached_return rc; 121 | char *value= memcached_stat_get_value(&container->memc, &stat[x], *ptr, &rc); 122 | 123 | sprintf(buf, "\t %s: %s\n", *ptr, value); 124 | free(value); 125 | memcached_string_append(container->stats_string, buf, strlen(buf)); 126 | } 127 | 128 | free(list); 129 | memcached_string_append(container->stats_string,"\n", strlen("\n")); 130 | } 131 | *length= container->stats_string->end - container->stats_string->string; 132 | free(stat); 133 | return container->stats_string->string; 134 | } 135 | 136 | void memc_stats_deinit(UDF_INIT *initid) 137 | { 138 | /* if we allocated initid->ptr, free it here */ 139 | memc_function_st *container= (memc_function_st *)initid->ptr; 140 | 141 | memcached_string_free(container->stats_string); 142 | memcached_free(&container->memc); 143 | free(container); 144 | 145 | return; 146 | } 147 | 148 | 149 | my_bool memc_stat_get_value_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 150 | { 151 | char **list; 152 | char **ptr; 153 | memcached_return rc; 154 | int exists= 0; 155 | unsigned int x; 156 | memc_function_st *container; 157 | memcached_stat_st *stat; 158 | memcached_server_st *servers; 159 | 160 | 161 | /* this is how to fail */ 162 | if (args->arg_count != 2) 163 | { 164 | strncpy(message, 165 | "two arguments must be supplied: memc_stat_get_value('', '')", 166 | MYSQL_ERRMSG_SIZE); 167 | return 1; 168 | } 169 | 170 | initid->max_length= MEMC_UDF_MAX_SIZE; 171 | container= calloc(1, sizeof(memc_function_st)); 172 | 173 | /* Init the memcached_st we will use for this pass */ 174 | rc= memc_get_servers(&container->memc); 175 | servers= memcached_servers_parse(args->args[0]); 176 | memcached_server_push(&container->memc, servers); 177 | memcached_server_list_free(servers); 178 | 179 | stat= memcached_stat(&container->memc, NULL, &rc); 180 | 181 | list= memcached_stat_get_keys(&container->memc, &stat[0], &rc); 182 | for (ptr= list; *ptr; ptr++) 183 | { 184 | if (!strcmp(args->args[1], *ptr)) 185 | { 186 | exists++; 187 | } 188 | } 189 | if (!exists) 190 | { 191 | char err_buf[50]; 192 | sprintf(err_buf, "ERROR: the stat key %s is not a valid stat!\n", args->args[1]); 193 | strncpy(message, err_buf, MYSQL_ERRMSG_SIZE); 194 | memcached_free(&container->memc); 195 | free(container); 196 | return 1; 197 | } 198 | 199 | initid->ptr= (char *)container; 200 | 201 | return 0; 202 | } 203 | /* 204 | memc_get 205 | get cached object, takes hash-key arg 206 | */ 207 | char *memc_stat_get_value(UDF_INIT *initid, UDF_ARGS *args, 208 | __attribute__ ((unused)) char *result, 209 | unsigned long *length, 210 | __attribute__ ((unused)) char *is_null, 211 | char *error) 212 | { 213 | /* how do I utilise this? Print out in case of error? */ 214 | memcached_return rc; 215 | char *value; 216 | char **list; 217 | char **ptr; 218 | char buf[100]; 219 | int exists= 0; 220 | 221 | memcached_stat_st *stat; 222 | memcached_server_st *servers; 223 | 224 | memc_function_st *container= (memc_function_st *)initid->ptr; 225 | 226 | servers= memcached_servers_parse(args->args[0]); 227 | memcached_server_push(&container->memc, servers); 228 | memcached_server_list_free(servers); 229 | 230 | stat= memcached_stat(&container->memc, NULL, &rc); 231 | 232 | list= memcached_stat_get_keys(&container->memc, &stat[0], &rc); 233 | for (ptr= list; *ptr; ptr++) 234 | { 235 | if (!strcmp(args->args[1], *ptr)) 236 | { 237 | exists++; 238 | } 239 | } 240 | if (exists) 241 | { 242 | value= memcached_stat_get_value(&container->memc, &stat[0], args->args[1], &rc); 243 | *length= strlen(value); 244 | } 245 | else 246 | { 247 | sprintf(error, "ERROR: the stat key %s is not a valid stat!\n", args->args[1]); 248 | *length=0; 249 | value= NULL; 250 | } 251 | 252 | return value; 253 | } 254 | 255 | /* de-init UDF */ 256 | void memc_stat_get_value_deinit(UDF_INIT *initid) 257 | { 258 | /* if we allocated initid->ptr, free it here */ 259 | memc_function_st *container= (memc_function_st *)initid->ptr; 260 | 261 | memcached_free(&container->memc); 262 | free(container); 263 | 264 | return; 265 | } 266 | 267 | my_bool memc_stat_get_keys_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 268 | { 269 | unsigned int x; 270 | memcached_return rc; 271 | memc_function_st *container; 272 | 273 | 274 | /* this is how to fail */ 275 | if (args->arg_count > 1) 276 | { 277 | strncpy(message, "This function takes no arguments: memc_stat_get_keys()", MYSQL_ERRMSG_SIZE); 278 | return 1; 279 | } 280 | 281 | initid->max_length= MEMC_UDF_MAX_SIZE; 282 | container= calloc(1, sizeof(memc_function_st)); 283 | 284 | /* Init the memcached_st we will use for this pass */ 285 | rc= memc_get_servers(&container->memc); 286 | 287 | /* Now setup the string */ 288 | container->stats_string= memcached_string_create(&container->memc, NULL, 1024); 289 | 290 | initid->ptr= (char *)container; 291 | 292 | return 0; 293 | } 294 | 295 | char *memc_stat_get_keys(UDF_INIT *initid, UDF_ARGS *args, 296 | __attribute__ ((unused)) char *result, 297 | unsigned long *length, 298 | __attribute__ ((unused)) char *is_null, 299 | __attribute__ ((unused)) char *error) 300 | { 301 | /* 302 | memc_stat 303 | get cached object, takes hash-key arg 304 | */ 305 | char **list; 306 | char **ptr; 307 | char buf[100]; 308 | memcached_stat_st stat; 309 | memcached_return rc; 310 | memc_function_st *container= (memc_function_st *)initid->ptr; 311 | 312 | list= memcached_stat_get_keys(&container->memc, &stat, &rc); 313 | for (ptr= list; *ptr; ptr++) 314 | { 315 | memcached_string_append(container->stats_string, *ptr, strlen(*ptr)); 316 | memcached_string_append(container->stats_string, "\n", 1); 317 | } 318 | free(list); 319 | 320 | *length= container->stats_string->end - container->stats_string->string; 321 | return container->stats_string->string; 322 | } 323 | /* de-init UDF */ 324 | void memc_stat_get_keys_deinit(UDF_INIT *initid) 325 | { 326 | /* if we allocated initid->ptr, free it here */ 327 | memc_function_st *container= (memc_function_st *)initid->ptr; 328 | 329 | memcached_string_free(container->stats_string); 330 | memcached_free(&container->memc); 331 | free(container); 332 | 333 | return; 334 | } 335 | 336 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hi! 2 | 3 | This is the memcached mysql UDFs (user defined functions) to work with libmemcached, Brian Aker's super duper 4 | new fast client library for memcached. 5 | 6 | 7 | Prerequisites 8 | 9 | * MySQL 5.0 and greater 10 | * Latest memcached (svn co http://code.sixapart.com/svn/memcached/trunk) 11 | * libmemcached (hg clone http://hg.tangent.org/libmemcached/) 12 | * latest autoconf tools 13 | 14 | To build: 15 | ./configure --with-mysql=/usr/local/mysql/bin/mysql_config --libdir=/usr/local/mysql/lib/mysql/ 16 | make 17 | make install 18 | 19 | 20 | To then load the functions that you need: 21 | 22 | Please keep in mind that for your UDF to be loaded, it must be in the 23 | library path for your server (and yes, we should fix this). On Linux you can 24 | set this by exporting the correct path in LD_LIBRARY_PATH for your mysql 25 | server. 26 | 27 | You can install the functions as listed below by cutting and pasting,or 28 | optionally there now are two ways to install these easily: 29 | 30 | * sql/install_functions.sql - this loads the functions with simple CREATE FUNCTION 31 | commands as shown below 32 | 33 | * utils/install.pl - This is a perl script that queries your mysql.func table to see what 34 | functions are already installed and installs them if not yet installed. It will ask you 35 | each time for every function not installed, if you want to install, or you can run it with 36 | -s/--silent to have it not prompt you. It runs as the 'root' database user (required). 37 | 38 | memc_servers_add() 39 | 40 | CREATE FUNCTION memc_servers_add RETURNS INT SONAME "libmemcached_functions_mysql.so"; 41 | 42 | memc_servers_add_by_key() 43 | 44 | CREATE FUNCTION memc_servers_add_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 45 | 46 | memc_servers_set() 47 | 48 | CREATE FUNCTION memc_servers_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 49 | 50 | memc_set() 51 | 52 | CREATE FUNCTION memc_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 53 | 54 | memc_set_by_key() 55 | 56 | CREATE FUNCTION memc_set_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 57 | 58 | memc_cas() 59 | 60 | CREATE FUNCTION memc_cas RETURNS INT SONAME "libmemcached_functions_mysql.so"; 61 | 62 | memc_cas_by_key() 63 | 64 | CREATE FUNCTION memc_cas_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 65 | 66 | memc_get() 67 | 68 | CREATE FUNCTION memc_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 69 | 70 | memc_get_by_key() 71 | 72 | CREATE FUNCTION memc_get RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 73 | 74 | memc_delete() 75 | 76 | CREATE FUNCTION memc_delete RETURNS INT SONAME "libmemcached_functions_mysql.so"; 77 | 78 | memc_delete_by_key() 79 | 80 | CREATE FUNCTION memc_delete_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 81 | 82 | memc_append() 83 | 84 | CREATE FUNCTION memc_append RETURNS INT SONAME "libmemcached_functions_mysql.so"; 85 | 86 | memc_append_by_key() 87 | 88 | CREATE FUNCTION memc_append_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 89 | 90 | memc_prepend() 91 | 92 | CREATE FUNCTION memc_prepend RETURNS INT SONAME "libmemcached_functions_mysql.so"; 93 | 94 | memc_prepend_by_key() 95 | 96 | CREATE FUNCTION memc_prepend_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 97 | 98 | memc_increment() 99 | 100 | CREATE FUNCTION memc_increment RETURNS INT SONAME "libmemcached_functions_mysql.so"; 101 | 102 | memc_decrement() 103 | 104 | CREATE FUNCTION memc_decrement RETURNS INT SONAME "libmemcached_functions_mysql.so"; 105 | 106 | memc_replace() 107 | 108 | CREATE FUNCTION memc_replace RETURNS INT SONAME "libmemcached_functions_mysql.so"; 109 | 110 | memc_replace_by_key() 111 | 112 | CREATE FUNCTION memc_replace_by_key RETURNS INT SONAME "libmemcached_functions_mysql.so"; 113 | 114 | memc_servers_behavior_set() 115 | 116 | CREATE FUNCTION memc_servers_behavior_set RETURNS INT SONAME "libmemcached_functions_mysql.so"; 117 | 118 | memc_list_behaviors() 119 | 120 | CREATE FUNCTION memc_list_behaviors RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 121 | 122 | memc_stats() 123 | 124 | CREATE FUNCTION memc_stats RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 125 | 126 | memc_stats_get_keys() 127 | 128 | CREATE FUNCTION memc_stats_get_keys RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 129 | 130 | memc_stats_get_value() 131 | 132 | CREATE FUNCTION memc_stats_get_value RETURNS STRING SONAME "libmemcached_functions_mysql.so"; 133 | 134 | 135 | Usage of functions 136 | 137 | memc_servers_set() 138 | 139 | I want to set the server I'm using to localhost: 140 | 141 | select memc_servers_set('127.0.0.1'); 142 | 143 | I have several servers, mem1.grazr.com, mem2.grazr.com: 144 | 145 | select memc_servers_set('mem1.grazr.com,mem2.grazr.com'); 146 | 147 | 148 | memc_set() 149 | 150 | mysql> select memc_set('abc', 'cool new memcached udf in mysql'); 151 | +----------------------------------------------------+ 152 | | memc_set('abc', 'cool new memcached udf in mysql') | 153 | +----------------------------------------------------+ 154 | | 0 | 155 | +----------------------------------------------------+ 156 | 1 row in set (0.00 sec) 157 | 158 | 159 | memc_get() 160 | 161 | mysql> select memc_get('abc'); 162 | +---------------------------------+ 163 | | memc_get('abc') | 164 | +---------------------------------+ 165 | | cool new memcached udf in mysql | 166 | +---------------------------------+ 167 | 1 row in set (0.00 sec) 168 | 169 | 170 | memc_delete() 171 | 172 | mysql> select memc_delete('abc'); 173 | +--------------------+ 174 | | memc_delete('abc') | 175 | +--------------------+ 176 | | 0 | 177 | +--------------------+ 178 | 1 row in set (0.00 sec) 179 | 180 | mysql> select memc_get('abc'); 181 | +-----------------+ 182 | | memc_get('abc') | 183 | +-----------------+ 184 | | NULL | 185 | +-----------------+ 186 | 1 row in set (0.00 sec) 187 | 188 | 189 | memc_append() and memc_prepend() 190 | 191 | mysql> select memc_set('abc', ' Spot '); 192 | +---------------------------+ 193 | | memc_set('abc', ' Spot ') | 194 | +---------------------------+ 195 | | 0 | 196 | +---------------------------+ 197 | 1 row in set (0.00 sec) 198 | 199 | mysql> select memc_append('abc', ' run.'); 200 | +-----------------------------+ 201 | | memc_append('abc', ' run.') | 202 | +-----------------------------+ 203 | | 0 | 204 | +-----------------------------+ 205 | 1 row in set (0.00 sec) 206 | 207 | mysql> select memc_get('abc'); 208 | +-----------------+ 209 | | memc_get('abc') | 210 | +-----------------+ 211 | | Spot run. | 212 | +-----------------+ 213 | 1 row in set (0.00 sec) 214 | 215 | mysql> select memc_prepend('abc', 'See'); 216 | +----------------------------+ 217 | | memc_prepend('abc', 'See') | 218 | +----------------------------+ 219 | | 0 | 220 | +----------------------------+ 221 | 1 row in set (0.00 sec) 222 | 223 | mysql> select memc_get('abc'); 224 | +-----------------+ 225 | | memc_get('abc') | 226 | +-----------------+ 227 | | See Spot run. | 228 | +-----------------+ 229 | 1 row in set (0.00 sec) 230 | 231 | 232 | memc_increment() and memc_decrement() 233 | 234 | mysql> select memc_set('sequence:1', 1); 235 | +---------------------------+ 236 | | memc_set('sequence:1', 1) | 237 | +---------------------------+ 238 | | 0 | 239 | +---------------------------+ 240 | 1 row in set (0.00 sec) 241 | 242 | mysql> select memc_get('sequence:1'); 243 | +------------------------+ 244 | | memc_get('sequence:1') | 245 | +------------------------+ 246 | | 1 | 247 | +------------------------+ 248 | 1 row in set (0.00 sec) 249 | 250 | mysql> select memc_increment('sequence:1', 5); 251 | +---------------------------------+ 252 | | memc_increment('sequence:1', 5) | 253 | +---------------------------------+ 254 | | 6 | 255 | +---------------------------------+ 256 | 1 row in set (0.00 sec) 257 | 258 | mysql> select memc_increment('sequence:1', 10); 259 | ]+----------------------------------+ 260 | | memc_increment('sequence:1', 10) | 261 | +----------------------------------+ 262 | | 16 | 263 | +----------------------------------+ 264 | 1 row in set (0.01 sec) 265 | 266 | mysql> select memc_increment('sequence:1'); 267 | +------------------------------+ 268 | | memc_increment('sequence:1') | 269 | +------------------------------+ 270 | | 17 | 271 | +------------------------------+ 272 | 1 row in set (0.00 sec) 273 | 274 | mysql> select memc_decrement('sequence:1'); 275 | +------------------------------+ 276 | | memc_decrement('sequence:1') | 277 | +------------------------------+ 278 | | 16 | 279 | +------------------------------+ 280 | 1 row in set (0.00 sec) 281 | 282 | mysql> select memc_decrement('sequence:1', 15); 283 | +----------------------------------+ 284 | | memc_decrement('sequence:1', 15) | 285 | +----------------------------------+ 286 | | 1 | 287 | +----------------------------------+ 288 | 1 row in set (0.00 sec) 289 | 290 | 291 | memc_replace() 292 | 293 | mysql> select memc_replace('sequence:1', 'String value'); 294 | +--------------------------------------------+ 295 | | memc_replace('sequence:1', 'String value') | 296 | +--------------------------------------------+ 297 | | 0 | 298 | +--------------------------------------------+ 299 | 1 row in set (0.00 sec) 300 | 301 | mysql> select memc_get('sequence:1'); 302 | +------------------------+ 303 | | memc_get('sequence:1') | 304 | +------------------------+ 305 | | String value | 306 | +------------------------+ 307 | 1 row in set (0.01 sec) 308 | 309 | memc_list_behaviors() 310 | 311 | Use this to see what behaviors you have to chose from 312 | 313 | 314 | memc_servers_behavior_set() 315 | 316 | You use this to set the type of behavior your client has to the memcached server 317 | 318 | mysql> select memc_list_behaviors()\G 319 | *************************** 1. row *************************** 320 | memc_list_behaviors(): 321 | +-------------------------------------+ 322 | | MEMCACHED SERVER BEHAVIORS | 323 | +-------------------------------------+ 324 | | MEMCACHED_BEHAVIOR_SUPPORT_CAS | 325 | | MEMCACHED_BEHAVIOR_NO_BLOCK | 326 | | MEMCACHED_BEHAVIOR_TCP_NODELAY | 327 | | MEMCACHED_BEHAVIOR_HASH | 328 | | MEMCACHED_BEHAVIOR_CACHE_LOOKUPS | 329 | | MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE | 330 | | MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE | 331 | +-------------------------------------+ 332 | 333 | 334 | mysql> select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1'); 335 | +-----------------------------------------------------------------+ 336 | | memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1') | 337 | +-----------------------------------------------------------------+ 338 | | 0 | 339 | +-----------------------------------------------------------------+ 340 | 1 row in set (0.01 sec) 341 | 342 | Have fun! 343 | 344 | Cheers, 345 | Brian, 346 | Seattle, WA 347 | Patrick, 348 | Sharon, NH (Live Free or Die!). 349 | -------------------------------------------------------------------------------- /config/missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | 4 | scriptversion=2006-05-10.23 5 | 6 | # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 7 | # Free Software Foundation, Inc. 8 | # Originally by Fran,cois Pinard , 1996. 9 | 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, write to the Free Software 22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 | # 02110-1301, USA. 24 | 25 | # As a special exception to the GNU General Public License, if you 26 | # distribute this file as part of a program that contains a 27 | # configuration script generated by Autoconf, you may include it under 28 | # the same distribution terms that you use for the rest of that program. 29 | 30 | if test $# -eq 0; then 31 | echo 1>&2 "Try \`$0 --help' for more information" 32 | exit 1 33 | fi 34 | 35 | run=: 36 | sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' 37 | sed_minuso='s/.* -o \([^ ]*\).*/\1/p' 38 | 39 | # In the cases where this matters, `missing' is being run in the 40 | # srcdir already. 41 | if test -f configure.ac; then 42 | configure_ac=configure.ac 43 | else 44 | configure_ac=configure.in 45 | fi 46 | 47 | msg="missing on your system" 48 | 49 | case $1 in 50 | --run) 51 | # Try to run requested program, and just exit if it succeeds. 52 | run= 53 | shift 54 | "$@" && exit 0 55 | # Exit code 63 means version mismatch. This often happens 56 | # when the user try to use an ancient version of a tool on 57 | # a file that requires a minimum version. In this case we 58 | # we should proceed has if the program had been absent, or 59 | # if --run hadn't been passed. 60 | if test $? = 63; then 61 | run=: 62 | msg="probably too old" 63 | fi 64 | ;; 65 | 66 | -h|--h|--he|--hel|--help) 67 | echo "\ 68 | $0 [OPTION]... PROGRAM [ARGUMENT]... 69 | 70 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 71 | error status if there is no known handling for PROGRAM. 72 | 73 | Options: 74 | -h, --help display this help and exit 75 | -v, --version output version information and exit 76 | --run try to run the given command, and emulate it if it fails 77 | 78 | Supported PROGRAM values: 79 | aclocal touch file \`aclocal.m4' 80 | autoconf touch file \`configure' 81 | autoheader touch file \`config.h.in' 82 | autom4te touch the output file, or create a stub one 83 | automake touch all \`Makefile.in' files 84 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 85 | flex create \`lex.yy.c', if possible, from existing .c 86 | help2man touch the output file 87 | lex create \`lex.yy.c', if possible, from existing .c 88 | makeinfo touch the output file 89 | tar try tar, gnutar, gtar, then tar without non-portable flags 90 | yacc create \`y.tab.[ch]', if possible, from existing .[ch] 91 | 92 | Send bug reports to ." 93 | exit $? 94 | ;; 95 | 96 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 97 | echo "missing $scriptversion (GNU Automake)" 98 | exit $? 99 | ;; 100 | 101 | -*) 102 | echo 1>&2 "$0: Unknown \`$1' option" 103 | echo 1>&2 "Try \`$0 --help' for more information" 104 | exit 1 105 | ;; 106 | 107 | esac 108 | 109 | # Now exit if we have it, but it failed. Also exit now if we 110 | # don't have it and --version was passed (most likely to detect 111 | # the program). 112 | case $1 in 113 | lex|yacc) 114 | # Not GNU programs, they don't have --version. 115 | ;; 116 | 117 | tar) 118 | if test -n "$run"; then 119 | echo 1>&2 "ERROR: \`tar' requires --run" 120 | exit 1 121 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 122 | exit 1 123 | fi 124 | ;; 125 | 126 | *) 127 | if test -z "$run" && ($1 --version) > /dev/null 2>&1; then 128 | # We have it, but it failed. 129 | exit 1 130 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 131 | # Could not run --version or --help. This is probably someone 132 | # running `$TOOL --version' or `$TOOL --help' to check whether 133 | # $TOOL exists and not knowing $TOOL uses missing. 134 | exit 1 135 | fi 136 | ;; 137 | esac 138 | 139 | # If it does not exist, or fails to run (possibly an outdated version), 140 | # try to emulate it. 141 | case $1 in 142 | aclocal*) 143 | echo 1>&2 "\ 144 | WARNING: \`$1' is $msg. You should only need it if 145 | you modified \`acinclude.m4' or \`${configure_ac}'. You might want 146 | to install the \`Automake' and \`Perl' packages. Grab them from 147 | any GNU archive site." 148 | touch aclocal.m4 149 | ;; 150 | 151 | autoconf) 152 | echo 1>&2 "\ 153 | WARNING: \`$1' is $msg. You should only need it if 154 | you modified \`${configure_ac}'. You might want to install the 155 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 156 | archive site." 157 | touch configure 158 | ;; 159 | 160 | autoheader) 161 | echo 1>&2 "\ 162 | WARNING: \`$1' is $msg. You should only need it if 163 | you modified \`acconfig.h' or \`${configure_ac}'. You might want 164 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 165 | from any GNU archive site." 166 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` 167 | test -z "$files" && files="config.h" 168 | touch_files= 169 | for f in $files; do 170 | case $f in 171 | *:*) touch_files="$touch_files "`echo "$f" | 172 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 173 | *) touch_files="$touch_files $f.in";; 174 | esac 175 | done 176 | touch $touch_files 177 | ;; 178 | 179 | automake*) 180 | echo 1>&2 "\ 181 | WARNING: \`$1' is $msg. You should only need it if 182 | you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 183 | You might want to install the \`Automake' and \`Perl' packages. 184 | Grab them from any GNU archive site." 185 | find . -type f -name Makefile.am -print | 186 | sed 's/\.am$/.in/' | 187 | while read f; do touch "$f"; done 188 | ;; 189 | 190 | autom4te) 191 | echo 1>&2 "\ 192 | WARNING: \`$1' is needed, but is $msg. 193 | You might have modified some files without having the 194 | proper tools for further handling them. 195 | You can get \`$1' as part of \`Autoconf' from any GNU 196 | archive site." 197 | 198 | file=`echo "$*" | sed -n "$sed_output"` 199 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 200 | if test -f "$file"; then 201 | touch $file 202 | else 203 | test -z "$file" || exec >$file 204 | echo "#! /bin/sh" 205 | echo "# Created by GNU Automake missing as a replacement of" 206 | echo "# $ $@" 207 | echo "exit 0" 208 | chmod +x $file 209 | exit 1 210 | fi 211 | ;; 212 | 213 | bison|yacc) 214 | echo 1>&2 "\ 215 | WARNING: \`$1' $msg. You should only need it if 216 | you modified a \`.y' file. You may need the \`Bison' package 217 | in order for those modifications to take effect. You can get 218 | \`Bison' from any GNU archive site." 219 | rm -f y.tab.c y.tab.h 220 | if test $# -ne 1; then 221 | eval LASTARG="\${$#}" 222 | case $LASTARG in 223 | *.y) 224 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 225 | if test -f "$SRCFILE"; then 226 | cp "$SRCFILE" y.tab.c 227 | fi 228 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 229 | if test -f "$SRCFILE"; then 230 | cp "$SRCFILE" y.tab.h 231 | fi 232 | ;; 233 | esac 234 | fi 235 | if test ! -f y.tab.h; then 236 | echo >y.tab.h 237 | fi 238 | if test ! -f y.tab.c; then 239 | echo 'main() { return 0; }' >y.tab.c 240 | fi 241 | ;; 242 | 243 | lex|flex) 244 | echo 1>&2 "\ 245 | WARNING: \`$1' is $msg. You should only need it if 246 | you modified a \`.l' file. You may need the \`Flex' package 247 | in order for those modifications to take effect. You can get 248 | \`Flex' from any GNU archive site." 249 | rm -f lex.yy.c 250 | if test $# -ne 1; then 251 | eval LASTARG="\${$#}" 252 | case $LASTARG in 253 | *.l) 254 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 255 | if test -f "$SRCFILE"; then 256 | cp "$SRCFILE" lex.yy.c 257 | fi 258 | ;; 259 | esac 260 | fi 261 | if test ! -f lex.yy.c; then 262 | echo 'main() { return 0; }' >lex.yy.c 263 | fi 264 | ;; 265 | 266 | help2man) 267 | echo 1>&2 "\ 268 | WARNING: \`$1' is $msg. You should only need it if 269 | you modified a dependency of a manual page. You may need the 270 | \`Help2man' package in order for those modifications to take 271 | effect. You can get \`Help2man' from any GNU archive site." 272 | 273 | file=`echo "$*" | sed -n "$sed_output"` 274 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 275 | if test -f "$file"; then 276 | touch $file 277 | else 278 | test -z "$file" || exec >$file 279 | echo ".ab help2man is required to generate this page" 280 | exit 1 281 | fi 282 | ;; 283 | 284 | makeinfo) 285 | echo 1>&2 "\ 286 | WARNING: \`$1' is $msg. You should only need it if 287 | you modified a \`.texi' or \`.texinfo' file, or any other file 288 | indirectly affecting the aspect of the manual. The spurious 289 | call might also be the consequence of using a buggy \`make' (AIX, 290 | DU, IRIX). You might want to install the \`Texinfo' package or 291 | the \`GNU make' package. Grab either from any GNU archive site." 292 | # The file to touch is that specified with -o ... 293 | file=`echo "$*" | sed -n "$sed_output"` 294 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 295 | if test -z "$file"; then 296 | # ... or it is the one specified with @setfilename ... 297 | infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 298 | file=`sed -n ' 299 | /^@setfilename/{ 300 | s/.* \([^ ]*\) *$/\1/ 301 | p 302 | q 303 | }' $infile` 304 | # ... or it is derived from the source name (dir/f.texi becomes f.info) 305 | test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info 306 | fi 307 | # If the file does not exist, the user really needs makeinfo; 308 | # let's fail without touching anything. 309 | test -f $file || exit 1 310 | touch $file 311 | ;; 312 | 313 | tar) 314 | shift 315 | 316 | # We have already tried tar in the generic part. 317 | # Look for gnutar/gtar before invocation to avoid ugly error 318 | # messages. 319 | if (gnutar --version > /dev/null 2>&1); then 320 | gnutar "$@" && exit 0 321 | fi 322 | if (gtar --version > /dev/null 2>&1); then 323 | gtar "$@" && exit 0 324 | fi 325 | firstarg="$1" 326 | if shift; then 327 | case $firstarg in 328 | *o*) 329 | firstarg=`echo "$firstarg" | sed s/o//` 330 | tar "$firstarg" "$@" && exit 0 331 | ;; 332 | esac 333 | case $firstarg in 334 | *h*) 335 | firstarg=`echo "$firstarg" | sed s/h//` 336 | tar "$firstarg" "$@" && exit 0 337 | ;; 338 | esac 339 | fi 340 | 341 | echo 1>&2 "\ 342 | WARNING: I can't seem to be able to run \`tar' with the given arguments. 343 | You may want to install GNU tar or Free paxutils, or check the 344 | command line arguments." 345 | exit 1 346 | ;; 347 | 348 | *) 349 | echo 1>&2 "\ 350 | WARNING: \`$1' is needed, and is $msg. 351 | You might have modified some files without having the 352 | proper tools for further handling them. Check the \`README' file, 353 | it often tells you about the needed prerequisites for installing 354 | this package. You may also peek at any GNU archive site, in case 355 | some other package would contain this missing \`$1' program." 356 | exit 1 357 | ;; 358 | esac 359 | 360 | exit 0 361 | 362 | # Local variables: 363 | # eval: (add-hook 'write-file-hooks 'time-stamp) 364 | # time-stamp-start: "scriptversion=" 365 | # time-stamp-format: "%:y-%02m-%02d.%02H" 366 | # time-stamp-end: "$" 367 | # End: 368 | -------------------------------------------------------------------------------- /config/install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2006-10-14.15 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. 43 | 44 | nl=' 45 | ' 46 | IFS=" "" $nl" 47 | 48 | # set DOITPROG to echo to test this script 49 | 50 | # Don't use :- since 4.3BSD and earlier shells don't like it. 51 | doit="${DOITPROG-}" 52 | if test -z "$doit"; then 53 | doit_exec=exec 54 | else 55 | doit_exec=$doit 56 | fi 57 | 58 | # Put in absolute file names if you don't have them in your path; 59 | # or use environment vars. 60 | 61 | mvprog="${MVPROG-mv}" 62 | cpprog="${CPPROG-cp}" 63 | chmodprog="${CHMODPROG-chmod}" 64 | chownprog="${CHOWNPROG-chown}" 65 | chgrpprog="${CHGRPPROG-chgrp}" 66 | stripprog="${STRIPPROG-strip}" 67 | rmprog="${RMPROG-rm}" 68 | mkdirprog="${MKDIRPROG-mkdir}" 69 | 70 | posix_glob= 71 | posix_mkdir= 72 | 73 | # Desired mode of installed file. 74 | mode=0755 75 | 76 | chmodcmd=$chmodprog 77 | chowncmd= 78 | chgrpcmd= 79 | stripcmd= 80 | rmcmd="$rmprog -f" 81 | mvcmd="$mvprog" 82 | src= 83 | dst= 84 | dir_arg= 85 | dstarg= 86 | no_target_directory= 87 | 88 | usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89 | or: $0 [OPTION]... SRCFILES... DIRECTORY 90 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91 | or: $0 [OPTION]... -d DIRECTORIES... 92 | 93 | In the 1st form, copy SRCFILE to DSTFILE. 94 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95 | In the 4th, create DIRECTORIES. 96 | 97 | Options: 98 | -c (ignored) 99 | -d create directories instead of installing files. 100 | -g GROUP $chgrpprog installed files to GROUP. 101 | -m MODE $chmodprog installed files to MODE. 102 | -o USER $chownprog installed files to USER. 103 | -s $stripprog installed files. 104 | -t DIRECTORY install into DIRECTORY. 105 | -T report an error if DSTFILE is a directory. 106 | --help display this help and exit. 107 | --version display version info and exit. 108 | 109 | Environment variables override the default commands: 110 | CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111 | " 112 | 113 | while test $# -ne 0; do 114 | case $1 in 115 | -c) shift 116 | continue;; 117 | 118 | -d) dir_arg=true 119 | shift 120 | continue;; 121 | 122 | -g) chgrpcmd="$chgrpprog $2" 123 | shift 124 | shift 125 | continue;; 126 | 127 | --help) echo "$usage"; exit $?;; 128 | 129 | -m) mode=$2 130 | shift 131 | shift 132 | case $mode in 133 | *' '* | *' '* | *' 134 | '* | *'*'* | *'?'* | *'['*) 135 | echo "$0: invalid mode: $mode" >&2 136 | exit 1;; 137 | esac 138 | continue;; 139 | 140 | -o) chowncmd="$chownprog $2" 141 | shift 142 | shift 143 | continue;; 144 | 145 | -s) stripcmd=$stripprog 146 | shift 147 | continue;; 148 | 149 | -t) dstarg=$2 150 | shift 151 | shift 152 | continue;; 153 | 154 | -T) no_target_directory=true 155 | shift 156 | continue;; 157 | 158 | --version) echo "$0 $scriptversion"; exit $?;; 159 | 160 | --) shift 161 | break;; 162 | 163 | -*) echo "$0: invalid option: $1" >&2 164 | exit 1;; 165 | 166 | *) break;; 167 | esac 168 | done 169 | 170 | if test $# -ne 0 && test -z "$dir_arg$dstarg"; then 171 | # When -d is used, all remaining arguments are directories to create. 172 | # When -t is used, the destination is already specified. 173 | # Otherwise, the last argument is the destination. Remove it from $@. 174 | for arg 175 | do 176 | if test -n "$dstarg"; then 177 | # $@ is not empty: it contains at least $arg. 178 | set fnord "$@" "$dstarg" 179 | shift # fnord 180 | fi 181 | shift # arg 182 | dstarg=$arg 183 | done 184 | fi 185 | 186 | if test $# -eq 0; then 187 | if test -z "$dir_arg"; then 188 | echo "$0: no input file specified." >&2 189 | exit 1 190 | fi 191 | # It's OK to call `install-sh -d' without argument. 192 | # This can happen when creating conditional directories. 193 | exit 0 194 | fi 195 | 196 | if test -z "$dir_arg"; then 197 | trap '(exit $?); exit' 1 2 13 15 198 | 199 | # Set umask so as not to create temps with too-generous modes. 200 | # However, 'strip' requires both read and write access to temps. 201 | case $mode in 202 | # Optimize common cases. 203 | *644) cp_umask=133;; 204 | *755) cp_umask=22;; 205 | 206 | *[0-7]) 207 | if test -z "$stripcmd"; then 208 | u_plus_rw= 209 | else 210 | u_plus_rw='% 200' 211 | fi 212 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 213 | *) 214 | if test -z "$stripcmd"; then 215 | u_plus_rw= 216 | else 217 | u_plus_rw=,u+rw 218 | fi 219 | cp_umask=$mode$u_plus_rw;; 220 | esac 221 | fi 222 | 223 | for src 224 | do 225 | # Protect names starting with `-'. 226 | case $src in 227 | -*) src=./$src ;; 228 | esac 229 | 230 | if test -n "$dir_arg"; then 231 | dst=$src 232 | dstdir=$dst 233 | test -d "$dstdir" 234 | dstdir_status=$? 235 | else 236 | 237 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 238 | # might cause directories to be created, which would be especially bad 239 | # if $src (and thus $dsttmp) contains '*'. 240 | if test ! -f "$src" && test ! -d "$src"; then 241 | echo "$0: $src does not exist." >&2 242 | exit 1 243 | fi 244 | 245 | if test -z "$dstarg"; then 246 | echo "$0: no destination specified." >&2 247 | exit 1 248 | fi 249 | 250 | dst=$dstarg 251 | # Protect names starting with `-'. 252 | case $dst in 253 | -*) dst=./$dst ;; 254 | esac 255 | 256 | # If destination is a directory, append the input filename; won't work 257 | # if double slashes aren't ignored. 258 | if test -d "$dst"; then 259 | if test -n "$no_target_directory"; then 260 | echo "$0: $dstarg: Is a directory" >&2 261 | exit 1 262 | fi 263 | dstdir=$dst 264 | dst=$dstdir/`basename "$src"` 265 | dstdir_status=0 266 | else 267 | # Prefer dirname, but fall back on a substitute if dirname fails. 268 | dstdir=` 269 | (dirname "$dst") 2>/dev/null || 270 | expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 271 | X"$dst" : 'X\(//\)[^/]' \| \ 272 | X"$dst" : 'X\(//\)$' \| \ 273 | X"$dst" : 'X\(/\)' \| . 2>/dev/null || 274 | echo X"$dst" | 275 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 276 | s//\1/ 277 | q 278 | } 279 | /^X\(\/\/\)[^/].*/{ 280 | s//\1/ 281 | q 282 | } 283 | /^X\(\/\/\)$/{ 284 | s//\1/ 285 | q 286 | } 287 | /^X\(\/\).*/{ 288 | s//\1/ 289 | q 290 | } 291 | s/.*/./; q' 292 | ` 293 | 294 | test -d "$dstdir" 295 | dstdir_status=$? 296 | fi 297 | fi 298 | 299 | obsolete_mkdir_used=false 300 | 301 | if test $dstdir_status != 0; then 302 | case $posix_mkdir in 303 | '') 304 | # Create intermediate dirs using mode 755 as modified by the umask. 305 | # This is like FreeBSD 'install' as of 1997-10-28. 306 | umask=`umask` 307 | case $stripcmd.$umask in 308 | # Optimize common cases. 309 | *[2367][2367]) mkdir_umask=$umask;; 310 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311 | 312 | *[0-7]) 313 | mkdir_umask=`expr $umask + 22 \ 314 | - $umask % 100 % 40 + $umask % 20 \ 315 | - $umask % 10 % 4 + $umask % 2 316 | `;; 317 | *) mkdir_umask=$umask,go-w;; 318 | esac 319 | 320 | # With -d, create the new directory with the user-specified mode. 321 | # Otherwise, rely on $mkdir_umask. 322 | if test -n "$dir_arg"; then 323 | mkdir_mode=-m$mode 324 | else 325 | mkdir_mode= 326 | fi 327 | 328 | posix_mkdir=false 329 | case $umask in 330 | *[123567][0-7][0-7]) 331 | # POSIX mkdir -p sets u+wx bits regardless of umask, which 332 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333 | ;; 334 | *) 335 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 336 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 337 | 338 | if (umask $mkdir_umask && 339 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 340 | then 341 | if test -z "$dir_arg" || { 342 | # Check for POSIX incompatibilities with -m. 343 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 344 | # other-writeable bit of parent directory when it shouldn't. 345 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 346 | ls_ld_tmpdir=`ls -ld "$tmpdir"` 347 | case $ls_ld_tmpdir in 348 | d????-?r-*) different_mode=700;; 349 | d????-?--*) different_mode=755;; 350 | *) false;; 351 | esac && 352 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { 353 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 354 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 355 | } 356 | } 357 | then posix_mkdir=: 358 | fi 359 | rmdir "$tmpdir/d" "$tmpdir" 360 | else 361 | # Remove any dirs left behind by ancient mkdir implementations. 362 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 363 | fi 364 | trap '' 0;; 365 | esac;; 366 | esac 367 | 368 | if 369 | $posix_mkdir && ( 370 | umask $mkdir_umask && 371 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 372 | ) 373 | then : 374 | else 375 | 376 | # The umask is ridiculous, or mkdir does not conform to POSIX, 377 | # or it failed possibly due to a race condition. Create the 378 | # directory the slow way, step by step, checking for races as we go. 379 | 380 | case $dstdir in 381 | /*) prefix=/ ;; 382 | -*) prefix=./ ;; 383 | *) prefix= ;; 384 | esac 385 | 386 | case $posix_glob in 387 | '') 388 | if (set -f) 2>/dev/null; then 389 | posix_glob=true 390 | else 391 | posix_glob=false 392 | fi ;; 393 | esac 394 | 395 | oIFS=$IFS 396 | IFS=/ 397 | $posix_glob && set -f 398 | set fnord $dstdir 399 | shift 400 | $posix_glob && set +f 401 | IFS=$oIFS 402 | 403 | prefixes= 404 | 405 | for d 406 | do 407 | test -z "$d" && continue 408 | 409 | prefix=$prefix$d 410 | if test -d "$prefix"; then 411 | prefixes= 412 | else 413 | if $posix_mkdir; then 414 | (umask=$mkdir_umask && 415 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416 | # Don't fail if two instances are running concurrently. 417 | test -d "$prefix" || exit 1 418 | else 419 | case $prefix in 420 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421 | *) qprefix=$prefix;; 422 | esac 423 | prefixes="$prefixes '$qprefix'" 424 | fi 425 | fi 426 | prefix=$prefix/ 427 | done 428 | 429 | if test -n "$prefixes"; then 430 | # Don't fail if two instances are running concurrently. 431 | (umask $mkdir_umask && 432 | eval "\$doit_exec \$mkdirprog $prefixes") || 433 | test -d "$dstdir" || exit 1 434 | obsolete_mkdir_used=true 435 | fi 436 | fi 437 | fi 438 | 439 | if test -n "$dir_arg"; then 440 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444 | else 445 | 446 | # Make a couple of temp file names in the proper directory. 447 | dsttmp=$dstdir/_inst.$$_ 448 | rmtmp=$dstdir/_rm.$$_ 449 | 450 | # Trap to clean up those temp files at exit. 451 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452 | 453 | # Copy the file name to the temp name. 454 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 455 | 456 | # and set any options; do chmod last to preserve setuid bits. 457 | # 458 | # If any of these fail, we abort the whole thing. If we want to 459 | # ignore errors from any of these, just make sure not to ignore 460 | # errors from the above "$doit $cpprog $src $dsttmp" command. 461 | # 462 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464 | && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 465 | && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466 | 467 | # Now rename the file to the real destination. 468 | { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469 | || { 470 | # The rename failed, perhaps because mv can't rename something else 471 | # to itself, or perhaps because mv is so ancient that it does not 472 | # support -f. 473 | 474 | # Now remove or move aside any old file at destination location. 475 | # We try this two ways since rm can't unlink itself on some 476 | # systems and the destination file might be busy for other 477 | # reasons. In this case, the final cleanup might fail but the new 478 | # file should still install successfully. 479 | { 480 | if test -f "$dst"; then 481 | $doit $rmcmd -f "$dst" 2>/dev/null \ 482 | || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 483 | && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484 | || { 485 | echo "$0: cannot unlink or rename $dst" >&2 486 | (exit 1); exit 1 487 | } 488 | else 489 | : 490 | fi 491 | } && 492 | 493 | # Now rename the file to the real destination. 494 | $doit $mvcmd "$dsttmp" "$dst" 495 | } 496 | } || exit 1 497 | 498 | trap '' 0 499 | fi 500 | done 501 | 502 | # Local variables: 503 | # eval: (add-hook 'write-file-hooks 'time-stamp) 504 | # time-stamp-start: "scriptversion=" 505 | # time-stamp-format: "%:y-%02m-%02d.%02H" 506 | # time-stamp-end: "$" 507 | # End: 508 | -------------------------------------------------------------------------------- /docs/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.10 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 5 | # 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 6 | # This Makefile.in is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | @SET_MAKE@ 16 | VPATH = @srcdir@ 17 | pkgdatadir = $(datadir)/@PACKAGE@ 18 | pkglibdir = $(libdir)/@PACKAGE@ 19 | pkgincludedir = $(includedir)/@PACKAGE@ 20 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 21 | install_sh_DATA = $(install_sh) -c -m 644 22 | install_sh_PROGRAM = $(install_sh) -c 23 | install_sh_SCRIPT = $(install_sh) -c 24 | INSTALL_HEADER = $(INSTALL_DATA) 25 | transform = $(program_transform_name) 26 | NORMAL_INSTALL = : 27 | PRE_INSTALL = : 28 | POST_INSTALL = : 29 | NORMAL_UNINSTALL = : 30 | PRE_UNINSTALL = : 31 | POST_UNINSTALL = : 32 | build_triplet = @build@ 33 | host_triplet = @host@ 34 | subdir = docs 35 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 36 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 37 | am__aclocal_m4_deps = $(top_srcdir)/config/ac_mysql.m4 \ 38 | $(top_srcdir)/config/ac_libmemcached.m4 \ 39 | $(top_srcdir)/configure.ac 40 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 41 | $(ACLOCAL_M4) 42 | mkinstalldirs = $(install_sh) -d 43 | CONFIG_HEADER = $(top_builddir)/src/libmemcached_config.h 44 | CONFIG_CLEAN_FILES = 45 | SOURCES = 46 | DIST_SOURCES = 47 | man3dir = $(mandir)/man3 48 | am__installdirs = "$(DESTDIR)$(man3dir)" 49 | NROFF = nroff 50 | MANS = $(man_MANS) 51 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 52 | ACLOCAL = @ACLOCAL@ 53 | AMTAR = @AMTAR@ 54 | AR = @AR@ 55 | AUTOCONF = @AUTOCONF@ 56 | AUTOHEADER = @AUTOHEADER@ 57 | AUTOMAKE = @AUTOMAKE@ 58 | AWK = @AWK@ 59 | CC = @CC@ 60 | CCDEPMODE = @CCDEPMODE@ 61 | CFLAGS = @CFLAGS@ 62 | CPP = @CPP@ 63 | CPPFLAGS = @CPPFLAGS@ 64 | CXX = @CXX@ 65 | CXXCPP = @CXXCPP@ 66 | CXXDEPMODE = @CXXDEPMODE@ 67 | CXXFLAGS = @CXXFLAGS@ 68 | CYGPATH_W = @CYGPATH_W@ 69 | DEFS = @DEFS@ 70 | DEPDIR = @DEPDIR@ 71 | DEPS_CFLAGS = @DEPS_CFLAGS@ 72 | DEPS_LIBS = @DEPS_LIBS@ 73 | ECHO = @ECHO@ 74 | ECHO_C = @ECHO_C@ 75 | ECHO_N = @ECHO_N@ 76 | ECHO_T = @ECHO_T@ 77 | EGREP = @EGREP@ 78 | EXEEXT = @EXEEXT@ 79 | F77 = @F77@ 80 | FFLAGS = @FFLAGS@ 81 | GREP = @GREP@ 82 | INSTALL = @INSTALL@ 83 | INSTALL_DATA = @INSTALL_DATA@ 84 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 85 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 86 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 87 | LDFLAGS = @LDFLAGS@ 88 | LIBOBJS = @LIBOBJS@ 89 | LIBS = @LIBS@ 90 | LIBTOOL = @LIBTOOL@ 91 | LN_S = @LN_S@ 92 | LTLIBOBJS = @LTLIBOBJS@ 93 | MAKEINFO = @MAKEINFO@ 94 | MKDIR_P = @MKDIR_P@ 95 | MYSQL_CONFIG = @MYSQL_CONFIG@ 96 | MYSQL_INC = @MYSQL_INC@ 97 | MYSQL_LIB = @MYSQL_LIB@ 98 | OBJEXT = @OBJEXT@ 99 | PACKAGE = @PACKAGE@ 100 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 101 | PACKAGE_NAME = @PACKAGE_NAME@ 102 | PACKAGE_STRING = @PACKAGE_STRING@ 103 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 104 | PACKAGE_VERSION = @PACKAGE_VERSION@ 105 | PATH_SEPARATOR = @PATH_SEPARATOR@ 106 | RANLIB = @RANLIB@ 107 | SET_MAKE = @SET_MAKE@ 108 | SHELL = @SHELL@ 109 | STRIP = @STRIP@ 110 | VERSION = @VERSION@ 111 | abs_builddir = @abs_builddir@ 112 | abs_srcdir = @abs_srcdir@ 113 | abs_top_builddir = @abs_top_builddir@ 114 | abs_top_srcdir = @abs_top_srcdir@ 115 | ac_ct_CC = @ac_ct_CC@ 116 | ac_ct_CXX = @ac_ct_CXX@ 117 | ac_ct_F77 = @ac_ct_F77@ 118 | am__include = @am__include@ 119 | am__leading_dot = @am__leading_dot@ 120 | am__quote = @am__quote@ 121 | am__tar = @am__tar@ 122 | am__untar = @am__untar@ 123 | bindir = @bindir@ 124 | build = @build@ 125 | build_alias = @build_alias@ 126 | build_cpu = @build_cpu@ 127 | build_os = @build_os@ 128 | build_vendor = @build_vendor@ 129 | builddir = @builddir@ 130 | datadir = @datadir@ 131 | datarootdir = @datarootdir@ 132 | docdir = @docdir@ 133 | dvidir = @dvidir@ 134 | exec_prefix = @exec_prefix@ 135 | host = @host@ 136 | host_alias = @host_alias@ 137 | host_cpu = @host_cpu@ 138 | host_os = @host_os@ 139 | host_vendor = @host_vendor@ 140 | htmldir = @htmldir@ 141 | includedir = @includedir@ 142 | infodir = @infodir@ 143 | install_sh = @install_sh@ 144 | libdir = @libdir@ 145 | libexecdir = @libexecdir@ 146 | localedir = @localedir@ 147 | localstatedir = @localstatedir@ 148 | mandir = @mandir@ 149 | mkdir_p = @mkdir_p@ 150 | oldincludedir = @oldincludedir@ 151 | pdfdir = @pdfdir@ 152 | prefix = @prefix@ 153 | program_transform_name = @program_transform_name@ 154 | psdir = @psdir@ 155 | sbindir = @sbindir@ 156 | sharedstatedir = @sharedstatedir@ 157 | srcdir = @srcdir@ 158 | sysconfdir = @sysconfdir@ 159 | target_alias = @target_alias@ 160 | top_build_prefix = @top_build_prefix@ 161 | top_builddir = @top_builddir@ 162 | top_srcdir = @top_srcdir@ 163 | INCLUDES = include 164 | EXTRA_DIST = memc_get.pod\ 165 | memc_set.pod\ 166 | memc_append.pod\ 167 | memc_prepend.pod\ 168 | memc_increment.pod\ 169 | memc_decrement.pod\ 170 | memc_servers_set.pod\ 171 | memc_list_behaviors.pod\ 172 | memc_list_hash_types.pod\ 173 | memc_list_distribution_types.pod\ 174 | memc_servers_behavior_set.pod\ 175 | memc_servers_behavior_get.pod\ 176 | memc_behavior_set.pod\ 177 | memc_behavior_get.pod\ 178 | memc_udf_version.pod\ 179 | memc_libmemcached_version.pod\ 180 | memc_stats.pod 181 | 182 | man_MANS = memc_get.3\ 183 | memc_set.3\ 184 | memc_append.3\ 185 | memc_prepend.3\ 186 | memc_increment.3\ 187 | memc_decrement.3\ 188 | memc_servers_set.3\ 189 | memc_list_behaviors.3\ 190 | memc_list_hash_types.3\ 191 | memc_list_distribution_types.3\ 192 | memc_servers_behavior_set.3\ 193 | memc_servers_behavior_get.3\ 194 | memc_behavior_set.3\ 195 | memc_behavior_get.3\ 196 | memc_udf_version.3\ 197 | memc_libmemcached_version.3\ 198 | memc_stat_get_keys.3\ 199 | memc_stats.3 200 | 201 | all: all-am 202 | 203 | .SUFFIXES: 204 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 205 | @for dep in $?; do \ 206 | case '$(am__configure_deps)' in \ 207 | *$$dep*) \ 208 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ 209 | && exit 0; \ 210 | exit 1;; \ 211 | esac; \ 212 | done; \ 213 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \ 214 | cd $(top_srcdir) && \ 215 | $(AUTOMAKE) --gnu docs/Makefile 216 | .PRECIOUS: Makefile 217 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 218 | @case '$?' in \ 219 | *config.status*) \ 220 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ 221 | *) \ 222 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ 223 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ 224 | esac; 225 | 226 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 227 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 228 | 229 | $(top_srcdir)/configure: $(am__configure_deps) 230 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 231 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 232 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 233 | 234 | mostlyclean-libtool: 235 | -rm -f *.lo 236 | 237 | clean-libtool: 238 | -rm -rf .libs _libs 239 | install-man3: $(man3_MANS) $(man_MANS) 240 | @$(NORMAL_INSTALL) 241 | test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" 242 | @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ 243 | l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ 244 | for i in $$l2; do \ 245 | case "$$i" in \ 246 | *.3*) list="$$list $$i" ;; \ 247 | esac; \ 248 | done; \ 249 | for i in $$list; do \ 250 | if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ 251 | else file=$$i; fi; \ 252 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 253 | case "$$ext" in \ 254 | 3*) ;; \ 255 | *) ext='3' ;; \ 256 | esac; \ 257 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 258 | inst=`echo $$inst | sed -e 's/^.*\///'`; \ 259 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 260 | echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ 261 | $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \ 262 | done 263 | uninstall-man3: 264 | @$(NORMAL_UNINSTALL) 265 | @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ 266 | l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ 267 | for i in $$l2; do \ 268 | case "$$i" in \ 269 | *.3*) list="$$list $$i" ;; \ 270 | esac; \ 271 | done; \ 272 | for i in $$list; do \ 273 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 274 | case "$$ext" in \ 275 | 3*) ;; \ 276 | *) ext='3' ;; \ 277 | esac; \ 278 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 279 | inst=`echo $$inst | sed -e 's/^.*\///'`; \ 280 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 281 | echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \ 282 | rm -f "$(DESTDIR)$(man3dir)/$$inst"; \ 283 | done 284 | tags: TAGS 285 | TAGS: 286 | 287 | ctags: CTAGS 288 | CTAGS: 289 | 290 | 291 | distdir: $(DISTFILES) 292 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 293 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 294 | list='$(DISTFILES)'; \ 295 | dist_files=`for file in $$list; do echo $$file; done | \ 296 | sed -e "s|^$$srcdirstrip/||;t" \ 297 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 298 | case $$dist_files in \ 299 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 300 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 301 | sort -u` ;; \ 302 | esac; \ 303 | for file in $$dist_files; do \ 304 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 305 | if test -d $$d/$$file; then \ 306 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 307 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 308 | cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ 309 | fi; \ 310 | cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ 311 | else \ 312 | test -f $(distdir)/$$file \ 313 | || cp -p $$d/$$file $(distdir)/$$file \ 314 | || exit 1; \ 315 | fi; \ 316 | done 317 | check-am: all-am 318 | check: check-am 319 | all-am: Makefile $(MANS) 320 | installdirs: 321 | for dir in "$(DESTDIR)$(man3dir)"; do \ 322 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ 323 | done 324 | install: install-am 325 | install-exec: install-exec-am 326 | install-data: install-data-am 327 | uninstall: uninstall-am 328 | 329 | install-am: all-am 330 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 331 | 332 | installcheck: installcheck-am 333 | install-strip: 334 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 335 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 336 | `test -z '$(STRIP)' || \ 337 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install 338 | mostlyclean-generic: 339 | 340 | clean-generic: 341 | 342 | distclean-generic: 343 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 344 | 345 | maintainer-clean-generic: 346 | @echo "This command is intended for maintainers to use" 347 | @echo "it deletes files that may require special tools to rebuild." 348 | clean-am: clean-generic clean-libtool mostlyclean-am 349 | 350 | distclean: distclean-am 351 | -rm -f Makefile 352 | distclean-am: clean-am distclean-generic 353 | 354 | dvi: dvi-am 355 | 356 | dvi-am: 357 | 358 | html: html-am 359 | 360 | info: info-am 361 | 362 | info-am: 363 | 364 | install-data-am: install-man 365 | 366 | install-dvi: install-dvi-am 367 | 368 | install-exec-am: 369 | 370 | install-html: install-html-am 371 | 372 | install-info: install-info-am 373 | 374 | install-man: install-man3 375 | 376 | install-pdf: install-pdf-am 377 | 378 | install-ps: install-ps-am 379 | 380 | installcheck-am: 381 | 382 | maintainer-clean: maintainer-clean-am 383 | -rm -f Makefile 384 | maintainer-clean-am: distclean-am maintainer-clean-generic 385 | 386 | mostlyclean: mostlyclean-am 387 | 388 | mostlyclean-am: mostlyclean-generic mostlyclean-libtool 389 | 390 | pdf: pdf-am 391 | 392 | pdf-am: 393 | 394 | ps: ps-am 395 | 396 | ps-am: 397 | 398 | uninstall-am: uninstall-man 399 | 400 | uninstall-man: uninstall-man3 401 | 402 | .MAKE: install-am install-strip 403 | 404 | .PHONY: all all-am check check-am clean clean-generic clean-libtool \ 405 | distclean distclean-generic distclean-libtool distdir dvi \ 406 | dvi-am html html-am info info-am install install-am \ 407 | install-data install-data-am install-dvi install-dvi-am \ 408 | install-exec install-exec-am install-html install-html-am \ 409 | install-info install-info-am install-man install-man3 \ 410 | install-pdf install-pdf-am install-ps install-ps-am \ 411 | install-strip installcheck installcheck-am installdirs \ 412 | maintainer-clean maintainer-clean-generic mostlyclean \ 413 | mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 414 | uninstall uninstall-am uninstall-man uninstall-man3 415 | 416 | 417 | memc_get.3: memc_get.pod 418 | pod2man -r "" -s 3 memc_get.pod > memc_get.3 419 | memc_get_by_key.3: memc_get.pod 420 | pod2man -r "" -s 3 memc_get.pod > memc_get_by_key.3 421 | memc_add.3: memc_set.pod 422 | pod2man -r "" -s 3 memc_set.pod > memc_add.3 423 | memc_replace.3: memc_set.pod 424 | pod2man -r "" -s 3 memc_set.pod > memc_replace.3 425 | memc_cas.3: memc_set.pod 426 | pod2man -r "" -s 3 memc_set.pod > memc_cas.3 427 | memc_cas_by_key.3: memc_set.pod 428 | pod2man -r "" -s 3 memc_set.pod > memc_cas_by_key.3 429 | memc_set.3: memc_set.pod 430 | pod2man -r "" -s 3 memc_set.pod > memc_set.3 431 | memc_set_by_key.3: memc_set.pod 432 | pod2man -r "" -s 3 memc_set.pod > memc_set_by_key.3 433 | memc_append.3: memc_append.pod 434 | pod2man -r "" -s 3 memc_append.pod > memc_append.3 435 | memc_append_by_key.3: memc_append.pod 436 | pod2man -r "" -s 3 memc_append.pod > memc_append_by_key.3 437 | memc_prepend.3: memc_prepend.pod 438 | pod2man -r "" -s 3 memc_prepend.pod > memc_prepend.3 439 | memc_prepend_by_key.3: memc_prepend.pod 440 | pod2man -r "" -s 3 memc_prepend.pod > memc_prepend_by_key.3 441 | memc_increment.3: memc_increment.pod 442 | pod2man -r "" -s 3 memc_increment.pod > memc_increment.3 443 | memc_decrement.3: memc_decrement.pod 444 | pod2man -r "" -s 3 memc_decrement.pod > memc_decrement.3 445 | memc_servers_set.3: memc_servers_set.pod 446 | pod2man -r "" -s 3 memc_servers_set.pod > memc_servers_set.3 447 | memc_list_behaviors.3: memc_list_behaviors.pod 448 | pod2man -r "" -s 3 memc_list_behaviors.pod > memc_list_behaviors.3 449 | memc_list_hash_types.3: memc_list_hash_types.pod 450 | pod2man -r "" -s 3 memc_list_hash_types.pod > memc_list_hash_types.3 451 | memc_list_distribution_types.3: memc_list_distribution_types.pod 452 | pod2man -r "" -s 3 memc_list_distribution_types.pod > memc_list_distribution_types.3 453 | memc_servers_behavior_set.3: memc_servers_behavior_set.pod 454 | pod2man -r "" -s 3 memc_servers_behavior_set.pod > memc_servers_behavior_set.3 455 | memc_servers_behavior_get.3: memc_servers_behavior_get.pod 456 | pod2man -r "" -s 3 memc_servers_behavior_get.pod > memc_servers_behavior_get.3 457 | memc_behavior_set.3: memc_behavior_set.pod 458 | pod2man -r "" -s 3 memc_behavior_set.pod > memc_behavior_set.3 459 | memc_behavior_get.3: memc_behavior_get.pod 460 | pod2man -r "" -s 3 memc_behavior_get.pod > memc_behavior_get.3 461 | memc_stats.3: memc_stats.pod 462 | pod2man -r "" -s 3 memc_stats.pod > memc_stats.3 463 | memc_stat_get_keys.3: memc_stats.pod 464 | pod2man -r "" -s 3 memc_stats.pod > memc_stat_get_keys.3 465 | memc_stat_get_value.3: memc_stats.pod 466 | pod2man -r "" -s 3 memc_stats.pod > memc_stat_get_value.3 467 | memc_udf_version.3: memc_stats.pod 468 | pod2man -r "" -s 3 memc_stats.pod > memc_udf_version.3 469 | memc_libmemcached_version.3: memc_stats.pod 470 | pod2man -r "" -s 3 memc_stats.pod > memc_libmemcached_version.3 471 | 472 | clean: 473 | rm -f *.3 474 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 475 | # Otherwise a system limit (for SysV at least) may be exceeded. 476 | .NOEXPORT: 477 | -------------------------------------------------------------------------------- /tests/memc_test.cmp: -------------------------------------------------------------------------------- 1 | memc_udf_version() 2 | 0.9 3 | memc_servers_set('127.0.0.1:11211') 4 | 0 5 | memc_server_count() 6 | 1 7 | memc_set('mysql:doc1', bcol) 8 | 1 9 | memc_get('mysql:doc1') 10 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 11 | memc_delete('mysql:doc1') 12 | 1 13 | memc_get('mysql:doc1') 14 | NULL 15 | memc_set('mysql:doc1', bcol, 10) 16 | 1 17 | memc_get('mysql:doc1') 18 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 19 | sleep(5) 20 | 0 21 | memc_get('mysql:doc1') 22 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 23 | sleep(6) 24 | 0 25 | memc_get('mysql:doc1') 26 | NULL 27 | memc_set('spot:test', ' Spot ') 28 | 1 29 | memc_get('spot:test') 30 | Spot 31 | memc_prepend('spot:test', 'See') 32 | 1 33 | memc_get('spot:test') 34 | See Spot 35 | memc_append('spot:test', 'run.') 36 | 1 37 | memc_get('spot:test') 38 | See Spot run. 39 | memc_delete('spot:test') 40 | 1 41 | memc_set_by_key('A','mysql:doc1', bcol) 42 | 1 43 | memc_get_by_key('A','mysql:doc1') 44 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 45 | memc_delete_by_key('A','mysql:doc1') 46 | 1 47 | memc_get_by_key('A','mysql:doc1') 48 | NULL 49 | memc_set_by_key('A', 'mysql:doc1', bcol, 10) 50 | 1 51 | memc_get_by_key('A', 'mysql:doc1') 52 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 53 | sleep(5) 54 | 0 55 | memc_get_by_key('A', 'mysql:doc1') 56 | This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how MySQL disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of MySQL AB. MySQL AB reserves any and all rights to this documentation not expressly granted above. 57 | sleep(6) 58 | 0 59 | memc_get_by_key('A', 'mysql:doc1') 60 | NULL 61 | memc_set_by_key('A','spot:test', ' Spot ') 62 | 1 63 | memc_get_by_key('A','spot:test') 64 | Spot 65 | memc_prepend_by_key('A','spot:test', 'See') 66 | 1 67 | memc_get_by_key('A','spot:test') 68 | See Spot 69 | memc_append_by_key('A','spot:test', 'run.') 70 | 1 71 | memc_get_by_key('A','spot:test') 72 | See Spot run. 73 | memc_delete_by_key('A','spot:test') 74 | 1 75 | memc_set('increment:test', 1) 76 | 1 77 | memc_get('increment:test') 78 | 1 79 | memc_increment('increment:test') 80 | 2 81 | memc_get('increment:test') 82 | 2 83 | memc_increment('increment:test', 5) 84 | 7 85 | memc_get('increment:test') 86 | 7 87 | memc_increment('increment:test', 20) 88 | 27 89 | memc_get('increment:test') 90 | 27 91 | memc_decrement('increment:test', 20) 92 | 7 93 | memc_get('increment:test') 94 | 7 95 | memc_decrement('increment:test') 96 | 6 97 | memc_get('increment:test') 98 | 6 99 | memc_delete('increment:test') 100 | 1 101 | memc_set('add:test', 'someval') 102 | 1 103 | memc_add('add:test', 'someval') 104 | 0 105 | memc_delete('add:test') 106 | 1 107 | memc_add('add:test', 'someval') 108 | 1 109 | memc_get('add:test') 110 | someval 111 | memc_delete('add:test') 112 | 1 113 | memc_add('add:test', 'someval', 5) 114 | 1 115 | memc_get('add:test') 116 | someval 117 | sleep(2) 118 | 0 119 | memc_get('add:test') 120 | someval 121 | sleep(4) 122 | 0 123 | memc_get('add:test') 124 | NULL 125 | memc_replace('replace:test', 'replaced') 126 | 0 127 | memc_set('replace:test', 'initial') 128 | 1 129 | memc_get('replace:test') 130 | initial 131 | memc_replace('replace:test', 'replaced') 132 | 1 133 | memc_get('replace:test') 134 | replaced 135 | memc_replace('replace:test', 'replaced again', 5) 136 | 1 137 | memc_get('replace:test') 138 | replaced again 139 | sleep(6) 140 | 0 141 | memc_get('replace:test') 142 | NULL 143 | memc_replace_by_key('A', 'replace:test', 'replaced') 144 | 0 145 | memc_set_by_key('A', 'replace:test', 'initial') 146 | 1 147 | memc_get_by_key('A', 'replace:test') 148 | initial 149 | memc_replace_by_key('A', 'replace:test', 'replaced') 150 | 1 151 | memc_get_by_key('A', 'replace:test') 152 | replaced 153 | memc_replace_by_key('A', 'replace:test', 'replaced again', 5) 154 | 1 155 | memc_get_by_key('A', 'replace:test') 156 | replaced again 157 | sleep(6) 158 | 0 159 | memc_get_by_key('A', 'replace:test') 160 | NULL 161 | memc_add_by_key('A', 'add:test', 'someval', 5) 162 | 1 163 | memc_get_by_key('A', 'add:test') 164 | someval 165 | sleep(2) 166 | 0 167 | memc_get_by_key('A', 'add:test') 168 | someval 169 | sleep(4) 170 | 0 171 | memc_get_by_key('A', 'add:test') 172 | NULL 173 | memc_set_by_key('A', 'add:test', 'someval') 174 | 1 175 | memc_add_by_key('A', 'add:test', 'someval') 176 | 0 177 | memc_delete_by_key('A', 'add:test') 178 | 1 179 | memc_add_by_key('A', 'add:test', 'someval') 180 | 1 181 | memc_get_by_key('A', 'add:test') 182 | someval 183 | memc_delete_by_key('A', 'add:test') 184 | 1 185 | memc_set('cas:test', 'some value') 186 | 1 187 | memc_get('cas:test') 188 | some value 189 | memc_cas('cas:test', 'casvalue changed?', 999999) 190 | 0 191 | memc_get('cas:test') 192 | some value 193 | memc_get_cas('cas:test') 194 | 67 195 | memc_cas('cas:test', 'casvalue changed?', memc_get_cas('cas:test')) 196 | 1 197 | memc_get('cas:test') 198 | casvalue changed? 199 | memc_set_by_key('A', 'cas:test', 'some value') 200 | 1 201 | memc_get_by_key('A', 'cas:test') 202 | some value 203 | memc_cas_by_key('A', 'cas:test', 'casvalue changed?', 999999) 204 | 0 205 | memc_get_by_key('A', 'cas:test') 206 | some value 207 | memc_get_cas_by_key('A', 'cas:test') 208 | 69 209 | memc_cas_by_key('A', 'cas:test', 'casvalue changed?', memc_get_cas_by_key('A', 'cas:test')) 210 | 1 211 | memc_get_by_key('A', 'cas:test') 212 | casvalue changed? 213 | memc_list_behaviors() 214 | \nMEMCACHED SERVER BEHAVIORS\nMEMCACHED_BEHAVIOR_SUPPORT_CAS\nMEMCACHED_BEHAVIOR_NO_BLOCK\nMEMCACHED_BEHAVIOR_TCP_NODELAY\nMEMCACHED_BEHAVIOR_HASH\nMEMCACHED_BEHAVIOR_CACHE_LOOKUPS\nMEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE\nMEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE\nMEMCACHED_BEHAVIOR_BUFFER_REQUESTS\nMEMCACHED_BEHAVIOR_KETAMA\nMEMCACHED_BEHAVIOR_POLL_TIMEOUT\nMEMCACHED_BEHAVIOR_RETRY_TIMEOUT\nMEMCACHED_BEHAVIOR_DISTRIBUTION\nMEMCACHED_BEHAVIOR_BUFFER_REQUESTS\nMEMCACHED_BEHAVIOR_USER_DATA\nMEMCACHED_BEHAVIOR_SORT_HOSTS\nMEMCACHED_BEHAVIOR_VERIFY_KEY\nMEMCACHED_BEHAVIOR_CONNECT_TIMEOUT\nMEMCACHED_BEHAVIOR_KETAMA_WEIGHTED\nMEMCACHED_BEHAVIOR_KETAMA_HASH\nMEMCACHED_BEHAVIOR_BINARY_PROTOCOL\nMEMCACHED_BEHAVIOR_SND_TIMEOUT\nMEMCACHED_BEHAVIOR_RCV_TIMEOUT\nMEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT\nMEMCACHED_BEHAVIOR_IO_MSG_WATERMARK\nMEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK\n\0\0\0Usage: memc_list_hash_types().\0\0\nMEMCACHED_HASH_DEFA 215 | memc_list_distribution_types() 216 | \nMEMACHED_DISTRIBUTION_MODULA\nMEMCACHED_DISTRIBUTION_CONSISTENT\nMEMCACHED_DISTRIBUTION_KETAMA\0\0\0U 217 | memc_list_hash_types() 218 | \nMEMCACHED_HASH_DEFAULT\nMEMCACHED_HASH_MD5\nMEMCACHED_HASH_CRC\nMEMCACHED_HASH_FNV1_64\nMEMCACHED_HASH_FNV1A_64\nMEMCACHED_HASH_FNV1_32\nMEMCACHED_HASH_FNV1A_32\nMEMCACHED_HASH_JENKINS\nMEMCACHED_HASH_HSI 219 | @behavior 220 | 0 221 | memc_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK', '1') 222 | 0 223 | memc_behavior_get('MEMCACHED_BEHAVIOR_NO_BLOCK') 224 | 1 225 | memc_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK', @behavior) 226 | 0 227 | @behavior 228 | 1 229 | memc_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', '1') 230 | 0 231 | memc_behavior_get('MEMCACHED_BEHAVIOR_SUPPORT_CAS') 232 | 1 233 | memc_behavior_set('MEMCACHED_BEHAVIOR_SUPPORT_CAS', @behavior) 234 | 0 235 | memc_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY', '1') 236 | 0 237 | memc_behavior_get('MEMCACHED_BEHAVIOR_TCP_NODELAY') 238 | 1 239 | memc_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY', @behavior) 240 | 0 241 | memc_behavior_set('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS', '1') 242 | 0 243 | memc_behavior_get('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS') 244 | 1 245 | memc_behavior_set('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS', @behavior) 246 | 0 247 | memc_behavior_set('MEMCACHED_BEHAVIOR_USER_DATA', '1') 248 | 0 249 | memc_behavior_get('MEMCACHED_BEHAVIOR_USER_DATA') 250 | 1 251 | memc_behavior_set('MEMCACHED_BEHAVIOR_USER_DATA', @behavior) 252 | 0 253 | memc_behavior_set('MEMCACHED_BEHAVIOR_SORT_HOSTS', '1') 254 | 0 255 | memc_behavior_get('MEMCACHED_BEHAVIOR_SORT_HOSTS') 256 | 1 257 | memc_behavior_set('MEMCACHED_BEHAVIOR_SORT_HOSTS', @behavior) 258 | 0 259 | memc_behavior_set('MEMCACHED_BEHAVIOR_VERIFY_KEY', '1') 260 | 0 261 | memc_behavior_get('MEMCACHED_BEHAVIOR_VERIFY_KEY') 262 | 1 263 | memc_behavior_set('MEMCACHED_BEHAVIOR_VERIFY_KEY', @behavior) 264 | 0 265 | memc_behavior_set('MEMCACHED_BEHAVIOR_KETAMA', '1') 266 | 0 267 | memc_behavior_get('MEMCACHED_BEHAVIOR_KETAMA') 268 | 1 269 | memc_behavior_set('MEMCACHED_BEHAVIOR_CACHE_LOOKUPS', '1') 270 | 0 271 | memc_behavior_get('MEMCACHED_BEHAVIOR_CACHE_LOOKUPS') 272 | 1 273 | memc_behavior_set('MEMCACHED_BEHAVIOR_CACHE_LOOKUPS', @behavior) 274 | 0 275 | memc_behavior_set('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS', '1') 276 | 0 277 | memc_behavior_get('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS') 278 | 1 279 | memc_behavior_set('MEMCACHED_BEHAVIOR_BUFFER_REQUESTS', @behavior) 280 | 0 281 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_DEFAULT' ) 282 | 0 283 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 284 | MEMCACHED_HASH_DEFAULT 285 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_MD5' ) 286 | 0 287 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 288 | MEMCACHED_HASH_MD5 289 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_CRC' ) 290 | 0 291 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 292 | MEMCACHED_HASH_CRC 293 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_FNV1_64' ) 294 | 0 295 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 296 | MEMCACHED_HASH_FNV1_64 297 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_FNV1A_64' ) 298 | 0 299 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 300 | MEMCACHED_HASH_FNV1A_64 301 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_FNV1_32' ) 302 | 0 303 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 304 | MEMCACHED_HASH_FNV1_32 305 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_FNV1A_32' ) 306 | 0 307 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 308 | MEMCACHED_HASH_FNV1A_32 309 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_JENKINS' ) 310 | 0 311 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 312 | MEMCACHED_HASH_JENKINS 313 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_HSIEH' ) 314 | 0 315 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 316 | MEMCACHED_HASH_JENKINS 317 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH','MEMCACHED_HASH_MURMUR' ) 318 | 0 319 | memc_behavior_get('MEMCACHED_BEHAVIOR_HASH') 320 | MEMCACHED_HASH_MURMUR 321 | memc_behavior_set('MEMCACHED_BEHAVIOR_HASH', @preserve_behavior) 322 | 0 323 | memc_behavior_set('MEMCACHED_BEHAVIOR_DISTRIBUTION', 'MEMCACHED_DISTRIBUTION_MODULA') 324 | 0 325 | memc_behavior_get('MEMCACHED_BEHAVIOR_DISTRIBUTION') 326 | MEMCACHED_DISTRIBUTION_MODULA 327 | memc_behavior_set('MEMCACHED_BEHAVIOR_DISTRIBUTION', 'MEMCACHED_DISTRIBUTION_CONSISTENT') 328 | 0 329 | memc_behavior_get('MEMCACHED_BEHAVIOR_DISTRIBUTION') 330 | MEMCACHED_DISTRIBUTION_CONSISTENT 331 | memc_behavior_set('MEMCACHED_BEHAVIOR_DISTRIBUTION', 'MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA') 332 | 0 333 | memc_behavior_get('MEMCACHED_BEHAVIOR_DISTRIBUTION') 334 | MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA 335 | memc_behavior_set('MEMCACHED_BEHAVIOR_DISTRIBUTION', @preserve_dist) 336 | 0 337 | @size 338 | 81660 339 | memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE', 60000) 340 | 0 341 | memc_behavior_get('MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE') 342 | 65328 343 | memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE', @size) 344 | 0 345 | @size 346 | 81660 347 | memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE', 120000) 348 | 0 349 | memc_behavior_get('MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE') 350 | 130656 351 | memc_behavior_set('MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE', @size) 352 | 0 353 | @size 354 | 1000 355 | memc_behavior_set('MEMCACHED_BEHAVIOR_POLL_TIMEOUT', 100) 356 | 0 357 | memc_behavior_get('MEMCACHED_BEHAVIOR_POLL_TIMEOUT') 358 | 100 359 | memc_behavior_set('MEMCACHED_BEHAVIOR_POLL_TIMEOUT', @size) 360 | 0 361 | @size 362 | 0 363 | memc_behavior_set('MEMCACHED_BEHAVIOR_RETRY_TIMEOUT', 5) 364 | 0 365 | memc_behavior_get('MEMCACHED_BEHAVIOR_RETRY_TIMEOUT') 366 | 5 367 | memc_behavior_set('MEMCACHED_BEHAVIOR_RETRY_TIMEOUT', @size) 368 | 0 369 | @size 370 | 500 371 | memc_behavior_set('MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK', 5) 372 | 0 373 | memc_behavior_get('MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK') 374 | 5 375 | memc_behavior_set('MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK', @size) 376 | 0 377 | @size 378 | 66560 379 | memc_behavior_set('MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK', 5) 380 | 0 381 | memc_behavior_get('MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK') 382 | 5 383 | memc_behavior_set('MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK', @size) 384 | 0 385 | memc_stat_get_keys() 386 | pid\nuptime\ntime\nversion\npointer_size\nrusage_user\nrusage_system\ncurr_items\ntotal_items\nbytes\ncurr_connections\ntotal_connections\nconnection_structures\ncmd_get\ncmd_set\nget_hits\nget_misses\nevictions\nbytes_read\nbytes_written\nlimit_maxbytes\nthreads\n 387 | if (memc_stats('localhost') IS NOT NULL, 'true', 'false') 388 | true 389 | memc_get('a') 390 | NULL 391 | memc_get('b') 392 | NULL 393 | memc_get('a') 394 | a:xxx 395 | memc_get('a') 396 | NULL 397 | memc_get('a') 398 | NULL 399 | memc_delete('a') 400 | 1 401 | memc_delete('b') 402 | 1 403 | memc_get('a') 404 | NULL 405 | --------------------------------------------------------------------------------