trilogy_w_prepared_statements 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +80 -0
  4. data/Rakefile +22 -0
  5. data/ext/trilogy-ruby/cast.c +277 -0
  6. data/ext/trilogy-ruby/cext.c +1048 -0
  7. data/ext/trilogy-ruby/extconf.rb +17 -0
  8. data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
  9. data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
  10. data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
  11. data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
  12. data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
  13. data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
  14. data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
  15. data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
  16. data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
  17. data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
  18. data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
  19. data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
  20. data/ext/trilogy-ruby/inc/trilogy.h +8 -0
  21. data/ext/trilogy-ruby/src/blocking.c +358 -0
  22. data/ext/trilogy-ruby/src/buffer.c +60 -0
  23. data/ext/trilogy-ruby/src/builder.c +236 -0
  24. data/ext/trilogy-ruby/src/charset.c +212 -0
  25. data/ext/trilogy-ruby/src/client.c +903 -0
  26. data/ext/trilogy-ruby/src/error.c +17 -0
  27. data/ext/trilogy-ruby/src/packet_parser.c +140 -0
  28. data/ext/trilogy-ruby/src/protocol.c +1175 -0
  29. data/ext/trilogy-ruby/src/reader.c +282 -0
  30. data/ext/trilogy-ruby/src/socket.c +623 -0
  31. data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
  32. data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
  33. data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
  34. data/lib/trilogy/version.rb +3 -0
  35. data/lib/trilogy.rb +61 -0
  36. data/trilogy.gemspec +27 -0
  37. metadata +107 -0
