activerecord-aurora-serverless-adapter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,71 @@
1
+ # Keep `AuroraServerless::Client` abstract and mix these methods
2
+ # in specifically to mimic the Mysql2 gem's interfaces.
3
+ #
4
+ module ActiveRecord
5
+ module ConnectionAdapters
6
+ module AuroraServerless
7
+ module Mysql2
8
+ module Client
9
+
10
+ ESCAPE_MAP = {
11
+ "\x00" => "0",
12
+ "\n" => "n",
13
+ "\r" => "r",
14
+ "\\" => "\\",
15
+ "'" => "'",
16
+ '"' => '"'
17
+ }.freeze
18
+
19
+ ESCAPE_PATTERN = Regexp.union(*ESCAPE_MAP.keys)
20
+
21
+ def self.default_query_options
22
+ {}
23
+ end
24
+
25
+ def query_options
26
+ {}
27
+ end
28
+
29
+ def query(sql)
30
+ raise ActiveRecord::StatementInvalid if @closed
31
+ result = execute_statement(sql)
32
+ AuroraServerless::Mysql2::Result.new(result)
33
+ end
34
+
35
+ def server_info
36
+ @server_info || begin
37
+ r = query 'SHOW VARIABLES LIKE "version"'
38
+ version = r.to_a.detect{ |r| r.detect { |v| v == 'version' } }.last
39
+ { version: version }
40
+ end
41
+ end
42
+
43
+ def close
44
+ @closed = true
45
+ end
46
+
47
+ def automatic_close=(*)
48
+ nil
49
+ end
50
+
51
+ def escape(string)
52
+ string.gsub(ESCAPE_PATTERN) { |x| "\\#{ESCAPE_MAP[x]}" }
53
+ end
54
+
55
+ def ping
56
+ return false if @closed
57
+ query('SELECT 1').to_a.first.first == 1
58
+ rescue
59
+ false
60
+ end
61
+
62
+ def abandon_results!
63
+ nil
64
+ end
65
+
66
+ end
67
+ end
68
+ AuroraServerless::Client.include AuroraServerless::Mysql2::Client
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveRecord
2
+ module ConnectionHandling
3
+
4
+ def aurora_serverless_connection(config)
5
+ client = aurora_serverless_connection_from_config(config)
6
+ ConnectionAdapters::AuroraServerlessAdapter.new(client, logger, nil, config)
7
+ end
8
+
9
+ def aurora_serverless_connection_from_config(config)
10
+ ConnectionAdapters::AuroraServerless::Client.new(
11
+ config[:database],
12
+ config[:resource_arn],
13
+ config[:secret_arn],
14
+ config
15
+ )
16
+ end
17
+ module_function :aurora_serverless_connection_from_config
18
+
19
+ end
20
+ end
@@ -0,0 +1,116 @@
1
+ # Wraps a `Aws::RDSDataService::Types::ExecuteStatementResponse` response object.
2
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/RDSDataService/Types/ExecuteStatementResponse.html
3
+ #
4
+ module ActiveRecord
5
+ module ConnectionAdapters
6
+ module AuroraServerless
7
+ module Mysql2
8
+ class Result
9
+ include Enumerable
10
+
11
+ attr_reader :response
12
+
13
+ def initialize(response)
14
+ @response = response
15
+ end
16
+
17
+ def fields
18
+ @fields ||= begin
19
+ md = @response.column_metadata
20
+ md ? md.map(&:label) : []
21
+ end
22
+ end
23
+
24
+ def to_a
25
+ as_array
26
+ end
27
+
28
+ def each(**kwargs)
29
+ eobj = each_object(kwargs)
30
+ block_given? ? eobj.each { |r| yield(r) } : eobj
31
+ end
32
+
33
+ private
34
+
35
+ def each_object(**kwargs)
36
+ symbolize_keys = kwargs[:symbolize_keys]
37
+ kwargs[:as] == :hash ? as_hash(symbolize_keys) : as_array
38
+ end
39
+
40
+ def as_array
41
+ @as_array ||= (@response.records || []).map do |fields|
42
+ fields.each_with_index.map do |field, index|
43
+ type = @response.column_metadata[index].type_name
44
+ type_cast(field, type)
45
+ end
46
+ end
47
+ end
48
+
49
+ def as_hash(symbolize_keys = true)
50
+ @as_hash ||= begin
51
+ h = ActiveRecord::Result.new(fields, as_array).to_a
52
+ symbolize_keys ? h.map { |r| r.symbolize_keys! } : h
53
+ end
54
+ end
55
+
56
+ def type_cast(field, type)
57
+ return if field.is_null
58
+ vmeth = VALUE_METHODS[type] || :string_value
59
+ value = field.public_send(vmeth)
60
+ case type
61
+ when 'DECIMAL' then type_cast_decimal(value)
62
+ when 'DATE' then type_cast_date(value)
63
+ when 'YEAR' then type_cast_year(value)
64
+ else
65
+ value
66
+ end
67
+ end
68
+
69
+ def type_cast_decimal(v)
70
+ BigDecimal(v)
71
+ end
72
+
73
+ def type_cast_date(v)
74
+ Date.parse(v)
75
+ end
76
+
77
+ def type_cast_year(v)
78
+ v.to_i
79
+ end
80
+
81
+ VALUE_METHODS = {
82
+ 'BIT' => :boolean_value,
83
+ 'TINYINT' => :long_value,
84
+ 'SMALLINT' => :long_value,
85
+ 'MEDIUMINT' => :long_value,
86
+ 'INT' => :long_value,
87
+ 'BIGINT' => :long_value,
88
+ 'FLOAT' => :double_value,
89
+ 'DOUBLE' => :double_value,
90
+ 'DECIMAL' => :string_value,
91
+ 'DATE' => :string_value,
92
+ 'DATETIME' => :string_value,
93
+ 'TIMESTAMP' => :string_value,
94
+ 'TIME' => :string_value,
95
+ 'YEAR' => :string_value,
96
+ 'CHAR' => :string_value,
97
+ 'VARCHAR' => :string_value,
98
+ 'BINARY' => :blob_value,
99
+ 'VARBINARY' => :blob_value,
100
+ 'TINYBLOB' => :blob_value,
101
+ 'TINYTEXT' => :string_value,
102
+ 'BLOB' => :blob_value,
103
+ 'TEXT' => :string_value,
104
+ 'MEDIUMBLOB' => :blob_value,
105
+ 'MEDIUMTEXT' => :string_value,
106
+ 'LONGBLOB' => :blob_value,
107
+ 'LONGTEXT' => :string_value,
108
+ }.freeze
109
+ private_constant :VALUE_METHODS
110
+
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
@@ -0,0 +1,7 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module AuroraServerless
4
+ VERSION = "1.0.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_record'
2
+ require 'aws-sdk-rdsdataservice'
3
+ require 'active_record/connection_adapters/aurora_serverless/version'
4
+ require 'active_record/connection_adapters/aurora_serverless/client'
5
+ require 'active_record/connection_adapters/aurora_serverless/abstract'
6
+ # TODO: [PG] Make this a conditional require? Railtie config? Just do both?
7
+ require 'active_record/connection_adapters/aurora_serverless/mysql2'
@@ -0,0 +1 @@
1
+ require 'active_record/connection_adapters/aurora_serverless_adapter'
data/lib/mysql2.rb ADDED
@@ -0,0 +1,4 @@
1
+ # This is here so the Mysql2 gem require will no-op.
2
+ #
3
+ module Mysql2
4
+ end
metadata ADDED
@@ -0,0 +1,217 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-aurora-serverless-adapter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ken Collins
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-rdsdataservice
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: appraisal
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-reporters
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-retry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Amazon Aurora Serverless is an on-demand, auto-scaling configuration
154
+ for Amazon Aurora (MySQL-compatible and PostgreSQL-compatible editions). Perfect
155
+ for small Rails on AWS Lambda.
156
+ email:
157
+ - kcollins@customink.com
158
+ executables: []
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".github/workflows/ci.yaml"
163
+ - ".gitignore"
164
+ - ".ruby-version"
165
+ - CODE_OF_CONDUCT.md
166
+ - Dockerfile-cdk
167
+ - Dockerfile-ci
168
+ - Gemfile
169
+ - Gemfile.lock
170
+ - LICENSE.txt
171
+ - README.md
172
+ - Rakefile
173
+ - activerecord-aurora-serverless-adapter.gemspec
174
+ - bin/_setup
175
+ - bin/_test
176
+ - bin/bootstrap
177
+ - bin/run
178
+ - bin/setup
179
+ - bin/test
180
+ - bin/test-ci-setup
181
+ - docker-compose.yml
182
+ - lib/active_record/connection_adapters/aurora_serverless/abstract.rb
183
+ - lib/active_record/connection_adapters/aurora_serverless/client.rb
184
+ - lib/active_record/connection_adapters/aurora_serverless/gem_hack.rb
185
+ - lib/active_record/connection_adapters/aurora_serverless/mysql2.rb
186
+ - lib/active_record/connection_adapters/aurora_serverless/mysql2/client.rb
187
+ - lib/active_record/connection_adapters/aurora_serverless/mysql2/connection_handling.rb
188
+ - lib/active_record/connection_adapters/aurora_serverless/mysql2/result.rb
189
+ - lib/active_record/connection_adapters/aurora_serverless/version.rb
190
+ - lib/active_record/connection_adapters/aurora_serverless_adapter.rb
191
+ - lib/activerecord-aurora-serverless-adapter.rb
192
+ - lib/mysql2.rb
193
+ homepage: https://github.com/customink/activerecord-aurora-serverless-adapter
194
+ licenses:
195
+ - MIT
196
+ metadata: {}
197
+ post_install_message:
198
+ rdoc_options: []
199
+ require_paths:
200
+ - lib
201
+ required_ruby_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ required_rubygems_version: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
211
+ requirements: []
212
+ rubyforge_project:
213
+ rubygems_version: 2.7.6.2
214
+ signing_key:
215
+ specification_version: 4
216
+ summary: ActiveRecord Adapter for Amazon Aurora Serverless
217
+ test_files: []