ar_shard 0.2.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fb30eeafede0838d558ae4886d8f2c4f517f4f182435120ba0a7216568e50dc6
4
+ data.tar.gz: c1b60bd917fcb034565f33192582d1338a406495483f3c34af827a41d6e8dd62
5
+ SHA512:
6
+ metadata.gz: 1ffca4562eabdd5f2ee9b5481d613d3f1619618e6829ce885f91dc58530237d5d90e0066fbff0695e06a827cae19e06a7d258bfdd009db5122a96a9ab37748b9
7
+ data.tar.gz: 0a6c6032fe0aa90979a839a1c76f82c48d6f4e3e4c3213b3f3e31958336fe6fb7c6b433c33879c61f1e0be024a642a55e1254a89076bc015f070268669e3dc1a
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.5.3
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,17 @@
1
+ ## 0.2.2
2
+ - Fixed missing connection if loaded from YAML
3
+ - Added tests for multiple connection switches with another block
4
+
5
+ ## 0.2.1
6
+
7
+ - Added support for Proc in config
8
+ - Fixed AR poluting
9
+ - Removed Rails dependency
10
+
11
+ ## 0.2.0
12
+
13
+ - Extracted to be a gem
14
+
15
+ ## 0.1.0
16
+
17
+ - Initial Idea
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ar_shard.gemspec
4
+ gemspec
5
+
6
+ gem 'rake', '~> 12.0'
7
+ gem 'minitest', '~> 5.0'
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ar_shard (0.2.2)
5
+ activerecord (>= 6)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (6.0.3.2)
11
+ activesupport (= 6.0.3.2)
12
+ activerecord (6.0.3.2)
13
+ activemodel (= 6.0.3.2)
14
+ activesupport (= 6.0.3.2)
15
+ activesupport (6.0.3.2)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 0.7, < 2)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ zeitwerk (~> 2.2, >= 2.2.2)
21
+ coderay (1.1.3)
22
+ concurrent-ruby (1.1.7)
23
+ i18n (1.8.5)
24
+ concurrent-ruby (~> 1.0)
25
+ method_source (1.0.0)
26
+ minitest (5.11.3)
27
+ pry (0.13.1)
28
+ coderay (~> 1.1)
29
+ method_source (~> 1.0)
30
+ rake (12.3.2)
31
+ sqlite3 (1.4.2)
32
+ thread_safe (0.3.6)
33
+ tzinfo (1.2.7)
34
+ thread_safe (~> 0.1)
35
+ zeitwerk (2.4.0)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ ar_shard!
42
+ minitest (~> 5.0)
43
+ pry
44
+ rake (~> 12.0)
45
+ sqlite3 (~> 1.4)
46
+
47
+ BUNDLED WITH
48
+ 1.17.3
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Alex Tsirel
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,89 @@
1
+ # AR Shard
2
+
3
+ AR Shard is non-intrusive extenstion for ActiveRecord to add threadsafe Model based sharding or just multidatabase connection. As this gem uses connection_handlers it can work only with ActiveRecord 6 and above.
4
+
5
+ ## Features
6
+ - Shard only part of you ActiveRecord w/o sharing connection
7
+ - Work with you Sharded Model and AR model at the same time
8
+ - Threadsafe. Battle-tested with Sidekiq and 4 mixed Databases
9
+ - Define config as a Proc. `Due to nature of connection_handlers all DB connections are established at boot time`
10
+
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application’s Gemfile:
15
+
16
+ ```ruby
17
+ gem 'ar_shard', '~> 0.2'
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Define your separate AR like:
23
+
24
+ ```ruby
25
+ class ShardRecord < ActiveRecord::Base
26
+ self.abstract_class = true
27
+
28
+ connected_shards shards: [
29
+ { shard_1: { adapter: 'sqlite3', database: 'shard_1' } },
30
+ { shard_2: { adapter: 'postgresql', database: 'shard_2' } },
31
+ { shard_3: { adapter: 'sqlite3', database: 'shard_3' } }
32
+ ]
33
+ end
34
+ ```
35
+
36
+ or with Proc
37
+
38
+ ```ruby
39
+ class ShardRecord < ActiveRecord::Base
40
+ self.abstract_class = true
41
+
42
+ connected_shards shards: -> { YAML.load_file('path/to/config/shards.yml') }
43
+ end
44
+ ```
45
+
46
+ given we have models like:
47
+
48
+ ```ruby
49
+ class User < ActiveRecord::Base
50
+
51
+ end
52
+
53
+ class Sharded::User < ShardRecord
54
+
55
+ end
56
+ ```
57
+
58
+ AR Shard is isolating and rotating connections. Same like Rails Multibase support but without overlap.
59
+ Now we can do crazy things like:
60
+
61
+ ```ruby
62
+ # Connecting to another DB
63
+ ShardRecord.with_shard(:shard_name) do
64
+ Sharded::User.find_each do |user|
65
+ # Working with our DB and another at the same time!
66
+
67
+ u = User.find_by(email: user.email)
68
+ u.update(name: user.name)
69
+ end
70
+ end
71
+ ```
72
+
73
+ ## Contributing
74
+
75
+ - [Report bugs](https://github.com/noma4i/ar_shard/issues)
76
+ - Fix bugs and [submit pull requests](https://github.com/noma4i/ar_shard/pulls)
77
+
78
+ To get started with development:
79
+
80
+ ```sh
81
+ git clone https://github.com/noma4i/ar_shard.git
82
+ cd ar_shard
83
+ bundle install
84
+ bundle exec rake test
85
+ ```
86
+
87
+ ## License
88
+
89
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task default: :test
@@ -0,0 +1,31 @@
1
+ require_relative 'lib/ar_shard/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'ar_shard'
5
+ spec.version = ARShard::VERSION
6
+ spec.authors = ['Alex Tsirel']
7
+ spec.email = ['noma4i@gmail.com']
8
+
9
+ spec.summary = 'Isolated Multibase Support for ActiveRecord Models with dynamic config'
10
+ spec.description = 'Isolated Multibase Support for ActiveRecord Models with dynamic config'
11
+ spec.homepage = 'https://github.com/noma4i/ar_shard'
12
+ spec.license = 'MIT'
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
14
+
15
+ spec.metadata['homepage_uri'] = spec.homepage
16
+ spec.metadata['source_code_uri'] = 'https://github.com/noma4i/ar_shard'
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = 'exe'
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.add_dependency 'activerecord', '>= 6'
28
+
29
+ spec.add_development_dependency 'pry'
30
+ spec.add_development_dependency 'sqlite3', '~> 1.4'
31
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'ar_shard'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ require 'ar_shard/version'
2
+ require 'ar_shard/active_record'
3
+
4
+ module ARShard
5
+ class Error < StandardError; end
6
+ end
@@ -0,0 +1,59 @@
1
+ require 'active_record'
2
+ require 'pry'
3
+
4
+ module ActiveRecord
5
+ mattr_accessor :klass_name
6
+
7
+ class Base
8
+ mattr_accessor :isolated_connection
9
+
10
+ def self.add_shared_override!
11
+ shard_model.define_singleton_method(:connection) do
12
+ @@isolated_connection || retrieve_connection
13
+ end
14
+ end
15
+ end
16
+
17
+ module ConnectionHandling
18
+ def connected_shards(shards: nil)
19
+ @connected_shards ||= begin
20
+ config_data = parse_config(shards)
21
+ @@klass_name = self.name
22
+ connections = {}
23
+
24
+ shard_model.add_shared_override!
25
+
26
+ config_data.each do |shard|
27
+ key, conf = shard.flatten
28
+ handler = lookup_connect(key.to_sym)
29
+
30
+ connections[key.to_sym] = handler.establish_connection(conf)
31
+ end
32
+
33
+ connections
34
+ end
35
+ end
36
+
37
+ def parse_config(config)
38
+ return config.call if config.is_a?(Proc)
39
+ return config if config.is_a?(Array)
40
+
41
+ raise ARShard::Error.new 'Shard config should be Array or Proc'
42
+ end
43
+
44
+ def shard_model
45
+ @shard_model ||= @@klass_name.constantize
46
+ end
47
+
48
+ def lookup_connect(handler_key)
49
+ connection_handlers[handler_key] ||= ActiveRecord::ConnectionAdapters::ConnectionHandler.new
50
+ end
51
+
52
+ def with_shard(handler_key, &blk)
53
+ shard_model.isolated_connection = connected_shards[handler_key].connection
54
+ yield
55
+ ensure
56
+ shard_model.isolated_connection = nil
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module ARShard
2
+ VERSION = "0.2.2"
3
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ar_shard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Alex Tsirel
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-15 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'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.4'
55
+ description: Isolated Multibase Support for ActiveRecord Models with dynamic config
56
+ email:
57
+ - noma4i@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - CHANGELOG.md
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - ar_shard.gemspec
71
+ - bin/console
72
+ - bin/setup
73
+ - lib/ar_shard.rb
74
+ - lib/ar_shard/active_record.rb
75
+ - lib/ar_shard/version.rb
76
+ homepage: https://github.com/noma4i/ar_shard
77
+ licenses:
78
+ - MIT
79
+ metadata:
80
+ homepage_uri: https://github.com/noma4i/ar_shard
81
+ source_code_uri: https://github.com/noma4i/ar_shard
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 2.3.0
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubygems_version: 3.0.8
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Isolated Multibase Support for ActiveRecord Models with dynamic config
101
+ test_files: []