mysql2 0.3.17 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +34 -19
- data/ext/mysql2/client.c +64 -61
- data/ext/mysql2/extconf.rb +99 -35
- data/ext/mysql2/result.c +51 -65
- data/ext/mysql2/result.h +1 -2
- data/lib/mysql2/client.rb +4 -0
- data/lib/mysql2/em.rb +10 -1
- data/lib/mysql2/error.rb +1 -1
- data/lib/mysql2/version.rb +1 -1
- data/lib/mysql2.rb +23 -0
- data/spec/em/em_spec.rb +21 -0
- data/spec/mysql2/client_spec.rb +52 -28
- data/spec/mysql2/result_spec.rb +16 -7
- data/support/libmysql.def +219 -0
- metadata +6 -19
- data/MIT-LICENSE +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6261e72195a2e1281c59ad35c44fe9edefc69241
|
4
|
+
data.tar.gz: 5dd5b66d3bc11fcd978d4a2d491ac47e3a005510
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a1dc5ee4f77d51c5042b5eb8153a18c2d199506c5514a5064c818fe5f800fcbd32dae5a73c29eec268b8f96e1f31c358f87e9306e50fbee7836f7a3a88c5393
|
7
|
+
data.tar.gz: fa5d2a4b7815f4b834598e647e0aecb328e8997638ea7c73ad313cfa6b9eba5099a329c402071fb08a8a09b99e5a99784191bf7ff5722f0707a69a9c5d041d62
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Brian Lopez
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Mysql2 - A modern, simple and very fast MySQL library for Ruby - binding to libmysql
|
2
2
|
|
3
|
-
[](https://travis-ci.org/brianmario/mysql2)
|
4
|
+
Appveyor CI [](https://ci.appveyor.com/project/sodabrew/mysql2)
|
4
5
|
|
5
6
|
The Mysql2 gem is meant to serve the extremely common use-case of connecting, querying and iterating on results.
|
6
7
|
Some database libraries out there serve as direct 1:1 mappings of the already complex C APIs available.
|
@@ -15,12 +16,16 @@ The API consists of two classes:
|
|
15
16
|
`Mysql2::Result` - returned from issuing a #query on the connection. It includes Enumerable.
|
16
17
|
|
17
18
|
## Installing
|
18
|
-
###
|
19
|
+
### General Instructions
|
19
20
|
``` sh
|
20
21
|
gem install mysql2
|
21
22
|
```
|
22
23
|
|
23
|
-
This gem links against MySQL's `libmysqlclient`
|
24
|
+
This gem links against MySQL's `libmysqlclient` library or `Connector/C`
|
25
|
+
library, and compatible alternatives such as MariaDB.
|
26
|
+
You may need to install a package such as `libmysqlclient-dev`, `mysql-devel`,
|
27
|
+
or other appropriate package for your system. See below for system-specific
|
28
|
+
instructions.
|
24
29
|
|
25
30
|
By default, the mysql2 gem will try to find a copy of MySQL in this order:
|
26
31
|
|
@@ -51,25 +56,35 @@ This may be needed if you deploy to a system where these libraries
|
|
51
56
|
are located somewhere different than on your build system.
|
52
57
|
This overrides any rpath calculated by default or by the options above.
|
53
58
|
|
54
|
-
###
|
55
|
-
|
56
|
-
|
59
|
+
### Linux and other Unixes
|
60
|
+
|
61
|
+
You may need to install a package such as `libmysqlclient-dev` or `mysql-devel`;
|
62
|
+
refer to your distribution's package guide to find the particular package.
|
63
|
+
The most common issue we see is a user who has the library file `libmysqlclient.so` but is
|
64
|
+
missing the header file `mysql.h` -- double check that you have the _-dev_ packages installed.
|
57
65
|
|
58
|
-
|
59
|
-
you can use that. If not, you will need to either copy the MySQL directory from your server, or else
|
60
|
-
obtain a copy of the MySQL C connector: http://dev.mysql.com/downloads/connector/c/
|
66
|
+
### Mac OS X
|
61
67
|
|
62
|
-
|
68
|
+
You may use MacPorts, Homebrew, or a native MySQL installer package. The most
|
69
|
+
common paths will be automatically searched. If you want to select a specific
|
70
|
+
MySQL directory, use the `--with-mysql-dir` or `--with-mysql-config` options above.
|
71
|
+
|
72
|
+
### Windows
|
73
|
+
Make sure that you have Ruby and the DevKit compilers installed. We recommend
|
74
|
+
the [Ruby Installer](http://rubyinstaller.org) distribution.
|
63
75
|
|
64
|
-
|
65
|
-
|
66
|
-
|
76
|
+
By default, the mysql2 gem will download and use MySQL Connector/C from
|
77
|
+
mysql.com. If you prefer to use a local installation of Connector/C, add the
|
78
|
+
flag `--with-mysql-dir=c:/mysql-connector-c-x-y-z` (_this path may use forward slashes_).
|
67
79
|
|
68
|
-
|
80
|
+
By default, the `libmysql.dll` library will be copied into the mysql2 gem
|
81
|
+
directory. To prevent this, add the flag `--no-vendor-libmysql`. The mysql2 gem
|
82
|
+
will search for `libmysql.dll` in the following paths, in order:
|
69
83
|
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
* Environment variable `RUBY_MYSQL2_LIBMYSQL_DLL=C:\path\to\libmysql.dll`
|
85
|
+
(_note the Windows-style backslashes_).
|
86
|
+
* In the mysql2 gem's own directory `vendor/libmysql.dll`
|
87
|
+
* In the system's default library search paths.
|
73
88
|
|
74
89
|
## Usage
|
75
90
|
|
@@ -422,13 +437,13 @@ As for field values themselves, I'm workin on it - but expect that soon.
|
|
422
437
|
|
423
438
|
This gem is tested with the following Ruby versions on Linux and Mac OS X:
|
424
439
|
|
425
|
-
* Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.x (ongoing patch releases)
|
440
|
+
* Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.x, 2.2.x (ongoing patch releases)
|
426
441
|
* Ruby Enterprise Edition (based on MRI 1.8.7)
|
427
442
|
* Rubinius 2.x
|
428
443
|
|
429
444
|
This gem is tested with the following MySQL and MariaDB versions:
|
430
445
|
|
431
|
-
* MySQL 5.0, 5.1, 5.5, 5.6
|
446
|
+
* MySQL 5.0, 5.1, 5.5, 5.6, 5.7
|
432
447
|
* MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
|
433
448
|
* MariaDB 5.5, 10.0
|
434
449
|
|
data/ext/mysql2/client.c
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
VALUE cMysql2Client;
|
18
18
|
extern VALUE mMysql2, cMysql2Error;
|
19
|
-
static VALUE sym_id, sym_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
|
19
|
+
static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
|
20
20
|
static ID intern_merge, intern_merge_bang, intern_error_number_eql, intern_sql_state_eql;
|
21
21
|
|
22
22
|
#ifndef HAVE_RB_HASH_DUP
|
@@ -182,23 +182,31 @@ static void *nogvl_connect(void *ptr) {
|
|
182
182
|
*/
|
183
183
|
static VALUE invalidate_fd(int clientfd)
|
184
184
|
{
|
185
|
-
#ifdef
|
185
|
+
#ifdef O_CLOEXEC
|
186
186
|
/* Atomically set CLOEXEC on the new FD in case another thread forks */
|
187
187
|
int sockfd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
188
|
-
if (sockfd < 0) {
|
189
|
-
/* Maybe SOCK_CLOEXEC is defined but not available on this kernel */
|
190
|
-
int sockfd = open("/dev/null", O_RDWR);
|
191
|
-
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
192
|
-
}
|
193
188
|
#else
|
194
|
-
/* Well we don't have
|
195
|
-
int sockfd =
|
196
|
-
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
189
|
+
/* Well we don't have O_CLOEXEC, trigger the fallback code below */
|
190
|
+
int sockfd = -1;
|
197
191
|
#endif
|
198
192
|
|
199
193
|
if (sockfd < 0) {
|
200
|
-
/*
|
201
|
-
*
|
194
|
+
/* Either O_CLOEXEC wasn't defined at compile time, or it was defined at
|
195
|
+
* compile time, but isn't available at run-time. So we'll just be quick
|
196
|
+
* about setting FD_CLOEXEC now.
|
197
|
+
*/
|
198
|
+
int flags;
|
199
|
+
sockfd = open("/dev/null", O_RDWR);
|
200
|
+
flags = fcntl(sockfd, F_GETFD);
|
201
|
+
/* Do the flags dance in case there are more defined flags in the future */
|
202
|
+
if (flags != -1) {
|
203
|
+
flags |= FD_CLOEXEC;
|
204
|
+
fcntl(sockfd, F_SETFD, flags);
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
if (sockfd < 0) {
|
209
|
+
/* Cannot raise here, because one or both of the following may be true:
|
202
210
|
* a) we have no GVL (in C Ruby)
|
203
211
|
* b) are running as a GC finalizer
|
204
212
|
*/
|
@@ -287,7 +295,7 @@ static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) {
|
|
287
295
|
oldLen = RSTRING_LEN(str);
|
288
296
|
newStr = xmalloc(oldLen*2+1);
|
289
297
|
|
290
|
-
newLen = mysql_escape_string((char *)newStr,
|
298
|
+
newLen = mysql_escape_string((char *)newStr, RSTRING_PTR(str), oldLen);
|
291
299
|
if (newLen == oldLen) {
|
292
300
|
/* no need to return a new ruby string if nothing changed */
|
293
301
|
xfree(newStr);
|
@@ -337,13 +345,13 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
|
|
337
345
|
VALUE rv;
|
338
346
|
GET_CLIENT(self);
|
339
347
|
|
340
|
-
args.host
|
341
|
-
args.unix_socket = NIL_P(socket)
|
342
|
-
args.port
|
343
|
-
args.user
|
344
|
-
args.passwd
|
345
|
-
args.db
|
346
|
-
args.mysql
|
348
|
+
args.host = NIL_P(host) ? NULL : StringValueCStr(host);
|
349
|
+
args.unix_socket = NIL_P(socket) ? NULL : StringValueCStr(socket);
|
350
|
+
args.port = NIL_P(port) ? 0 : NUM2INT(port);
|
351
|
+
args.user = NIL_P(user) ? NULL : StringValueCStr(user);
|
352
|
+
args.passwd = NIL_P(pass) ? NULL : StringValueCStr(pass);
|
353
|
+
args.db = NIL_P(database) ? NULL : StringValueCStr(database);
|
354
|
+
args.mysql = wrapper->client;
|
347
355
|
args.client_flag = NUM2ULONG(flags);
|
348
356
|
|
349
357
|
if (wrapper->connect_timeout)
|
@@ -438,7 +446,7 @@ static void *nogvl_do_result(void *ptr, char use_result) {
|
|
438
446
|
MYSQL_RES *result;
|
439
447
|
|
440
448
|
wrapper = (mysql_client_wrapper *)ptr;
|
441
|
-
if(use_result) {
|
449
|
+
if (use_result) {
|
442
450
|
result = mysql_use_result(wrapper->client);
|
443
451
|
} else {
|
444
452
|
result = mysql_store_result(wrapper->client);
|
@@ -483,7 +491,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
|
|
483
491
|
}
|
484
492
|
|
485
493
|
is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
|
486
|
-
if(is_streaming == Qtrue) {
|
494
|
+
if (is_streaming == Qtrue) {
|
487
495
|
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
|
488
496
|
} else {
|
489
497
|
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
|
@@ -669,7 +677,7 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
|
|
669
677
|
/* ensure the string is in the encoding the connection is expecting */
|
670
678
|
args.sql = rb_str_export_to_enc(args.sql, conn_enc);
|
671
679
|
#endif
|
672
|
-
args.sql_ptr =
|
680
|
+
args.sql_ptr = RSTRING_PTR(args.sql);
|
673
681
|
args.sql_len = RSTRING_LEN(args.sql);
|
674
682
|
|
675
683
|
/* see if this connection is still waiting on a result from a previous query */
|
@@ -736,9 +744,14 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) {
|
|
736
744
|
oldLen = RSTRING_LEN(str);
|
737
745
|
newStr = xmalloc(oldLen*2+1);
|
738
746
|
|
739
|
-
newLen = mysql_real_escape_string(wrapper->client, (char *)newStr,
|
747
|
+
newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen);
|
740
748
|
if (newLen == oldLen) {
|
741
749
|
/* no need to return a new ruby string if nothing changed */
|
750
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
751
|
+
if (default_internal_enc) {
|
752
|
+
str = rb_str_export_to_enc(str, default_internal_enc);
|
753
|
+
}
|
754
|
+
#endif
|
742
755
|
xfree(newStr);
|
743
756
|
return str;
|
744
757
|
} else {
|
@@ -800,17 +813,17 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
|
|
800
813
|
break;
|
801
814
|
|
802
815
|
case MYSQL_READ_DEFAULT_FILE:
|
803
|
-
charval = (const char *)
|
816
|
+
charval = (const char *)StringValueCStr(value);
|
804
817
|
retval = charval;
|
805
818
|
break;
|
806
819
|
|
807
820
|
case MYSQL_READ_DEFAULT_GROUP:
|
808
|
-
charval = (const char *)
|
821
|
+
charval = (const char *)StringValueCStr(value);
|
809
822
|
retval = charval;
|
810
823
|
break;
|
811
824
|
|
812
825
|
case MYSQL_INIT_COMMAND:
|
813
|
-
charval = (const char *)
|
826
|
+
charval = (const char *)StringValueCStr(value);
|
814
827
|
retval = charval;
|
815
828
|
break;
|
816
829
|
|
@@ -843,30 +856,23 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) {
|
|
843
856
|
*
|
844
857
|
* Returns a string that represents the client library version.
|
845
858
|
*/
|
846
|
-
static VALUE rb_mysql_client_info(VALUE
|
847
|
-
VALUE version,
|
848
|
-
|
849
|
-
rb_encoding *default_internal_enc;
|
850
|
-
rb_encoding *conn_enc;
|
851
|
-
GET_CLIENT(self);
|
852
|
-
#endif
|
853
|
-
version = rb_hash_new();
|
859
|
+
static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) {
|
860
|
+
VALUE version_info, version, header_version;
|
861
|
+
version_info = rb_hash_new();
|
854
862
|
|
855
|
-
|
856
|
-
|
857
|
-
conn_enc = rb_to_encoding(wrapper->encoding);
|
858
|
-
#endif
|
863
|
+
version = rb_str_new2(mysql_get_client_info());
|
864
|
+
header_version = rb_str_new2(MYSQL_LINK_VERSION);
|
859
865
|
|
860
|
-
rb_hash_aset(version, sym_id, LONG2NUM(mysql_get_client_version()));
|
861
|
-
client_info = rb_str_new2(mysql_get_client_info());
|
862
866
|
#ifdef HAVE_RUBY_ENCODING_H
|
863
|
-
rb_enc_associate(
|
864
|
-
|
865
|
-
client_info = rb_str_export_to_enc(client_info, default_internal_enc);
|
866
|
-
}
|
867
|
+
rb_enc_associate(version, rb_usascii_encoding());
|
868
|
+
rb_enc_associate(header_version, rb_usascii_encoding());
|
867
869
|
#endif
|
868
|
-
|
869
|
-
|
870
|
+
|
871
|
+
rb_hash_aset(version_info, sym_id, LONG2NUM(mysql_get_client_version()));
|
872
|
+
rb_hash_aset(version_info, sym_version, version);
|
873
|
+
rb_hash_aset(version_info, sym_header_version, header_version);
|
874
|
+
|
875
|
+
return version_info;
|
870
876
|
}
|
871
877
|
|
872
878
|
/* call-seq:
|
@@ -907,14 +913,10 @@ static VALUE rb_mysql_client_server_info(VALUE self) {
|
|
907
913
|
* Return the file descriptor number for this client.
|
908
914
|
*/
|
909
915
|
static VALUE rb_mysql_client_socket(VALUE self) {
|
910
|
-
GET_CLIENT(self);
|
911
916
|
#ifndef _WIN32
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
fd_set_fd = wrapper->client->net.fd;
|
916
|
-
return INT2NUM(fd_set_fd);
|
917
|
-
}
|
917
|
+
GET_CLIENT(self);
|
918
|
+
REQUIRE_CONNECTED(wrapper);
|
919
|
+
return INT2NUM(wrapper->client->net.fd);
|
918
920
|
#else
|
919
921
|
rb_raise(cMysql2Error, "Raw access to the mysql file descriptor isn't supported on Windows");
|
920
922
|
#endif
|
@@ -987,7 +989,7 @@ static VALUE rb_mysql_client_select_db(VALUE self, VALUE db)
|
|
987
989
|
REQUIRE_CONNECTED(wrapper);
|
988
990
|
|
989
991
|
args.mysql = wrapper->client;
|
990
|
-
args.db =
|
992
|
+
args.db = StringValueCStr(db);
|
991
993
|
|
992
994
|
if (rb_thread_call_without_gvl(nogvl_select_db, &args, RUBY_UBF_IO, 0) == Qfalse)
|
993
995
|
rb_raise_mysql2_error(wrapper);
|
@@ -1183,11 +1185,11 @@ static VALUE set_ssl_options(VALUE self, VALUE key, VALUE cert, VALUE ca, VALUE
|
|
1183
1185
|
GET_CLIENT(self);
|
1184
1186
|
|
1185
1187
|
mysql_ssl_set(wrapper->client,
|
1186
|
-
NIL_P(key)
|
1187
|
-
NIL_P(cert)
|
1188
|
-
NIL_P(ca)
|
1189
|
-
NIL_P(capath) ? NULL :
|
1190
|
-
NIL_P(cipher) ? NULL :
|
1188
|
+
NIL_P(key) ? NULL : StringValueCStr(key),
|
1189
|
+
NIL_P(cert) ? NULL : StringValueCStr(cert),
|
1190
|
+
NIL_P(ca) ? NULL : StringValueCStr(ca),
|
1191
|
+
NIL_P(capath) ? NULL : StringValueCStr(capath),
|
1192
|
+
NIL_P(cipher) ? NULL : StringValueCStr(cipher));
|
1191
1193
|
|
1192
1194
|
return self;
|
1193
1195
|
}
|
@@ -1254,12 +1256,12 @@ void init_mysql2_client() {
|
|
1254
1256
|
rb_define_alloc_func(cMysql2Client, allocate);
|
1255
1257
|
|
1256
1258
|
rb_define_singleton_method(cMysql2Client, "escape", rb_mysql_client_escape, 1);
|
1259
|
+
rb_define_singleton_method(cMysql2Client, "info", rb_mysql_client_info, 0);
|
1257
1260
|
|
1258
1261
|
rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0);
|
1259
1262
|
rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1);
|
1260
1263
|
rb_define_method(cMysql2Client, "abandon_results!", rb_mysql_client_abandon_results, 0);
|
1261
1264
|
rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1);
|
1262
|
-
rb_define_method(cMysql2Client, "info", rb_mysql_client_info, 0);
|
1263
1265
|
rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0);
|
1264
1266
|
rb_define_method(cMysql2Client, "socket", rb_mysql_client_socket, 0);
|
1265
1267
|
rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0);
|
@@ -1293,6 +1295,7 @@ void init_mysql2_client() {
|
|
1293
1295
|
|
1294
1296
|
sym_id = ID2SYM(rb_intern("id"));
|
1295
1297
|
sym_version = ID2SYM(rb_intern("version"));
|
1298
|
+
sym_header_version = ID2SYM(rb_intern("header_version"));
|
1296
1299
|
sym_async = ID2SYM(rb_intern("async"));
|
1297
1300
|
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
1298
1301
|
sym_as = ID2SYM(rb_intern("as"));
|
data/ext/mysql2/extconf.rb
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
require 'mkmf'
|
3
3
|
|
4
4
|
def asplode lib
|
5
|
-
|
5
|
+
if RUBY_PLATFORM =~ /mingw|mswin/
|
6
|
+
abort "-----\n#{lib} is missing. Check your installation of MySQL or Connector/C, and try again.\n-----"
|
7
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
8
|
+
abort "-----\n#{lib} is missing. You may need to 'brew install mysql' or 'port install mysql', and try again.\n-----"
|
9
|
+
else
|
10
|
+
abort "-----\n#{lib} is missing. You may need to 'apt-get install libmysqlclient-dev' or 'yum install mysql-devel', and try again.\n-----"
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
14
|
# 2.0-only
|
@@ -20,16 +26,16 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[
|
|
20
26
|
/opt
|
21
27
|
/opt/local
|
22
28
|
/opt/local/mysql
|
23
|
-
/opt/local/lib/mysql5
|
29
|
+
/opt/local/lib/mysql5*
|
24
30
|
/usr
|
25
31
|
/usr/mysql
|
26
32
|
/usr/local
|
27
33
|
/usr/local/mysql
|
28
34
|
/usr/local/mysql-*
|
29
|
-
/usr/local/lib/mysql5
|
35
|
+
/usr/local/lib/mysql5*
|
30
36
|
].map{|dir| "#{dir}/bin" }
|
31
37
|
|
32
|
-
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
|
38
|
+
GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"
|
33
39
|
|
34
40
|
# If the user has provided a --with-mysql-dir argument, we must respect it or fail.
|
35
41
|
inc, lib = dir_config('mysql')
|
@@ -66,16 +72,23 @@ elsif mc = (with_config('mysql-config') || Dir[GLOB].first)
|
|
66
72
|
rpath_dir = libs
|
67
73
|
else
|
68
74
|
inc, lib = dir_config('mysql', '/usr/local')
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
75
|
+
unless find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql")
|
76
|
+
found = false
|
77
|
+
# For some systems and some versions of libmysqlclient, there were extra
|
78
|
+
# libraries needed to link. Try each typical extra library, add it to the
|
79
|
+
# global compile flags, and see if that allows us to link libmysqlclient.
|
80
|
+
warn "-----\nlibmysqlclient is missing. Trying again with extra runtime libraries...\n-----"
|
81
|
+
|
82
|
+
%w{ m z socket nsl mygcc }.each do |extra_lib|
|
83
|
+
if have_library(extra_lib) && find_library('mysqlclient', 'mysql_query', lib, "#{lib}/mysql")
|
84
|
+
found = true
|
85
|
+
break
|
86
|
+
end
|
87
|
+
end
|
88
|
+
asplode('libmysqlclient') unless found
|
73
89
|
end
|
74
|
-
rpath_dir = lib
|
75
|
-
end
|
76
90
|
|
77
|
-
|
78
|
-
exit 1 unless have_library('libmysql')
|
91
|
+
rpath_dir = lib
|
79
92
|
end
|
80
93
|
|
81
94
|
if have_header('mysql.h')
|
@@ -98,31 +111,82 @@ if try_link('int main() {return 0;}', gcc_flags)
|
|
98
111
|
$CFLAGS << gcc_flags
|
99
112
|
end
|
100
113
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
114
|
+
if RUBY_PLATFORM =~ /mswin|mingw/
|
115
|
+
# Build libmysql.a interface link library
|
116
|
+
require 'rake'
|
117
|
+
|
118
|
+
# Build libmysql.a interface link library
|
119
|
+
# Use rake to rebuild only if these files change
|
120
|
+
deffile = File.expand_path('../../../support/libmysql.def', __FILE__)
|
121
|
+
libfile = File.expand_path(File.join(rpath_dir, 'libmysql.lib'))
|
122
|
+
file 'libmysql.a' => [deffile, libfile] do |t|
|
123
|
+
when_writing 'building libmysql.a' do
|
124
|
+
# Ruby kindly shows us where dllwrap is, but that tool does more than we want.
|
125
|
+
# Maybe in the future Ruby could provide RbConfig::CONFIG['DLLTOOL'] directly.
|
126
|
+
dlltool = RbConfig::CONFIG['DLLWRAP'].gsub('dllwrap', 'dlltool')
|
127
|
+
sh dlltool, '--kill-at',
|
128
|
+
'--dllname', 'libmysql.dll',
|
129
|
+
'--output-lib', 'libmysql.a',
|
130
|
+
'--input-def', deffile, libfile
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
Rake::Task['libmysql.a'].invoke
|
135
|
+
$LOCAL_LIBS << ' ' << 'libmysql.a'
|
136
|
+
|
137
|
+
# Make sure the generated interface library works (if cross-compiling, trust without verifying)
|
138
|
+
unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
139
|
+
abort "-----\nCannot find libmysql.a\n----" unless have_library('libmysql')
|
140
|
+
abort "-----\nCannot link to libmysql.a (my_init)\n----" unless have_func('my_init')
|
141
|
+
end
|
142
|
+
|
143
|
+
# Vendor libmysql.dll
|
144
|
+
vendordir = File.expand_path('../../../vendor/', __FILE__)
|
145
|
+
directory vendordir
|
146
|
+
|
147
|
+
vendordll = File.join(vendordir, 'libmysql.dll')
|
148
|
+
dllfile = File.expand_path(File.join(rpath_dir, 'libmysql.dll'))
|
149
|
+
file vendordll => [dllfile, vendordir] do |t|
|
150
|
+
when_writing 'copying libmysql.dll' do
|
151
|
+
cp dllfile, vendordll
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Copy libmysql.dll to the local vendor directory by default
|
156
|
+
if arg_config('--no-vendor-libmysql')
|
157
|
+
# Fine, don't.
|
158
|
+
puts "--no-vendor-libmysql"
|
159
|
+
else # Default: arg_config('--vendor-libmysql')
|
160
|
+
# Let's do it!
|
161
|
+
Rake::Task[vendordll].invoke
|
162
|
+
end
|
111
163
|
else
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
164
|
+
case explicit_rpath = with_config('mysql-rpath')
|
165
|
+
when true
|
166
|
+
abort "-----\nOption --with-mysql-rpath must have an argument\n-----"
|
167
|
+
when false
|
168
|
+
warn "-----\nOption --with-mysql-rpath has been disabled at your request\n-----"
|
169
|
+
when String
|
170
|
+
# The user gave us a value so use it
|
171
|
+
rpath_flags = " -Wl,-rpath,#{explicit_rpath}"
|
172
|
+
warn "-----\nSetting mysql rpath to #{explicit_rpath}\n-----"
|
173
|
+
$LDFLAGS << rpath_flags
|
174
|
+
else
|
175
|
+
if libdir = rpath_dir[%r{(-L)?(/[^ ]+)}, 2]
|
176
|
+
rpath_flags = " -Wl,-rpath,#{libdir}"
|
177
|
+
if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', rpath_flags)
|
178
|
+
# Usually Ruby sets RPATHFLAG the right way for each system, but not on OS X.
|
179
|
+
warn "-----\nSetting rpath to #{libdir}\n-----"
|
180
|
+
$LDFLAGS << rpath_flags
|
181
|
+
else
|
182
|
+
if RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
|
183
|
+
# If we got here because try_link failed, warn the user
|
184
|
+
warn "-----\nDon't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load\n-----"
|
185
|
+
end
|
186
|
+
# Make sure that LIBPATH gets set if we didn't explicitly set the rpath.
|
187
|
+
warn "-----\nSetting libpath to #{libdir}\n-----"
|
188
|
+
$LIBPATH << libdir unless $LIBPATH.include?(libdir)
|
122
189
|
end
|
123
|
-
# Make sure that LIBPATH gets set if we didn't explicitly set the rpath.
|
124
|
-
warn "-----\nSetting libpath to #{libdir}\n-----"
|
125
|
-
$LIBPATH << libdir unless $LIBPATH.include?(libdir)
|
126
190
|
end
|
127
191
|
end
|
128
192
|
end
|