mysql2 0.3.11-x86-mingw32 → 0.3.18-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +280 -75
  3. data/ext/mysql2/client.c +721 -206
  4. data/ext/mysql2/client.h +26 -12
  5. data/ext/mysql2/extconf.rb +120 -16
  6. data/ext/mysql2/infile.c +122 -0
  7. data/ext/mysql2/infile.h +1 -0
  8. data/ext/mysql2/mysql2_ext.h +7 -4
  9. data/ext/mysql2/mysql_enc_name_to_ruby.h +168 -0
  10. data/ext/mysql2/mysql_enc_to_ruby.h +246 -0
  11. data/ext/mysql2/result.c +230 -112
  12. data/ext/mysql2/result.h +4 -1
  13. data/lib/mysql2.rb +46 -3
  14. data/lib/mysql2/1.8/mysql2.so +0 -0
  15. data/lib/mysql2/1.9/mysql2.so +0 -0
  16. data/lib/mysql2/2.0/mysql2.so +0 -0
  17. data/lib/mysql2/2.1/mysql2.so +0 -0
  18. data/lib/mysql2/client.rb +48 -200
  19. data/lib/mysql2/console.rb +5 -0
  20. data/lib/mysql2/em.rb +22 -3
  21. data/lib/mysql2/error.rb +71 -6
  22. data/lib/mysql2/mysql2.rb +2 -0
  23. data/lib/mysql2/version.rb +1 -1
  24. data/spec/configuration.yml.example +17 -0
  25. data/spec/em/em_spec.rb +90 -5
  26. data/spec/my.cnf.example +9 -0
  27. data/spec/mysql2/client_spec.rb +501 -69
  28. data/spec/mysql2/error_spec.rb +58 -44
  29. data/spec/mysql2/result_spec.rb +191 -74
  30. data/spec/spec_helper.rb +23 -3
  31. data/spec/test_data +1 -0
  32. data/support/libmysql.def +219 -0
  33. data/support/mysql_enc_to_ruby.rb +82 -0
  34. data/support/ruby_enc_to_mysql.rb +61 -0
  35. data/vendor/README +654 -0
  36. data/vendor/libmysql.dll +0 -0
  37. metadata +86 -221
  38. data/.gitignore +0 -12
  39. data/.rspec +0 -3
  40. data/.rvmrc +0 -1
  41. data/.travis.yml +0 -7
  42. data/CHANGELOG.md +0 -244
  43. data/Gemfile +0 -3
  44. data/MIT-LICENSE +0 -20
  45. data/Rakefile +0 -5
  46. data/benchmark/active_record.rb +0 -51
  47. data/benchmark/active_record_threaded.rb +0 -42
  48. data/benchmark/allocations.rb +0 -33
  49. data/benchmark/escape.rb +0 -36
  50. data/benchmark/query_with_mysql_casting.rb +0 -80
  51. data/benchmark/query_without_mysql_casting.rb +0 -56
  52. data/benchmark/sequel.rb +0 -37
  53. data/benchmark/setup_db.rb +0 -119
  54. data/benchmark/threaded.rb +0 -44
  55. data/mysql2.gemspec +0 -29
  56. data/tasks/benchmarks.rake +0 -20
  57. data/tasks/compile.rake +0 -71
  58. data/tasks/rspec.rake +0 -16
  59. data/tasks/vendor_mysql.rake +0 -40
data/ext/mysql2/client.h CHANGED
@@ -1,24 +1,30 @@
1
1
  #ifndef MYSQL2_CLIENT_H
2
2
  #define MYSQL2_CLIENT_H
3
3
 
4
+ #ifndef HAVE_RB_THREAD_CALL_WITHOUT_GVL
5
+ #ifdef HAVE_RB_THREAD_BLOCKING_REGION
6
+
7
+ /* emulate rb_thread_call_without_gvl with rb_thread_blocking_region */
8
+ #define rb_thread_call_without_gvl(func, data1, ubf, data2) \
9
+ rb_thread_blocking_region((rb_blocking_function_t *)func, data1, ubf, data2)
10
+
11
+ #else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
4
12
  /*
5
- * partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
13
+ * partial emulation of the 2.0 rb_thread_call_without_gvl under 1.8,
6
14
  * this is enough for dealing with blocking I/O functions in the
7
15
  * presence of threads.
8
16
  */
9
- #ifndef HAVE_RB_THREAD_BLOCKING_REGION
10
17
 
11
18
  #include <rubysig.h>
12
19
  #define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