@@ -0,0 +1,206 @@
1
+ /***************************************************************************
2
+ * _ _ ____ _
3
+ * Project ___| | | | _ \| |
4
+ * / __| | | | |_) | |
5
+ * | (__| |_| | _ <| |___
6
+ * \___|\___/|_| \_\_____|
7
+ *
8
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
9
+ *
10
+ * This software is licensed as described in the file COPYING, which
11
+ * you should have received as part of this distribution. The terms
12
+ * are also available at http://curl.haxx.se/docs/copyright.html.
13
+ *
14
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
+ * copies of the Software, and permit persons to whom the Software is
16
+ * furnished to do so, under the terms of the COPYING file.
17
+ *
18
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
+ * KIND, either express or implied.
20
+ *
21
+ ***************************************************************************/
22
+
23
+ /* This file is an amalgamation of hostcheck.c and most of rawstr.c
24
+ from cURL. The contents of the COPYING file mentioned above are:
25
+ COPYRIGHT AND PERMISSION NOTICE
26
+ Copyright (c) 1996 - 2013, Daniel Stenberg, <daniel@haxx.se>.
27
+ All rights reserved.
28
+ Permission to use, copy, modify, and distribute this software for any purpose
29
+ with or without fee is hereby granted, provided that the above copyright
30
+ notice and this permission notice appear in all copies.
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
34
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
35
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
36
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
37
+ OR OTHER DEALINGS IN THE SOFTWARE.
38
+ Except as contained in this notice, the name of a copyright holder shall not
39
+ be used in advertising or otherwise to promote the sale, use or other dealings
40
+ in this Software without prior written authorization of the copyright holder.
41
+ */
42
+
43
+ #include "trilogy/vendor/curl_hostcheck.h"
44
+ #include <string.h>
45
+
46
+ /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
47
+ its behavior is altered by the current locale. */
48
+ static char Curl_raw_toupper(char in)
49
+ {
50
+ switch (in) {
51
+ case 'a':
52
+ return 'A';
53
+ case 'b':
54
+ return 'B';
55
+ case 'c':
56
+ return 'C';
57
+ case 'd':
58
+ return 'D';
59
+ case 'e':
60
+ return 'E';
61
+ case 'f':
62
+ return 'F';
63
+ case 'g':
64
+ return 'G';
65
+ case 'h':
66
+ return 'H';
67
+ case 'i':
68
+ return 'I';
69
+ case 'j':
70
+ return 'J';
71
+ case 'k':
72
+ return 'K';
73
+ case 'l':
74
+ return 'L';
75
+ case 'm':
76
+ return 'M';
77
+ case 'n':
78
+ return 'N';
79
+ case 'o':
80
+ return 'O';
81
+ case 'p':
82
+ return 'P';
83
+ case 'q':
84
+ return 'Q';
85
+ case 'r':
86
+ return 'R';
87
+ case 's':
88
+ return 'S';
89
+ case 't':
90
+ return 'T';
91
+ case 'u':
92
+ return 'U';
93
+ case 'v':
94
+ return 'V';
95
+ case 'w':
96
+ return 'W';
97
+ case 'x':
98
+ return 'X';
99
+ case 'y':
100
+ return 'Y';
101
+ case 'z':
102
+ return 'Z';
103
+ }
104
+ return in;
105
+ }
106
+
107
+ /*
108
+ * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
109
+ * to be locale independent and only compare strings we know are safe for
110
+ * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
111
+ * some further explanation to why this function is necessary.
112
+ *
113
+ * The function is capable of comparing a-z case insensitively even for
114
+ * non-ascii.
115
+ */
116
+
117
+ static int Curl_raw_equal(const char *first, const char *second)
118
+ {
119
+ while (*first && *second) {
120
+ if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
121
+ /* get out of the loop as soon as they don't match */
122
+ break;
123
+ first++;
124
+ second++;
125
+ }
126
+ /* we do the comparison here (possibly again), just to make sure that if the
127
+ loop above is skipped because one of the strings reached zero, we must
128
+ not return this as a successful match */
129
+ return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
130
+ }
131
+
132
+ static int Curl_raw_nequal(const char *first, const char *second, size_t max)
133
+ {
134
+ while (*first && *second && max) {
135
+ if (Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
136
+ break;
137
+ }
138
+ max--;
139
+ first++;
140
+ second++;
141
+ }
142
+ if (0 == max)
143
+ return 1; /* they are equal this far */
144
+
145
+ return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
146
+ }
147
+
148
+ /*
149
+ * Match a hostname against a wildcard pattern.
150
+ * E.g.
151
+ * "foo.host.com" matches "*.host.com".
152
+ *
153
+ * We use the matching rule described in RFC6125, section 6.4.3.
154
+ * http://tools.ietf.org/html/rfc6125#section-6.4.3
155
+ */
156
+
157
+ static int hostmatch(const char *hostname, const char *pattern)
158
+ {
159
+ const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
160
+ int wildcard_enabled;
161
+ size_t prefixlen, suffixlen;
162
+ pattern_wildcard = strchr(pattern, '*');
163
+ if (pattern_wildcard == NULL)
164
+ return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH : CURL_HOST_NOMATCH;
165
+
166
+ /* We require at least 2 dots in pattern to avoid too wide wildcard
167
+ match. */
168
+ wildcard_enabled = 1;
169
+ pattern_label_end = strchr(pattern, '.');
170
+ if (pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL ||
171
+ pattern_wildcard > pattern_label_end || Curl_raw_nequal(pattern, "xn--", 4)) {
172
+ wildcard_enabled = 0;
173
+ }
174
+ if (!wildcard_enabled)
175
+ return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH : CURL_HOST_NOMATCH;
176
+
177
+ hostname_label_end = strchr(hostname, '.');
178
+ if (hostname_label_end == NULL || !Curl_raw_equal(pattern_label_end, hostname_label_end))
179
+ return CURL_HOST_NOMATCH;
180
+
181
+ /* The wildcard must match at least one character, so the left-most
182
+ label of the hostname is at least as large as the left-most label
183
+ of the pattern. */
184
+ if (hostname_label_end - hostname < pattern_label_end - pattern)
185
+ return CURL_HOST_NOMATCH;
186
+
187
+ prefixlen = (size_t)(pattern_wildcard - pattern);
188
+ suffixlen = (size_t)(pattern_label_end - (pattern_wildcard + 1));
189
+ return Curl_raw_nequal(pattern, hostname, prefixlen) &&
190
+ Curl_raw_nequal(pattern_wildcard + 1, hostname_label_end - suffixlen, suffixlen)
191
+ ? CURL_HOST_MATCH
192
+ : CURL_HOST_NOMATCH;
193
+ }
194
+
195
+ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
196
+ {
197
+ if (!match_pattern || !*match_pattern || !hostname || !*hostname) /* sanity check */
198
+ return 0;
199
+
200
+ if (Curl_raw_equal(hostname, match_pattern)) /* trivial case */
201
+ return 1;
202
+
203
+ if (hostmatch(hostname, match_pattern) == CURL_HOST_MATCH)
204
+ return 1;
205
+ return 0;
206
+ }
@@ -0,0 +1,175 @@
1
+ /* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
2
+
3
+ /*
4
+ Copyright (C) 2012, iSEC Partners.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
20
+ */
21
+
22
+ /*
23
+ * Helper functions to perform basic hostname validation using OpenSSL.
24
+ *
25
+ * Please read "everything-you-wanted-to-know-about-openssl.pdf" before
26
+ * attempting to use this code. This whitepaper describes how the code works,
27
+ * how it should be used, and what its limitations are.
28
+ *
29
+ * Author: Alban Diquet
30
+ * License: See LICENSE
31
+ *
32
+ */
33
+
34
+ // Get rid of OSX 10.7 and greater deprecation warnings.
35
+ #if defined(__APPLE__) && defined(__clang__)
36
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
37
+ #endif
38
+
39
+ #include <openssl/ssl.h>
40
+ #include <openssl/x509v3.h>
41
+ #include <string.h>
42
+
43
+ #include "trilogy/vendor/curl_hostcheck.h"
44
+ #include "trilogy/vendor/openssl_hostname_validation.h"
45
+
46
+ #define HOSTNAME_MAX_SIZE 255
47
+
48
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
49
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
50
+ #define ASN1_STRING_get0_data ASN1_STRING_data
51
+ #endif
52
+
53
+ /**
54
+ * Tries to find a match for hostname in the certificate's Common Name field.
55
+ *
56
+ * Returns MatchFound if a match was found.
57
+ * Returns MatchNotFound if no matches were found.
58
+ * Returns MalformedCertificate if the Common Name had a NUL character embedded
59
+ * in it. Returns Error if the Common Name could not be extracted.
60
+ */
61
+ static HostnameValidationResult matches_common_name(const char *hostname, const X509 *server_cert)
62
+ {
63
+ int common_name_loc = -1;
64
+ X509_NAME_ENTRY *common_name_entry = NULL;
65
+ ASN1_STRING *common_name_asn1 = NULL;
66
+ const char *common_name_str = NULL;
67
+
68
+ // Find the position of the CN field in the Subject field of the certificate
69
+ common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *)server_cert), NID_commonName, -1);
70
+ if (common_name_loc < 0) {
71
+ return Error;
72
+ }
73
+
74
+ // Extract the CN field
75
+ common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *)server_cert), common_name_loc);
76
+ if (common_name_entry == NULL) {
77
+ return Error;
78
+ }
79
+
80
+ // Convert the CN field to a C string
81
+ common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
82
+ if (common_name_asn1 == NULL) {
83
+ return Error;
84
+ }
85
+ common_name_str = (char *)ASN1_STRING_get0_data(common_name_asn1);
86
+
87
+ // Make sure there isn't an embedded NUL character in the CN
88
+ if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {
89
+ return MalformedCertificate;
90
+ }
91
+
92
+ // Compare expected hostname with the CN
93
+ if (Curl_cert_hostcheck(common_name_str, hostname) == CURL_HOST_MATCH) {
94
+ return MatchFound;
95
+ } else {
96
+ return MatchNotFound;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Tries to find a match for hostname in the certificate's Subject Alternative
102
+ * Name extension.
103
+ *
104
+ * Returns MatchFound if a match was found.
105
+ * Returns MatchNotFound if no matches were found.
106
+ * Returns MalformedCertificate if any of the hostnames had a NUL character
107
+ * embedded in it. Returns NoSANPresent if the SAN extension was not present in
108
+ * the certificate.
109
+ */
110
+ static HostnameValidationResult matches_subject_alternative_name(const char *hostname, const X509 *server_cert)
111
+ {
112
+ HostnameValidationResult result = MatchNotFound;
113
+ int i;
114
+ int san_names_nb = -1;
115
+ STACK_OF(GENERAL_NAME) *san_names = NULL;
116
+
117
+ // Try to extract the names within the SAN extension from the certificate
118
+ san_names = X509_get_ext_d2i((X509 *)server_cert, NID_subject_alt_name, NULL, NULL);
119
+ if (san_names == NULL) {
120
+ return NoSANPresent;
121
+ }
122
+ san_names_nb = sk_GENERAL_NAME_num(san_names);
123
+
124
+ // Check each name within the extension
125
+ for (i = 0; i < san_names_nb; i++) {
126
+ const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
127
+
128
+ if (current_name->type == GEN_DNS) {
129
+ // Current name is a DNS name, let's check it
130
+ const char *dns_name = (char *)ASN1_STRING_get0_data(current_name->d.dNSName);
131
+
132
+ // Make sure there isn't an embedded NUL character in the DNS name
133
+ if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != strlen(dns_name)) {
134
+ result = MalformedCertificate;
135
+ break;
136
+ } else { // Compare expected hostname with the DNS name
137
+ if (Curl_cert_hostcheck(dns_name, hostname) == CURL_HOST_MATCH) {
138
+ result = MatchFound;
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
145
+
146
+ return result;
147
+ }
148
+
149
+ /**
150
+ * Validates the server's identity by looking for the expected hostname in the
151
+ * server's certificate. As described in RFC 6125, it first tries to find a
152
+ * match in the Subject Alternative Name extension. If the extension is not
153
+ * present in the certificate, it checks the Common Name instead.
154
+ *
155
+ * Returns MatchFound if a match was found.
156
+ * Returns MatchNotFound if no matches were found.
157
+ * Returns MalformedCertificate if any of the hostnames had a NUL character
158
+ * embedded in it. Returns Error if there was an error.
159
+ */
160
+ HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert)
161
+ {
162
+ HostnameValidationResult result;
163
+
164
+ if ((hostname == NULL) || (server_cert == NULL))
165
+ return Error;
166
+
167
+ // First try the Subject Alternative Names extension
168
+ result = matches_subject_alternative_name(hostname, server_cert);
169
+ if (result == NoSANPresent) {
170
+ // Extension was not found: try the Common Name
171
+ result = matches_common_name(hostname, server_cert);
172
+ }
173
+
174
+ return result;
175
+ }
@@ -0,0 +1,37 @@
1
+ #ifndef TRILOGY_RUBY_H
2
+ #define TRILOGY_RUBY_H
3
+
4
+ #include <stdbool.h>
5
+
6
+ #include <trilogy.h>
7
+
8
+ #define TRILOGY_FLAGS_CAST 1
9
+ #define TRILOGY_FLAGS_CAST_BOOLEANS 2
10
+ #define TRILOGY_FLAGS_LOCAL_TIMEZONE 4
11
+ #define TRILOGY_FLAGS_FLATTEN_ROWS 8
12
+ #define TRILOGY_FLAGS_DEFAULT (TRILOGY_FLAGS_CAST)
13
+
14
+ struct rb_trilogy_cast_options {
15
+ bool cast;
16
+ bool cast_booleans;
17
+ bool database_local_time;
18
+ bool flatten_rows;
19
+ };
20
+
21
+ struct column_info {
22
+ TRILOGY_TYPE_t type;
23
+ TRILOGY_CHARSET_t charset;
24
+ uint32_t len;
25
+ uint16_t flags;
26
+ uint8_t decimals;
27
+ };
28
+
29
+ extern VALUE rb_cTrilogyError;
30
+
31
+ VALUE
32
+ rb_trilogy_cast_value(const trilogy_value_t *value, const struct column_info *column,
33
+ const struct rb_trilogy_cast_options *options);
34
+
35
+ void rb_trilogy_cast_init(void);
36
+
37
+ #endif
@@ -0,0 +1,3 @@
1
+ class Trilogy
2
+ VERSION = "2.2.0"
3
+ end
data/lib/trilogy.rb ADDED
@@ -0,0 +1,61 @@
1
+ require "trilogy/cext"
2
+ require "trilogy/version"
3
+
4
+ class Trilogy
5
+ def in_transaction?
6
+ (server_status & SERVER_STATUS_IN_TRANS) != 0
7
+ end
8
+
9
+ def server_info
10
+ version_str = server_version
11
+
12
+ if /\A(\d+)\.(\d+)\.(\d+)/ =~ version_str
13
+ version_num = ($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
14
+ end
15
+
16
+ { :version => version_str, :id => version_num }
17
+ end
18
+
19
+ def connected_host
20
+ @connected_host ||= query_with_flags("select @@hostname", query_flags | QUERY_FLAGS_FLATTEN_ROWS).rows.first
21
+ end
22
+
23
+ def query_with_flags(sql, flags)
24
+ old_flags = query_flags
25
+ self.query_flags = flags
26
+
27
+ query(sql)
28
+ ensure
29
+ self.query_flags = old_flags
30
+ end
31
+ end
32
+
33
+ Trilogy::Result.class_eval do
34
+ def count
35
+ rows.count
36
+ end
37
+
38
+ def each_hash
39
+ return enum_for(:each_hash) unless block_given?
40
+
41
+ rows.each do |row|
42
+ this_row = {}
43
+
44
+ idx = 0
45
+ row.each do |col|
46
+ this_row[fields[idx]] = col
47
+ idx += 1
48
+ end
49
+
50
+ yield this_row
51
+ end
52
+
53
+ self
54
+ end
55
+
56
+ def each(&bk)
57
+ rows.each(&bk)
58
+ end
59
+
60
+ include Enumerable
61
+ end
data/trilogy.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ require File.expand_path("../lib/trilogy/version", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'trilogy_w_prepared_statements'
5
+ s.version = Trilogy::VERSION
6
+ s.authors = ['GitHub Engineering', 'Brian Lopez']
7
+ s.email = "opensource+trilogy@github.com"
8
+ s.license = "MIT"
9
+ s.homepage = "https://github.com/lorint/trilogy_w_prepared_statements"
10
+ s.summary = "A friendly MySQL-compatible library for Ruby, binding to libtrilogy"
11
+
12
+ s.extensions = "ext/trilogy-ruby/extconf.rb"
13
+
14
+ gem_files = %w[LICENSE README.md Rakefile trilogy.gemspec]
15
+ gem_files += Dir.glob("lib/**/*.rb")
16
+ gem_files += Dir.glob("ext/trilogy-ruby/*.c")
17
+ gem_files += Dir.glob("ext/trilogy-ruby/*.h")
18
+ gem_files += Dir.glob("ext/trilogy-ruby/src/**/*.c")
19
+ gem_files += Dir.glob("ext/trilogy-ruby/inc/**/*.h")
20
+
21
+ s.files = gem_files
22
+
23
+ s.require_paths = ["lib"]
24
+
25
+ s.add_development_dependency "rake-compiler", "~> 1.0"
26
+ s.add_development_dependency "minitest", "~> 5.5"
27
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trilogy_w_prepared_statements
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.2.0
5
+ platform: ruby
6
+ authors:
7
+ - GitHub Engineering
8
+ - Brian Lopez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2022-12-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake-compiler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '5.5'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '5.5'
42
+ description:
43
+ email: opensource+trilogy@github.com
44
+ executables: []
45
+ extensions:
46
+ - ext/trilogy-ruby/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - ext/trilogy-ruby/cast.c
53
+ - ext/trilogy-ruby/cext.c
54
+ - ext/trilogy-ruby/extconf.rb
55
+ - ext/trilogy-ruby/inc/trilogy.h
56
+ - ext/trilogy-ruby/inc/trilogy/blocking.h
57
+ - ext/trilogy-ruby/inc/trilogy/buffer.h
58
+ - ext/trilogy-ruby/inc/trilogy/builder.h
59
+ - ext/trilogy-ruby/inc/trilogy/charset.h
60
+ - ext/trilogy-ruby/inc/trilogy/client.h
61
+ - ext/trilogy-ruby/inc/trilogy/error.h
62
+ - ext/trilogy-ruby/inc/trilogy/packet_parser.h
63
+ - ext/trilogy-ruby/inc/trilogy/protocol.h
64
+ - ext/trilogy-ruby/inc/trilogy/reader.h
65
+ - ext/trilogy-ruby/inc/trilogy/socket.h
66
+ - ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h
67
+ - ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h
68
+ - ext/trilogy-ruby/src/blocking.c
69
+ - ext/trilogy-ruby/src/buffer.c
70
+ - ext/trilogy-ruby/src/builder.c
71
+ - ext/trilogy-ruby/src/charset.c
72
+ - ext/trilogy-ruby/src/client.c
73
+ - ext/trilogy-ruby/src/error.c
74
+ - ext/trilogy-ruby/src/packet_parser.c
75
+ - ext/trilogy-ruby/src/protocol.c
76
+ - ext/trilogy-ruby/src/reader.c
77
+ - ext/trilogy-ruby/src/socket.c
78
+ - ext/trilogy-ruby/src/vendor/curl_hostcheck.c
79
+ - ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c
80
+ - ext/trilogy-ruby/trilogy-ruby.h
81
+ - lib/trilogy.rb
82
+ - lib/trilogy/version.rb
83
+ - trilogy.gemspec
84
+ homepage: https://github.com/lorint/trilogy_w_prepared_statements
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.0.8
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: A friendly MySQL-compatible library for Ruby, binding to libtrilogy
107
+ test_files: []