trilogy 2.9.0 → 2.11.0

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.
@@ -25,6 +25,12 @@ struct trilogy_sock {
25
25
  SSL *ssl;
26
26
  };
27
27
 
28
+ void trilogy_sock_set_fd(trilogy_sock_t *_sock, int fd)
29
+ {
30
+ struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
31
+ sock->fd = fd;
32
+ }
33
+
28
34
  static int _cb_raw_fd(trilogy_sock_t *_sock)
29
35
  {
30
36
  struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Trilogy
2
4
  module Encoding
3
5
  RUBY_ENCODINGS = {
data/lib/trilogy/error.rb CHANGED
@@ -54,6 +54,12 @@ class Trilogy
54
54
  include ConnectionError
55
55
  end
56
56
 
57
+ class SynchronizationError < BaseError
58
+ def initialize(message = "This connection is already in use by another thread or fiber")
59
+ super
60
+ end
61
+ end
62
+
57
63
  # Trilogy::ClientError is the base error type for invalid queries or parameters
58
64
  # that shouldn't be retried.
59
65
  class ClientError < BaseError
@@ -94,6 +100,7 @@ class Trilogy
94
100
  1160 => BaseConnectionError, # ER_NET_ERROR_ON_WRITE
95
101
  1161 => BaseConnectionError, # ER_NET_WRITE_INTERRUPTED
96
102
  1927 => BaseConnectionError, # ER_CONNECTION_KILLED
103
+ 4031 => BaseConnectionError, # Disconnected by server
97
104
  }
98
105
  class << self
99
106
  def from_code(message, code)
@@ -6,6 +6,8 @@ class Trilogy
6
6
  rows.count
7
7
  end
8
8
 
9
+ alias_method :size, :count
10
+
9
11
  def each_hash
10
12
  return enum_for(:each_hash) unless block_given?
11
13
 
@@ -1,3 +1,3 @@
1
1
  class Trilogy
2
- VERSION = "2.9.0"
2
+ VERSION = "2.11.0"
3
3
  end
data/lib/trilogy.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "socket"
3
4
  require "trilogy/version"
4
5
  require "trilogy/error"
5
6
  require "trilogy/result"
@@ -7,7 +8,34 @@ require "trilogy/cext"
7
8
  require "trilogy/encoding"
8
9
 
9
10
  class Trilogy
11
+ IO_TIMEOUT_ERROR =
12
+ if defined?(IO::TimeoutError)
13
+ IO::TimeoutError
14
+ else
15
+ Class.new(StandardError)
16
+ end
17
+ private_constant :IO_TIMEOUT_ERROR
18
+
19
+ Synchronization = Module.new
20
+
21
+ source = public_instance_methods(false).flat_map do |method|
22
+ [
23
+ "def #{method}(...)",
24
+ "raise SynchronizationError unless @mutex.try_lock",
25
+ "begin",
26
+ "super",
27
+ "ensure",
28
+ "@mutex.unlock",
29
+ "end",
30
+ "end",
31
+ ]
32
+ end
33
+ Synchronization.class_eval(source.join(";"), __FILE__, __LINE__)
34
+
35
+ prepend(Synchronization)
36
+
10
37
  def initialize(options = {})
38
+ @mutex = Mutex.new
11
39
  options[:port] = options[:port].to_i if options[:port]
12
40
  mysql_encoding = options[:encoding] || "utf8mb4"
13
41
  encoding = Trilogy::Encoding.find(mysql_encoding)
@@ -15,7 +43,54 @@ class Trilogy
15
43
  @connection_options = options
16
44
  @connected_host = nil
17
45
 
18
- _connect(encoding, charset, options)
46
+ socket = nil
47
+ begin
48
+ if host = options[:host]
49
+ port = options[:port] || 3306
50
+ connect_timeout = options[:connect_timeout] || options[:write_timeout]
51
+
52
+ socket = TCPSocket.new(host, port, connect_timeout: connect_timeout)
53
+
54
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
55
+
56
+ if keepalive_enabled = options[:keepalive_enabled]
57
+ keepalive_idle = options[:keepalive_idle]
58
+ keepalive_interval = options[:keepalive_interval]
59
+ keepalive_count = options[:keepalive_count]
60
+
61
+ socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
62
+
63
+ if keepalive_idle > 0 && defined?(Socket::TCP_KEEPIDLE)
64
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, keepalive_idle)
65
+ end
66
+ if keepalive_interval > 0 && defined?(Socket::TCP_KEEPINTVL)
67
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, keepalive_interval)
68
+ end
69
+ if keepalive_count > 0 && defined?(Socket::TCP_KEEPCNT)
70
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, keepalive_count)
71
+ end
72
+ end
73
+ else
74
+ path = options[:socket] ||= "/tmp/mysql.sock"
75
+ socket = UNIXSocket.new(path)
76
+ end
77
+ rescue Errno::ETIMEDOUT, IO_TIMEOUT_ERROR => e
78
+ raise Trilogy::TimeoutError, e.message
79
+ rescue SocketError => e
80
+ connection_str = host ? "#{host}:#{port}" : path
81
+ raise Trilogy::BaseConnectionError, "unable to connect to \"#{connection_str}\": #{e.message}"
82
+ rescue => e
83
+ if e.respond_to?(:errno)
84
+ raise Trilogy::SyscallError.from_errno(e.errno, e.message)
85
+ else
86
+ raise
87
+ end
88
+ end
89
+
90
+ _connect(socket, encoding, charset, options)
91
+ ensure
92
+ # Socket's fd will be dup'd in C
93
+ socket&.close
19
94
  end
20
95
 
21
96
  def connection_options
data/trilogy.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.require_paths = ["lib"]
24
24
 
25
- s.add_development_dependency "rake-compiler", "~> 1.0"
26
- s.add_development_dependency "minitest", "~> 5.5"
25
+ s.required_ruby_version = ">= 3.0"
26
+
27
+ s.add_dependency "bigdecimal"
27
28
  end
metadata CHANGED
@@ -1,44 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trilogy
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Engineering
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: rake-compiler
13
+ name: bigdecimal
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :development
18
+ version: '0'
19
+ type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - "~>"
23
+ - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '1.0'
27
- - !ruby/object:Gem::Dependency
28
- name: minitest
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '5.5'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '5.5'
41
- description:
25
+ version: '0'
42
26
  email: opensource+trilogy@github.com
43
27
  executables: []
44
28
  extensions:
@@ -87,7 +71,6 @@ homepage: https://github.com/trilogy-libraries/trilogy
87
71
  licenses:
88
72
  - MIT
89
73
  metadata: {}
90
- post_install_message:
91
74
  rdoc_options: []
92
75
  require_paths:
93
76
  - lib
@@ -95,15 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
78
  requirements:
96
79
  - - ">="
97
80
  - !ruby/object:Gem::Version
98
- version: '0'
81
+ version: '3.0'
99
82
  required_rubygems_version: !ruby/object:Gem::Requirement
100
83
  requirements:
101
84
  - - ">="
102
85
  - !ruby/object:Gem::Version
103
86
  version: '0'
104
87
  requirements: []
105
- rubygems_version: 3.5.11
106
- signing_key:
88
+ rubygems_version: 3.6.9
107
89
  specification_version: 4
108
90
  summary: A friendly MySQL-compatible library for Ruby, binding to libtrilogy
109
91
  test_files: []