13
20
  typedef void rb_unblock_function_t(void *);
14
- typedef VALUE rb_blocking_function_t(void *);
15
- static VALUE
16
- rb_thread_blocking_region(
17
- rb_blocking_function_t *func, void *data1,
21
+ static void *
22
+ rb_thread_call_without_gvl(
23
+ void *(*func)(void *), void *data1,
18
24
  RB_MYSQL_UNUSED rb_unblock_function_t *ubf,
19
25
  RB_MYSQL_UNUSED void *data2)
20
26
  {
21
- VALUE rv;
27
+ void *rv;
22
28
 
23
29
  TRAP_BEG;
24
30
  rv = func(data1);
@@ -28,15 +34,23 @@ rb_thread_blocking_region(
28
34
  }
29
35
 
30
36
  #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
31
-
32
- void init_mysql2_client();
37
+ #endif /* ! HAVE_RB_THREAD_CALL_WITHOUT_GVL */
33
38
 
34
39
  typedef struct {
35
40
  VALUE encoding;
36
- int active;
41
+ VALUE active_thread; /* rb_thread_current() or Qnil */
42
+ long server_version;
37
43
  int reconnect_enabled;
38
- int closed;
44
+ unsigned int connect_timeout;
45
+ int active;
46
+ int connected;
47
+ int initialized;
48
+ int refcount;
49
+ int freed;
39
50
  MYSQL *client;
40
51
  } mysql_client_wrapper;
41
52
 
42
- #endif
53
+ void init_mysql2_client();
54
+ void decr_mysql2_client(mysql_client_wrapper *wrapper);
55
+
56
+ #endif
@@ -5,9 +5,14 @@ def asplode lib
5
5
  abort "-----\n#{lib} is missing. please check your installation of mysql and try again.\n-----"
6
6
  end
7
7
 
8
+ # 2.0-only
9
+ have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
10
+
8
11
  # 1.9-only
9
12
  have_func('rb_thread_blocking_region')
10
13
  have_func('rb_wait_for_single_fd')
14
+ have_func('rb_hash_dup')
15
+ have_func('rb_intern3')
11
16
 
12
17
  # borrowed from mysqlplus
13
18
  # http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
@@ -15,30 +20,50 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
15
20
  /opt
16
21
  /opt/local
17
22
  /opt/local/mysql
18
- /opt/local/lib/mysql5
23
+ /opt/local/lib/mysql5*
19
24
  /usr
25
+ /usr/mysql
20
26
  /usr/local
21
27
  /usr/local/mysql
22
28
  /usr/local/mysql-*
23
- /usr/local/lib/mysql5
29
+ /usr/local/lib/mysql5*
24
30
  ].map{|dir| "#{dir}/bin" }
25
31
 
26
32
  GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
27
33
 
28
- if RUBY_PLATFORM =~ /mswin|mingw/
29
- inc, lib = dir_config('mysql')
30
- exit 1 unless have_library("libmysql")
31
- elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
34
+ # If the user has provided a --with-mysql-dir argument, we must respect it or fail.
35
+ inc, lib = dir_config('mysql')
36
+ if inc && lib
37
+ # Ruby versions not incorporating the mkmf fix at
38
+ # https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
39
+ # do not properly search for lib directories, and must be corrected
40
+ unless lib && lib[-3, 3] == 'lib'
41
+ @libdir_basename = 'lib'
42
+ inc, lib = dir_config('mysql')
43
+ end
44
+ abort "-----\nCannot find include dir(s) #{inc}\n-----" unless inc && inc.split(File::PATH_SEPARATOR).any?{|dir| File.directory?(dir)}
45
+ abort "-----\nCannot find library dir(s) #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any?{|dir| File.directory?(dir)}
46
+ warn "-----\nUsing --with-mysql-dir=#{File.dirname inc}\n-----"
47
+ rpath_dir = lib
48
+ elsif mc = (with_config('mysql-config') || Dir[GLOB].first)
49
+ # If the user has provided a --with-mysql-config argument, we must respect it or fail.
50
+ # If the user gave --with-mysql-config with no argument means we should try to find it.
32
51
  mc = Dir[GLOB].first if mc == true
33
- cflags = `#{mc} --cflags`.chomp
52
+ abort "-----\nCannot find mysql_config at #{mc}\n-----" unless mc && File.exists?(mc)
53
+ abort "-----\nCannot execute mysql_config at #{mc}\n-----" unless File.executable?(mc)
54
+ warn "-----\nUsing mysql_config at #{mc}\n-----"
55
+ ver = `#{mc} --version`.chomp.to_f
56
+ includes = `#{mc} --include`.chomp
34
57
  exit 1 if $? != 0
35
58
  libs = `#{mc} --libs_r`.chomp
36
- if libs.empty?
59
+ # MySQL 5.5 and above already have re-entrant code in libmysqlclient (no _r).
60
+ if ver >= 5.5 || libs.empty?
37
61
  libs = `#{mc} --libs`.chomp
38
62
  end
39
63
  exit 1 if $? != 0
40
- $CPPFLAGS += ' ' + cflags
64
+ $INCFLAGS += ' ' + includes
41
65
  $libs = libs + " " + $libs
66
+ rpath_dir = libs
42
67
  else
43
68
  inc, lib = dir_config('mysql', '/usr/local')
44
69
  libs = ['m', 'z', 'socket', 'nsl', 'mygcc']
@@ -46,11 +71,12 @@ else
46
71
  exit 1 if libs.empty?
47
72
  have_library(libs.shift)
48
73
  end
74
+ rpath_dir = lib
49
75
  end
50
76
 
51
- if have_header('mysql.h') then
77
+ if have_header('mysql.h')
52
78
  prefix = nil
53
- elsif have_header('mysql/mysql.h') then
79
+ elsif have_header('mysql/mysql.h')
54
80
  prefix = 'mysql'
55
81
  else
56
82
  asplode 'mysql.h'
@@ -61,13 +87,91 @@ end
61
87
  asplode h unless have_header h
62
88
  end
63
89
 
64
- unless RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /sparc/
65
- $CFLAGS << ' -Wall -funroll-loops'
90
+ # These gcc style flags are also supported by clang and xcode compilers,
91
+ # so we'll use a does-it-work test instead of an is-it-gcc test.
92
+ gcc_flags = ' -Wall -funroll-loops'
93
+ if try_link('int main() {return 0;}', gcc_flags)
94
+ $CFLAGS << gcc_flags
66
95
  end
67
- # $CFLAGS << ' -O0 -ggdb3 -Wextra'
68
96
 
69
- if hard_mysql_path = $libs[%r{-L(/[^ ]+)}, 1]
70
- $LDFLAGS << " -Wl,-rpath,#{hard_mysql_path}"
97
+ if RUBY_PLATFORM =~ /mswin|mingw/
98
+ # Build libmysql.a interface link library
99
+ require 'rake'
100
+
101
+ # Build libmysql.a interface link library
102
+ # Use rake to rebuild only if these files change
103
+ deffile = File.expand_path('../../../support/libmysql.def', __FILE__)
104
+ libfile = File.expand_path(File.join(rpath_dir, 'libmysql.lib'))
105
+ file 'libmysql.a' => [deffile, libfile] do |t|
106
+ when_writing 'building libmysql.a' do
107
+ # Ruby kindly shows us where dllwrap is, but that tool does more than we want.
108
+ # Maybe in the future Ruby could provide RbConfig::CONFIG['DLLTOOL'] directly.
109
+ dlltool = RbConfig::CONFIG['DLLWRAP'].gsub('dllwrap', 'dlltool')
110
+ sh dlltool, '--kill-at',
111
+ '--dllname', 'libmysql.dll',
112
+ '--output-lib', 'libmysql.a',
113
+ '--input-def', deffile, libfile
114
+ end
115
+ end
116
+
117
+ Rake::Task['libmysql.a'].invoke
118
+ $LOCAL_LIBS << ' ' << 'libmysql.a'
119
+
120
+ # Make sure the generated interface library works (if cross-compiling, trust without verifying)
121
+ unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
122
+ abort "-----\nCannot find libmysql.a\n----" unless have_library('libmysql')
123
+ abort "-----\nCannot link to libmysql.a (my_init)\n----" unless have_func('my_init')
124
+ end
125
+
126
+ # Vendor libmysql.dll
127
+ vendordir = File.expand_path('../../../vendor/', __FILE__)
128
+ directory vendordir
129
+
130
+ vendordll = File.join(vendordir, 'libmysql.dll')
131
+ dllfile = File.expand_path(File.join(rpath_dir, 'libmysql.dll'))
132
+ file vendordll => [dllfile, vendordir] do |t|
133
+ when_writing 'copying libmysql.dll' do
134
+ cp dllfile, vendordll
135
+ end
136
+ end
137
+
138
+ # Copy libmysql.dll to the local vendor directory by default
139
+ if arg_config('--no-vendor-libmysql')
140
+ # Fine, don't.
141
+ puts "--no-vendor-libmysql"
142
+ else # Default: arg_config('--vendor-libmysql')
143
+ # Let's do it!
144
+ Rake::Task[vendordll].invoke
145
+ end
146
+ else
147
+ case explicit_rpath = with_config('mysql-rpath')
148
+ when true
149
+ abort "-----\nOption --with-mysql-rpath must have an argument\n-----"
150
+ when false
151
+ warn "-----\nOption --with-mysql-rpath has been disabled at your request\n-----"
152
+ when String
153
+ # The user gave us a value so use it
154
+ rpath_flags = " -Wl,-rpath,#{explicit_rpath}"
155
+ warn "-----\nSetting mysql rpath to #{explicit_rpath}\n-----"
156
+ $LDFLAGS << rpath_flags
157
+ else
158
+ if libdir = rpath_dir[%r{(-L)?(/[^ ]+)}, 2]
159
+ rpath_flags = " -Wl,-rpath,#{libdir}"
160
+ if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', rpath_flags)
161
+ # Usually Ruby sets RPATHFLAG the right way for each system, but not on OS X.
162
+ warn "-----\nSetting rpath to #{libdir}\n-----"
163
+ $LDFLAGS << rpath_flags
164
+ else
165
+ if RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
166
+ # If we got here because try_link failed, warn the user
167
+ warn "-----\nDon't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load\n-----"
168
+ end
169
+ # Make sure that LIBPATH gets set if we didn't explicitly set the rpath.
170
+ warn "-----\nSetting libpath to #{libdir}\n-----"
171
+ $LIBPATH << libdir unless $LIBPATH.include?(libdir)
172
+ end
173
+ end
174
+ end
71
175
  end
72
176
 
73
177
  create_makefile('mysql2/mysql2')
@@ -0,0 +1,122 @@
1
+ #include <mysql2_ext.h>
2
+
3
+ #include <errno.h>
4
+ #ifndef _MSC_VER
5
+ #include <unistd.h>
6
+ #endif
7
+ #include <fcntl.h>
8
+
9
+ #define ERROR_LEN 1024
10
+ typedef struct
11
+ {
12
+ int fd;
13
+ char *filename;
14
+ char error[ERROR_LEN];
15
+ mysql_client_wrapper *wrapper;
16
+ } mysql2_local_infile_data;
17
+
18
+ /* MySQL calls this function when a user begins a LOAD DATA LOCAL INFILE query.
19
+ *
20
+ * Allocate a data struct and pass it back through the data pointer.
21
+ *
22
+ * Returns:
23
+ * 0 on success
24
+ * 1 on error
25
+ */
26
+ static int
27
+ mysql2_local_infile_init(void **ptr, const char *filename, void *userdata)
28
+ {
29
+ mysql2_local_infile_data *data = malloc(sizeof(mysql2_local_infile_data));
30
+ if (!data) return 1;
31
+
32
+ *ptr = data;
33
+ data->error[0] = 0;
34
+ data->wrapper = userdata;
35
+
36
+ data->filename = strdup(filename);
37
+ if (!data->filename) {
38
+ snprintf(data->error, ERROR_LEN, "%s: %s", strerror(errno), filename);
39
+ return 1;
40
+ }
41
+
42
+ data->fd = open(filename, O_RDONLY);
43
+ if (data->fd < 0) {
44
+ snprintf(data->error, ERROR_LEN, "%s: %s", strerror(errno), filename);
45
+ return 1;
46
+ }
47
+
48
+ return 0;
49
+ }
50
+
51
+ /* MySQL calls this function to read data from the local file.
52
+ *
53
+ * Returns:
54
+ * > 0 number of bytes read
55
+ * == 0 end of file
56
+ * < 0 error
57
+ */
58
+ static int
59
+ mysql2_local_infile_read(void *ptr, char *buf, uint buf_len)
60
+ {
61
+ int count;
62
+ mysql2_local_infile_data *data = (mysql2_local_infile_data *)ptr;
63
+
64
+ count = (int)read(data->fd, buf, buf_len);
65
+ if (count < 0) {
66
+ snprintf(data->error, ERROR_LEN, "%s: %s", strerror(errno), data->filename);
67
+ }
68
+
69
+ return count;
70
+ }
71
+
72
+ /* MySQL calls this function when we're done with the LOCAL INFILE query.
73
+ *
74
+ * ptr will be null if the init function failed.
75
+ */
76
+ static void
77
+ mysql2_local_infile_end(void *ptr)
78
+ {
79
+ mysql2_local_infile_data *data = (mysql2_local_infile_data *)ptr;
80
+ if (data) {
81
+ if (data->fd >= 0)
82
+ close(data->fd);
83
+ if (data->filename)
84
+ free(data->filename);
85
+ free(data);
86
+ }
87
+ }
88
+
89
+ /* MySQL calls this function if any of the functions above returned an error.
90
+ *
91
+ * This function is called even if init failed, with whatever ptr value
92
+ * init has set, regardless of the return value of the init function.
93
+ *
94
+ * Returns:
95
+ * Error message number (see http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html)
96
+ */
97
+ static int
98
+ mysql2_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
99
+ {
100
+ mysql2_local_infile_data *data = (mysql2_local_infile_data *) ptr;
101
+
102
+ if (data) {
103
+ snprintf(error_msg, error_msg_len, "%s", data->error);
104
+ return CR_UNKNOWN_ERROR;
105
+ }
106
+
107
+ snprintf(error_msg, error_msg_len, "Out of memory");
108
+ return CR_OUT_OF_MEMORY;
109
+ }
110
+
111
+ /* Tell MySQL Client to use our own local_infile functions.
112
+ * This is both due to bugginess in the default handlers,
113
+ * and to improve the Rubyness of the handlers here.
114
+ */
115
+ void mysql2_set_local_infile(MYSQL *mysql, void *userdata)
116
+ {
117
+ mysql_set_local_infile_handler(mysql,
118
+ mysql2_local_infile_init,
119
+ mysql2_local_infile_read,
120
+ mysql2_local_infile_end,
121
+ mysql2_local_infile_error, userdata);
122
+ }
@@ -0,0 +1 @@
1
+ void mysql2_set_local_infile(MYSQL *mysql, void *userdata);
@@ -1,12 +1,11 @@
1
1
  #ifndef MYSQL2_EXT
2
2
  #define MYSQL2_EXT
3
3
 
4
- // tell rbx not to use it's caching compat layer
5
- // by doing this we're making a promize to RBX that
6
- // we'll never modify the pointers we get back from RSTRING_PTR
4
+ /* tell rbx not to use it's caching compat layer
5
+ by doing this we're making a promise to RBX that
6
+ we'll never modify the pointers we get back from RSTRING_PTR */
7
7
  #define RSTRING_NOT_MODIFIED
8
8
  #include <ruby.h>
9
- #include <fcntl.h>
10
9
 
11
10
  #ifndef HAVE_UINT
12
11
  #define HAVE_UINT
@@ -29,6 +28,9 @@ typedef unsigned int uint;
29
28
  #ifdef HAVE_RUBY_ENCODING_H
30
29
  #include <ruby/encoding.h>
31
30
  #endif
31
+ #ifdef HAVE_RUBY_THREAD_H
32
+ #include <ruby/thread.h>
33
+ #endif
32
34
 
33
35
  #if defined(__GNUC__) && (__GNUC__ >= 3)
34
36
  #define RB_MYSQL_UNUSED __attribute__ ((unused))
@@ -38,5 +40,6 @@ typedef unsigned int uint;
38
40
 
39
41
  #include <client.h>
40
42
  #include <result.h>
43
+ #include <infile.h>
41
44
 
42
45
  #endif
@@ -0,0 +1,168 @@
1
+ /* C code produced by gperf version 3.0.3 */
2
+ /* Command-line: gperf */
3
+ /* Computed positions: -k'1,3,$' */
4
+
5
+ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
6
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
7
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
8
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
9
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
10
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
11
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
12
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
13
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
14
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
15
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
16
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
17
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
18
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
19
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
20
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
21
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
22
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
23
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
24
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
25
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
26
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
27
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
28
+ /* The character set is not based on ISO-646. */
29
+ error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
30
+ #endif
31
+
32
+ struct mysql2_mysql_enc_name_to_rb_map { const char *name; const char *rb_name; };
33
+ /* maximum key range = 66, duplicates = 0 */
34
+
35
+ #ifdef __GNUC__
36
+ __inline
37
+ #else
38
+ #ifdef __cplusplus
39
+ inline
40
+ #endif
41
+ #endif
42
+ static unsigned int
43
+ mysql2_mysql_enc_name_to_rb_hash (str, len)
44
+ register const char *str;
45
+ register unsigned int len;
46
+ {
47
+ static const unsigned char asso_values[] =
48
+ {
49
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
50
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
51
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
52
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
53
+ 69, 69, 69, 69, 69, 69, 69, 69, 40, 5,
54
+ 0, 69, 0, 40, 25, 20, 10, 55, 69, 69,
55
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
56
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
57
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
58
+ 69, 69, 69, 69, 69, 69, 69, 35, 5, 0,
59
+ 10, 0, 20, 0, 5, 5, 69, 0, 10, 15,
60
+ 0, 0, 69, 69, 25, 5, 5, 0, 69, 30,
61
+ 69, 0, 69, 69, 69, 69, 69, 69, 69, 69,
62
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
63
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
64
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
65
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
66
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
67
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
68
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
70
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
71
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
72
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
73
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
74
+ 69, 69, 69, 69, 69, 69
75
+ };
76
+ return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
77
+ }
78
+
79
+ #ifdef __GNUC__
80
+ __inline
81
+ #ifdef __GNUC_STDC_INLINE__
82
+ __attribute__ ((__gnu_inline__))
83
+ #endif
84
+ #endif
85
+ const struct mysql2_mysql_enc_name_to_rb_map *
86
+ mysql2_mysql_enc_name_to_rb (str, len)
87
+ register const char *str;
88
+ register unsigned int len;
89
+ {
90
+ enum
91
+ {
92
+ TOTAL_KEYWORDS = 39,
93
+ MIN_WORD_LENGTH = 3,
94
+ MAX_WORD_LENGTH = 8,
95
+ MIN_HASH_VALUE = 3,
96
+ MAX_HASH_VALUE = 68
97
+ };
98
+
99
+ static const struct mysql2_mysql_enc_name_to_rb_map wordlist[] =
100
+ {
101
+ {""}, {""}, {""},
102
+ {"gbk", "GBK"},
103
+ {""},
104
+ {"greek", "ISO-8859-7"},
105
+ {"gb2312", "GB2312"},
106
+ {"keybcs2", NULL},
107
+ {""},
108
+ {"ucs2", "UTF-16BE"},
109
+ {"koi8u", "KOI8-R"},
110
+ {"binary", "ASCII-8BIT"},
111
+ {"eucjpms", "eucJP-ms"},
112
+ {""},
113
+ {"ujis", "eucJP-ms"},
114
+ {"cp852", "CP852"},
115
+ {"cp1251", "Windows-1251"},
116
+ {"geostd8", NULL},
117
+ {""},
118
+ {"sjis", "Shift_JIS"},
119
+ {"macce", "macCentEuro"},
120
+ {"latin2", "ISO-8859-2"},
121
+ {""},
122
+ {"macroman", "macRoman"},
123
+ {"dec8", NULL},
124
+ {"utf32", "UTF-32"},
125
+ {"latin1", "ISO-8859-1"},
126
+ {"utf8mb4", "UTF-8"},
127
+ {"hp8", NULL},
128
+ {"swe7", NULL},
129
+ {"euckr", "EUC-KR"},
130
+ {"cp1257", "Windows-1257"},
131
+ {""}, {""},
132
+ {"utf8", "UTF-8"},
133
+ {"koi8r", "KOI8-R"},
134
+ {"cp1256", "Windows-1256"},
135
+ {""}, {""}, {""},
136
+ {"cp866", "IBM866"},
137
+ {"latin7", "ISO-8859-13"},
138
+ {""}, {""}, {""},
139
+ {"ascii", "US-ASCII"},
140
+ {"hebrew", "ISO-8859-8"},
141
+ {""}, {""},
142
+ {"big5", "Big5"},
143
+ {"utf16", "UTF-16"},
144
+ {"cp1250", "Windows-1250"},
145
+ {""}, {""}, {""},
146
+ {"cp850", "CP850"},
147
+ {"tis620", "TIS-620"},
148
+ {""}, {""}, {""},
149
+ {"cp932", "Windows-31J"},
150
+ {"latin5", "ISO-8859-9"},
151
+ {""}, {""}, {""}, {""}, {""}, {""},
152
+ {"armscii8", NULL}
153
+ };
154
+
155
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
156
+ {
157
+ register int key = mysql2_mysql_enc_name_to_rb_hash (str, len);
158
+
159
+ if (key <= MAX_HASH_VALUE && key >= 0)
160
+ {
161
+ register const char *s = wordlist[key].name;
162
+
163
+ if (*str == *s && !strcmp (str + 1, s + 1))
164
+ return &wordlist[key];
165
+ }
166
+ }
167
+ return 0;
168
+ }