sequel-connection_guard 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9deb4fcabe84e3c610ee8041ab0eaa63633f2d7525f47324e9bb2e99bc6de84e
4
+ data.tar.gz: d30029a4edbd19ee0427f09018fa3791e55fa4f6e9d6d38d14f3e6cee52ab4cf
5
+ SHA512:
6
+ metadata.gz: 3f8fa9c222c2169cef6308dca198b6a405133990576c273ff1a4a38be299aea4a035f1fb56820a202cf0a5aed08ffaddab484ceb7f2520affc0ee07a68fcb8d8
7
+ data.tar.gz: 4469478b2db4f9cce22f5cb30a7db36d5edaff74871f103da1a6ec0d8bd4142afb7c6992a5afba68f27fcc6f17d9a8d131f8d9bfa46000e17a79e8ae02483669
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,24 @@
1
+ inherit_gem:
2
+ rubocop-config-umbrellio: lib/rubocop.yml
3
+ armitage-rubocop:
4
+ - lib/rubocop.general.yml
5
+ - lib/rubocop.rspec.yml
6
+
7
+ AllCops:
8
+ TargetRubyVersion: 2.6.3
9
+ Include:
10
+ - sequel-connection_guard.gemspec
11
+ - lib/**/*.rb
12
+ - spec/**/*.rb
13
+ - Gemfile
14
+ - Rakefile
15
+ - bin/console
16
+
17
+ Style/TrailingCommaInArguments:
18
+ EnforcedStyleForMultiline: comma
19
+
20
+ Style/TrailingCommaInArrayLiteral:
21
+ EnforcedStyleForMultiline: comma
22
+
23
+ Style/TrailingCommaInHashLiteral:
24
+ EnforcedStyleForMultiline: comma
@@ -0,0 +1,20 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.1
5
+ - 2.6
6
+ - ruby-head
7
+
8
+ services:
9
+ - postgresql
10
+ addons:
11
+ postgresql: 9.6
12
+
13
+ before_install: gem install bundler
14
+ before_script:
15
+ - psql -c 'create database sequel_connection_guard;' -U postgres
16
+ script:
17
+ - bundle exec rspec
18
+ - bundle exec rubocop
19
+
20
+ cache: bundler
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Alexander Komarov
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,162 @@
1
+ # sequel-connection_guard
2
+ [![Build Status](https://travis-ci.org/umbrellio/sequel-connection_guard.svg?branch=master)](https://travis-ci.org/umbrellio/sequel-connection_guard)
3
+ [![Coverage Status](https://coveralls.io/repos/github/umbrellio/sequel-connection_guard/badge.svg?branch=master)](https://coveralls.io/github/umbrellio/sequel-connection_guard?branch=master)
4
+ [![Gem Version](https://badge.fury.io/rb/sequel-connection_guard.svg)](https://badge.fury.io/rb/sequel-connection_guard)
5
+
6
+ This Sequel extension provides a set of abstractions for working with databases that might not be
7
+ reachable at any given moment in time.
8
+
9
+ **This gem was only tested against PostgreSQL databases.**
10
+
11
+ Goals:
12
+ - Allow to bootstrap an application when a database server is down
13
+ - Allow to safely and explicitly access a database
14
+ - In case connection fails, retry on next attempt
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem 'sequel-connection_guard'
22
+ ```
23
+
24
+ And then execute:
25
+ ```sh
26
+ $ bundle
27
+ ```
28
+
29
+ Enable the extension:
30
+ ```ruby
31
+ Sequel.extension :connection_guard
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ This extension provides two main abstractions for accessing unreliable databases. These are almost
37
+ identical, but one allows you to reach a database handle (instance of `Sequel::Database`) and
38
+ another allows you to reach a Sequel model (instance of `Sequel::Model`).
39
+
40
+ ### Database guard
41
+
42
+ A database guard is what you use to access a database handle. First, you need to instantiate one:
43
+ ```ruby
44
+ ::DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb')
45
+ ```
46
+
47
+ You can perform additional actions upon DB initialization, such as enabling Sequel plugins:
48
+ ```ruby
49
+ ::DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb') do |db|
50
+ db.extension :advisory_locking
51
+ db.extension :pg_json
52
+ end
53
+ ```
54
+
55
+ There are two ways of using the guard.
56
+
57
+ #### Safe access
58
+
59
+ You can safely access the database handle by using `#safe_execute`:
60
+
61
+ ```ruby
62
+ users = DB.safe_execute do
63
+ # if the database is reachable
64
+ alive do |db|
65
+ db[:users].all
66
+ end
67
+
68
+ # if the database could not be reached. NOTE: this is optional
69
+ dead do
70
+ []
71
+ end
72
+ end
73
+ ```
74
+
75
+ #### Unsafe access
76
+
77
+ When you don't care about safety (or you're already inside a `safe_execute` context), use
78
+ `#force_execute`:
79
+
80
+ ```ruby
81
+ users = DB.force_execute { |db| db[:users].all }
82
+ ```
83
+
84
+ #### Accessing a raw database handle
85
+
86
+ Sometimes it's necessary to get access to a raw instance of `Sequel::Database` (for example, when
87
+ using the `database_cleaner` gem). You can get a raw handle like this:
88
+
89
+ ```ruby
90
+ DB.raw_handle
91
+ ```
92
+
93
+ Beware that this will raise `Sequel::DatabaseConnectionError` if the database is currently
94
+ unreachable.
95
+
96
+ ### Model guard
97
+
98
+ A model guard is what you use to access a model handle. To create a model guard:
99
+ ```ruby
100
+ # NOTE: `DB` must be an instance of Sequel::DatabaseGuard
101
+ UserGuard = Sequel::ModelGuard(DB[:users]) do
102
+ one_to_many :cookies, class: 'Cookie::RawModel'
103
+
104
+ def admin?
105
+ role == 'admin'
106
+ end
107
+ end
108
+ ```
109
+
110
+ There are, again, two ways of using the guard.
111
+
112
+ #### Safe access
113
+
114
+ You can safely access the model by using `#safe_execute`:
115
+
116
+ ```ruby
117
+ users = UserGuard.safe_execute do
118
+ # if the database is reachable
119
+ alive do |model|
120
+ model.all
121
+ end
122
+
123
+ # if the database could not be reached. NOTE: this is optional
124
+ dead do
125
+ []
126
+ end
127
+ end
128
+ ```
129
+
130
+ #### Unsafe access
131
+
132
+ When you don't care about safety (or you're already inside a `safe_execute` context), use
133
+ `#force_execute`:
134
+
135
+ ```ruby
136
+ users = UserGuard.force_execute { |model| model.all }
137
+ ```
138
+
139
+ #### Accessing a raw model
140
+
141
+ Sometimes it's necessary to get access to a raw instance of `Sequel::Model` (good examples are
142
+ using this extension with `factory_bot` and describing associations like shown above).
143
+ To get the raw model:
144
+
145
+ ```ruby
146
+ User = UserGuard::RawModel
147
+ ```
148
+
149
+ ## Contributing
150
+
151
+ Bug reports and pull requests are welcome on GitHub at https://github.com/umbrellio/sequel-connection_guard.
152
+
153
+ ## License
154
+
155
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
156
+
157
+ ## Authors
158
+ Created by [Alexander Komarov](https://github.com/akxcv).
159
+
160
+ <a href="https://github.com/umbrellio/">
161
+ <img style="float: left;" src="https://umbrellio.github.io/Umbrellio/supported_by_umbrellio.svg" alt="Supported by Umbrellio" width="439" height="72">
162
+ </a>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'sequel'
6
+
7
+ Sequel.extension :connection_guard
8
+
9
+ require 'pry'
10
+ Pry.start
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sequel/extensions/connection_guard/configuration_error"
4
+ require "sequel/extensions/connection_guard/connection_guard"
5
+ require "sequel/extensions/connection_guard/database_guard"
6
+ require "sequel/extensions/connection_guard/dataset"
7
+ require "sequel/extensions/connection_guard/executor"
8
+ require "sequel/extensions/connection_guard/model_guard"
9
+
10
+ # @api public
11
+ # @since 0.1.0
12
+ module Sequel
13
+ # A constructor for model guards.
14
+ #
15
+ # @param ds [Sequel::ConnectionGuard::Dataset]
16
+ # @param class_body [Proc] Mimics Sequel::Model class body.
17
+ #
18
+ # @example Creating model guards
19
+ # DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb')
20
+ #
21
+ # UserGuard = Sequel::ModelGuard(DB[:users]) do
22
+ # many_to_one :cookies, class: 'CookieGuard::RawModel', key: :user_id
23
+ #
24
+ # def admin?
25
+ # role == 'admin'
26
+ # end
27
+ # end
28
+ #
29
+ # CookieGuard = Sequel::ModelGuard(DB[:cookies])
30
+ #
31
+ # @example Safely accessing a model
32
+ # users = UserGuard.safe_execute do
33
+ # alive do |model|
34
+ # model.all
35
+ # end
36
+ #
37
+ # dead do
38
+ # []
39
+ # end
40
+ # end
41
+ #
42
+ # @example Unsafely accessing a model (raises an exception if connection fails)
43
+ # cookies = UserGuard.force_execute { |model| model.first!(id: id).cookies }
44
+ #
45
+ # @api public
46
+ # @since 0.1.0
47
+ # rubocop:disable Naming/MethodName
48
+ def self.ModelGuard(ds, &class_body)
49
+ model = ConnectionGuard::ModelGuard.new(ds, &class_body)
50
+
51
+ Class.new.tap do |klass|
52
+ klass.define_singleton_method(:safe_execute) do |&block|
53
+ model.safe_execute(&block)
54
+ end
55
+
56
+ klass.define_singleton_method(:force_execute) do |&block|
57
+ model.force_execute(&block)
58
+ end
59
+
60
+ klass.define_singleton_method(:const_missing) do |const_name|
61
+ if const_name == :RawModel
62
+ model.raw_model
63
+ else
64
+ super(const_name)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ # rubocop:enable Naming/MethodName
70
+
71
+ # @see Sequel::ConnectionGuard::DatabaseGuard
72
+ #
73
+ # @api public
74
+ # @since 0.1.0
75
+ DatabaseGuard = ConnectionGuard::DatabaseGuard
76
+
77
+ # @api public
78
+ # @since 0.1.0
79
+ module ConnectionGuard; end
80
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # @api public
6
+ # @since 0.1.0
7
+ ConfigurationError = Class.new(ArgumentError)
8
+ end
9
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # @api private
6
+ # @since 0.1.0
7
+ class ConnectionGuard
8
+ # @param config [String, Hash] database configuration
9
+ # @param initializer [Proc] code to run upon successful connection
10
+ #
11
+ # @api private
12
+ # @since 0.1.0
13
+ def initialize(config, &initializer)
14
+ @config = config
15
+ @initializer = initializer
16
+ @connection = nil
17
+
18
+ try_establish_connection
19
+ end
20
+
21
+ # @raise [Sequel::DatabaseConnectionError] connection failure
22
+ #
23
+ # @api private
24
+ # @since 0.1.0
25
+ def force_execute(&_block)
26
+ try_establish_connection if @connection.nil?
27
+ raise Sequel::DatabaseConnectionError unless connection_established?
28
+
29
+ yield @connection
30
+ end
31
+
32
+ # @raise [Sequel::DatabaseConnectionError] if connection is not established
33
+ #
34
+ # @api private
35
+ # @since 0.1.0
36
+ def raw_handle
37
+ try_establish_connection if @connection.nil?
38
+
39
+ return @connection if connection_established?
40
+ raise Sequel::DatabaseConnectionError
41
+ end
42
+
43
+ private
44
+
45
+ # @return [void]
46
+ #
47
+ # @api private
48
+ # @since 0.1.0
49
+ def try_establish_connection
50
+ @connection = Sequel.connect(@config)
51
+ @initializer&.call(@connection)
52
+ rescue Sequel::DatabaseConnectionError
53
+ end
54
+
55
+ # @return [bool]
56
+ #
57
+ # @api private
58
+ # @since 0.1.0
59
+ def connection_established?
60
+ return false if @connection.nil?
61
+ @connection.test_connection
62
+ rescue Sequel::Error
63
+ false
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # An abstraction for safely accessing Sequel models.
6
+ #
7
+ # @example Creating a database guard
8
+ # DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb')
9
+ #
10
+ # @example Safely accessing the database
11
+ # users = DB.safe_execute do
12
+ # alive do |db|
13
+ # db[:users].all
14
+ # end
15
+ #
16
+ # dead do
17
+ # []
18
+ # end
19
+ # end
20
+ #
21
+ # @example Unsafely accessing the database (raises an exception if connection fails)
22
+ # DB.force_execute { |db| db[:users].insert(email: 'billikota@example.com', role: 'admin') }
23
+ #
24
+ # @api public
25
+ # @since 0.1.0
26
+ class DatabaseGuard
27
+ # @param config [String, Hash] database configuration
28
+ # @param initializer [Proc] code to run upon successful connection
29
+ #
30
+ # @api public
31
+ # @since 0.1.0
32
+ def initialize(config, &initializer)
33
+ @connection_guard = ConnectionGuard.new(config, &initializer)
34
+ end
35
+
36
+ # Safely access the database.
37
+ #
38
+ # @example
39
+ # users = DB.safe_execute do
40
+ # alive { |db| db[:users].all }
41
+ # dead { [] }
42
+ # end
43
+ #
44
+ # @param block [Proc]
45
+ #
46
+ # @api public
47
+ # @since 0.1.0
48
+ def safe_execute(&block)
49
+ executor = Executor.new
50
+ executor.instance_eval(&block)
51
+ @connection_guard.force_execute(&executor.on_alive)
52
+ rescue Sequel::DatabaseConnectionError
53
+ executor.on_dead&.call
54
+ end
55
+
56
+ # Unsafely access the database. Will fail if connection fails.
57
+ #
58
+ # @example
59
+ # DB.force_execute { |db| db[:users].insert(email: 'rustam@example.com') }
60
+ #
61
+ # @param block [Proc]
62
+ # @raise [Sequel::DatabaseConnectionError] connection failure
63
+ #
64
+ # @api public
65
+ # @since 0.1.0
66
+ def force_execute(&block)
67
+ @connection_guard.force_execute(&block)
68
+ end
69
+
70
+ # A raw connection handle. Intended for use in test environments (e.x. with DatabaseCleaner)
71
+ #
72
+ # @raise [Sequel::DatabaseConnectionError] if connection is not established
73
+ #
74
+ # @api public
75
+ # @since 0.1.0
76
+ def raw_handle
77
+ @connection_guard.raw_handle
78
+ end
79
+
80
+ # @param table_name [Symbol]
81
+ # @return [Sequel::ConnectionGuard::Dataset]
82
+ #
83
+ # @api private
84
+ # @since 0.1.0
85
+ def [](table_name)
86
+ Dataset.new(@connection_guard, table_name)
87
+ end
88
+
89
+ # @return [void]
90
+ #
91
+ # @api private
92
+ # @since 0.1.0
93
+ def disconnect
94
+ @connection_guard.force_execute(&:disconnect)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # A value object that stores all the information required to construct a Sequel dataset.
6
+ #
7
+ # @api private
8
+ # @since 0.1.0
9
+ class Dataset
10
+ # @api private
11
+ # @since 0.1.0
12
+ attr_reader :connection_guard, :table_name
13
+
14
+ # @param connection_guard [Sequel::ConnectionGuard::ConnectionGuard]
15
+ # @param table_name [Symbol]
16
+ #
17
+ # @api private
18
+ # @since 0.1.0
19
+ def initialize(connection_guard, table_name)
20
+ @connection_guard = connection_guard
21
+ @table_name = table_name
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # Provides a DSL for accessing the database safely.
6
+ #
7
+ # @example Safely accessing a database
8
+ # DB.safe_execute do
9
+ # alive do |db|
10
+ # db[:users].all
11
+ # end
12
+ #
13
+ # dead do
14
+ # []
15
+ # end
16
+ # end
17
+ #
18
+ # @example Safely accessing a model
19
+ # UserGuard.safe_execute do
20
+ # alive do |model|
21
+ # model.first!
22
+ # end
23
+ #
24
+ # # `dead` handler is optional
25
+ # end
26
+ #
27
+ # @api private
28
+ # @since 0.1.0
29
+ class Executor
30
+ # @api private
31
+ # @since 0.1.0
32
+ attr_reader :on_dead
33
+
34
+ # @param block [Proc]
35
+ #
36
+ # @api private
37
+ # @since 0.1.0
38
+ def alive(&block)
39
+ @on_alive = block
40
+ end
41
+
42
+ # @param block [Proc]
43
+ #
44
+ # @api private
45
+ # @since 0.1.0
46
+ def dead(&block)
47
+ @on_dead = block
48
+ end
49
+
50
+ # @raise [Sequel::ConnectionGuard::ConfigurationError] if an `alive` handler is missing
51
+ #
52
+ # @api private
53
+ # @since 0.1.0
54
+ def on_alive
55
+ raise ConfigurationError, "`alive` handler is required for .safe_execute" if @on_alive.nil?
56
+ @on_alive
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module ConnectionGuard
5
+ # An abstraction for safely accessing Sequel models.
6
+ #
7
+ # @see Sequel.ModelGuard
8
+ #
9
+ # @api public
10
+ # @since 0.1.0
11
+ class ModelGuard
12
+ # @param ds [Sequel::ConnectionGuard::Dataset]
13
+ # @option class_body [Proc]
14
+ #
15
+ # @api private
16
+ # @since 0.1.0
17
+ def initialize(ds, &class_body)
18
+ @connection_guard = ds.connection_guard
19
+ @table_name = ds.table_name
20
+ @class_body = class_body
21
+ @connected = false
22
+ @model = nil
23
+ end
24
+
25
+ # Safely access the model.
26
+ #
27
+ # @example
28
+ # users = UserGuard.safe_execute do
29
+ # alive { |model| model.all }
30
+ # dead { [] }
31
+ # end
32
+ #
33
+ # @param block [Proc]
34
+ #
35
+ # @api public
36
+ # @since 0.1.0
37
+ def safe_execute(&block)
38
+ executor = Executor.new
39
+ executor.instance_eval(&block)
40
+
41
+ @connection_guard.force_execute do |connection|
42
+ instantiate_model(connection) unless @connected
43
+
44
+ executor.on_alive.call(@model)
45
+ end
46
+ rescue Sequel::DatabaseConnectionError
47
+ @connected = false
48
+
49
+ executor.on_dead&.call
50
+ end
51
+
52
+ # Unsafely access the model. Will fail if connection fails.
53
+ #
54
+ # @example
55
+ # UserGuard.force_execute { |model| model.create(email: 'vova@example.com') }
56
+ #
57
+ # @param block [Proc]
58
+ # @raise [Sequel::DatabaseConnectionError] connection failure
59
+ #
60
+ # @api public
61
+ # @since 0.1.0
62
+ def force_execute(&block)
63
+ @connection_guard.force_execute do |connection|
64
+ instantiate_model(connection) unless @connected
65
+
66
+ yield @model
67
+ end
68
+ rescue Sequel::DatabaseConnectionError => error
69
+ @connected = false
70
+ raise error
71
+ end
72
+
73
+ # @api private
74
+ # @since 0.1.0
75
+ def raw_model
76
+ try_instantiate_model if @model.nil?
77
+ @model
78
+ end
79
+
80
+ private
81
+
82
+ # @raise [Sequel::DatabaseConnectionError] connection failure
83
+ #
84
+ # @api private
85
+ # @since 0.1.0
86
+ def instantiate_model(connection)
87
+ if @model.nil?
88
+ @model = Class.new(Sequel::Model(connection[@table_name]))
89
+ @model.class_eval(&@class_body) unless @class_body.nil?
90
+ else
91
+ @model.dataset = connection[@table_name]
92
+ end
93
+
94
+ @connected = true
95
+ end
96
+
97
+ # @api private
98
+ # @since 0.1.0
99
+ def try_instantiate_model
100
+ @connection_guard.force_execute { |connection| instantiate_model(connection) }
101
+ rescue Sequel::DatabaseConnectionError
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.required_ruby_version = ">= 2.5.1"
8
+
9
+ spec.name = "sequel-connection_guard"
10
+ spec.version = "0.1.0"
11
+ spec.authors = ["Alexander Komarov"]
12
+ spec.email = %w[ak@akxcv.com oss@umbrellio.biz]
13
+
14
+ spec.summary = "A set of tools for working with unreliable databases."
15
+ spec.description = "Provides an abstraction for working with unreliable databases safely."
16
+ spec.homepage = "https://github.com/umbrellio/sequel-connection_guard"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+
23
+ spec.require_paths = %w[lib]
24
+
25
+ spec.add_dependency "sequel", "> 5.5"
26
+
27
+ spec.add_development_dependency "bundler"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.8"
30
+ spec.add_development_dependency "armitage-rubocop", "~> 0.33"
31
+ spec.add_development_dependency "rubocop-config-umbrellio", "~> 0.70.0"
32
+ spec.add_development_dependency "pg", "~> 1.0"
33
+ spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "coveralls", "~> 0.8"
35
+ spec.add_development_dependency "simplecov", "~> 0.16"
36
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel-connection_guard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Komarov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
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: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: armitage-rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.33'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.33'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-config-umbrellio
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.70.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.70.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: pg
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.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: coveralls
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.16'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.16'
153
+ description: Provides an abstraction for working with unreliable databases safely.
154
+ email:
155
+ - ak@akxcv.com
156
+ - oss@umbrellio.biz
157
+ executables: []
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".rubocop.yml"
164
+ - ".travis.yml"
165
+ - Gemfile
166
+ - LICENSE
167
+ - README.md
168
+ - Rakefile
169
+ - bin/console
170
+ - bin/setup
171
+ - lib/sequel/extensions/connection_guard.rb
172
+ - lib/sequel/extensions/connection_guard/configuration_error.rb
173
+ - lib/sequel/extensions/connection_guard/connection_guard.rb
174
+ - lib/sequel/extensions/connection_guard/database_guard.rb
175
+ - lib/sequel/extensions/connection_guard/dataset.rb
176
+ - lib/sequel/extensions/connection_guard/executor.rb
177
+ - lib/sequel/extensions/connection_guard/model_guard.rb
178
+ - sequel-connection_guard.gemspec
179
+ homepage: https://github.com/umbrellio/sequel-connection_guard
180
+ licenses:
181
+ - MIT
182
+ metadata: {}
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: 2.5.1
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ requirements: []
198
+ rubygems_version: 3.0.3
199
+ signing_key:
200
+ specification_version: 4
201
+ summary: A set of tools for working with unreliable databases.
202
+ test_files: []