octoshark 0.1.2 → 0.3.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.
data/Rakefile CHANGED
@@ -10,16 +10,16 @@ task :default => :spec
10
10
 
11
11
  namespace :db do
12
12
  task :establish_connection do
13
- configs = YAML.load_file('spec/support/config.yml').with_indifferent_access
14
- config = configs[:db1].except(:database)
15
- @databases = configs.map { |_, config| config[:database] }
13
+ configs = YAML.load_file('spec/support/config.yml')
14
+ config = configs['db1'].reject { |k, v| k == 'database' }
15
+ @databases = configs.map { |_, config| config['database'] }
16
16
  ActiveRecord::Base.establish_connection(config)
17
17
  end
18
18
 
19
19
  task :create => :establish_connection do
20
20
  @databases.each do |database|
21
21
  begin
22
- ActiveRecord::Base.connection.create_database(database)
22
+ ActiveRecord::Base.connection.create_database(database, charset: 'utf8')
23
23
  puts "#{database} created."
24
24
  rescue ActiveRecord::StatementInvalid => e
25
25
  if e.message.match /database exists/
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.0.0"
6
+ gem "mysql2", "< 0.3"
7
+ gem "sqlite3", "~> 1.3.13"
8
+
9
+ gemspec path: "../"
@@ -3,5 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 3.1.0"
6
+ gem "mysql2", "~> 0.3.10"
7
+ gem "sqlite3", "~> 1.3.13"
6
8
 
7
- gemspec :path => "../"
9
+ gemspec path: "../"
@@ -3,5 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 3.2.0"
6
+ gem "mysql2", "~> 0.3.10"
7
+ gem "sqlite3", "~> 1.3.13"
6
8
 
7
- gemspec :path => "../"
9
+ gemspec path: "../"
@@ -3,5 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 4.0.0"
6
+ gem "mysql2", "~> 0.3.10"
7
+ gem "sqlite3", "~> 1.3.13"
6
8
 
7
- gemspec :path => "../"
9
+ gemspec path: "../"
@@ -3,5 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 4.1.0"
6
+ gem "mysql2", "~> 0.3.13"
7
+ gem "sqlite3", "~> 1.3.13"
6
8
 
7
- gemspec :path => "../"
9
+ gemspec path: "../"
@@ -3,5 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "activerecord", "~> 4.2.0"
6
+ gem "mysql2", "~> 0.3.13"
7
+ gem "sqlite3", "~> 1.3.13"
6
8
 
7
- gemspec :path => "../"
9
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0"
6
+ gem "mysql2", "~> 0.5.2"
7
+ gem "sqlite3", "~> 1.3.13"
8
+
9
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.1.0"
6
+ gem "mysql2", "~> 0.5.2"
7
+ gem "sqlite3", "~> 1.4.1"
8
+
9
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.2.0"
6
+ gem "mysql2", "~> 0.5.2"
7
+ gem "sqlite3", "~> 1.4.1"
8
+
9
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 6.0.0"
6
+ gem "mysql2", "~> 0.5.2"
7
+ gem "sqlite3", "~> 1.4.1"
8
+
9
+ gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 6.1.0"
6
+ gem "mysql2", "~> 0.5.2"
7
+ gem "sqlite3", "~> 1.4.1"
8
+
9
+ gemspec path: "../"
data/lib/octoshark.rb CHANGED
@@ -3,23 +3,8 @@ require 'active_record'
3
3
  require 'octoshark/active_record_extensions'
4
4
 
5
5
  module Octoshark
6
- autoload :ConnectionManager, 'octoshark/connection_manager'
7
- autoload :Error, 'octoshark/error'
8
-
9
- # Octoshark needs to keep track of all connection managers in order to
10
- # automatically reconnect on connection establish.
11
- @@connection_managers = []
12
-
13
- def self.connection_managers
14
- @@connection_managers
15
- end
16
-
17
- def self.reset_connection_managers!
18
- connection_managers.map(&:reset!)
19
- end
20
-
21
- def self.disconnect!
22
- connection_managers.map(&:disconnect!)
23
- @@connection_managers = []
24
- end
6
+ autoload :CurrentConnection, 'octoshark/current_connection'
7
+ autoload :ConnectionManager, 'octoshark/connection_manager'
8
+ autoload :ConnectionPoolsManager, 'octoshark/connection_pools_manager'
9
+ autoload :Error, 'octoshark/error'
25
10
  end
@@ -1,47 +1,31 @@
1
1
  module Octoshark
2
- module ActiveRecordBase
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- class << self
7
- alias_method_chain :establish_connection, :octoshark
8
- end
9
- end
10
-
11
- module ClassMethods
12
- # When a connection is established in an ancestor process that must have
13
- # subsequently forked, ActiveRecord establishes a new connection because
14
- # it can't reuse the existing one. When that happens, we need to reconnect
15
- # Octoshark connection managers.
16
- def establish_connection_with_octoshark(*args)
17
- establish_connection_without_octoshark(*args)
18
- Octoshark.reset_connection_managers!
19
- end
2
+ module ConnectionHandler
3
+ def establish_connection(*args)
4
+ Octoshark::ConnectionPoolsManager.reset_connection_managers!
5
+ super(*args)
20
6
  end
21
7
  end
22
8
 
23
9
  module ActiveRecordAbstractAdapter
24
- extend ActiveSupport::Concern
25
-
26
10
  attr_accessor :connection_name, :database_name
27
11
 
28
- included do
29
- alias_method_chain :log, :octoshark
30
- end
31
-
32
- def log_with_octoshark(sql, name = "SQL", *other_args, &block)
33
- if connection_name
34
- if database_name
35
- name = "[Octoshark: #{connection_name} #{database_name}] #{name}"
36
- else
37
- name = "[Octoshark: #{connection_name}] #{name}"
38
- end
12
+ def log(sql, name = "SQL", *other_args, &block)
13
+ if connection_name || database_name
14
+ name = "[Octoshark: #{[connection_name, database_name].compact.join(' ')}] #{name}"
39
15
  end
40
16
 
41
- log_without_octoshark(sql, name, *other_args, &block)
17
+ super(sql, name, *other_args, &block)
42
18
  end
43
19
  end
44
20
  end
45
21
 
46
- ActiveRecord::Base.send(:include, Octoshark::ActiveRecordBase)
47
- ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, Octoshark::ActiveRecordAbstractAdapter)
22
+ if defined?(ActiveRecord::ConnectionAdapters::ConnectionHandler)
23
+ # Rails 3.2, 4.0, 4.1, 4.2, 5.0
24
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, Octoshark::ConnectionHandler)
25
+ else
26
+ # Rails 3.0 and 3.1 does not lazy load
27
+ require 'active_record/connection_adapters/abstract_adapter'
28
+ ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, Octoshark::ConnectionHandler)
29
+ end
30
+
31
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:prepend, Octoshark::ActiveRecordAbstractAdapter)
@@ -1,118 +1,20 @@
1
1
  module Octoshark
2
2
  class ConnectionManager
3
+ include CurrentConnection
3
4
 
4
- attr_reader :connection_pools
5
+ def with_connection(config, connection_name: nil, &block)
6
+ connection_method = "#{config[:adapter]}_connection"
5
7
 
6
- def initialize(configs = {})
7
- @configs = configs.with_indifferent_access
8
- setup_connection_pools
9
-
10
- Octoshark.connection_managers << self
11
- end
12
-
13
- def reset!
14
- disconnect!
15
- setup_connection_pools
16
- end
17
-
18
- def current_connection
19
- Thread.current[identifier] || raise(Octoshark::Error::NoCurrentConnection, "No current connection")
20
- end
21
-
22
- def current_connection?
23
- !Thread.current[identifier].nil?
24
- end
25
-
26
- def current_or_default_connection
27
- Thread.current[identifier] || ActiveRecord::Base.connection_pool.connection
28
- end
29
-
30
- def with_connection(name, &block)
31
- connection_pool = find_connection_pool(name)
32
- with_connection_pool(name, connection_pool, &block)
33
- end
34
-
35
- def with_new_connection(name, config, reusable: false, &block)
36
- if reusable
37
- connection_pool = @connection_pools[name] ||= create_connection_pool(config)
38
- with_connection_pool(name, connection_pool, &block)
39
- else
40
- connection_pool = create_connection_pool(config)
41
- with_connection_pool(name, connection_pool, &block).tap do
42
- connection_pool.disconnect!
43
- end
44
- end
45
- end
46
-
47
- def use_database(name, database_name, &block)
48
- connection_pool = find_connection_pool(name)
49
- with_connection_pool(name, connection_pool, database_name, &block)
50
- end
51
-
52
- def without_connection(&block)
53
- change_connection_reference(nil) do
54
- yield
55
- end
56
- end
57
-
58
- def find_connection_pool(name)
59
- @connection_pools[name] || raise(Octoshark::Error::NoConnection, "No such database connection '#{name}'")
60
- end
61
-
62
- def disconnect!
63
- @connection_pools.values.each do |connection_pool|
64
- connection_pool.disconnect!
65
- end
66
- end
67
-
68
- def identifier
69
- @identifier ||= "octoshark_#{object_id}"
70
- end
71
-
72
- private
73
- def spec_class
74
- if defined?(ActiveRecord::ConnectionAdapters::ConnectionSpecification)
75
- spec_class = ActiveRecord::ConnectionAdapters::ConnectionSpecification
76
- else
77
- spec_class = ActiveRecord::Base::ConnectionSpecification
78
- end
79
- end
80
-
81
- def change_connection_reference(connection, &block)
82
- previous_connection = Thread.current[identifier]
83
- Thread.current[identifier] = connection
8
+ connection = ActiveRecord::Base.send(connection_method, config)
9
+ connection.connection_name = connection_name
10
+ connection.database_name = config[:database] if config[:database]
84
11
 
85
12
  begin
86
- yield
87
- ensure
88
- Thread.current[identifier] = previous_connection
89
- end
90
- end
91
-
92
- def setup_connection_pools
93
- @connection_pools = HashWithIndifferentAccess.new
94
-
95
- @configs.each_pair do |name, config|
96
- @connection_pools[name] = create_connection_pool(config)
97
- end
98
- end
99
-
100
- def create_connection_pool(config)
101
- spec = spec_class.new(config, "#{config[:adapter]}_connection")
102
- ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
103
- end
104
-
105
- def with_connection_pool(name, connection_pool, database_name = nil, &block)
106
- connection_pool.with_connection do |connection|
107
- connection.connection_name = name
108
- if database_name
109
- connection.database_name = database_name
110
- connection.execute("use #{database_name}")
111
- end
112
-
113
13
  change_connection_reference(connection) do
114
14
  yield(connection)
115
15
  end
16
+ ensure
17
+ connection.disconnect!
116
18
  end
117
19
  end
118
20
  end
@@ -0,0 +1,97 @@
1
+ module Octoshark
2
+ class ConnectionPoolsManager
3
+ include CurrentConnection
4
+
5
+ # Octoshark needs to keep track of all persistent connection managers
6
+ # in order to automatically reconnect on connection establish.
7
+ @@connection_managers = []
8
+
9
+ def self.connection_managers
10
+ @@connection_managers
11
+ end
12
+
13
+ def self.reset_connection_managers!
14
+ connection_managers.each(&:reset!)
15
+ end
16
+
17
+ def self.disconnect!
18
+ connection_managers.map(&:disconnect!)
19
+ @@connection_managers = []
20
+ end
21
+
22
+ attr_reader :connection_pools
23
+
24
+ def initialize(configs = {})
25
+ @configs = configs.with_indifferent_access
26
+ setup_connection_pools
27
+
28
+ self.class.connection_managers << self
29
+ end
30
+
31
+ def reset!
32
+ disconnect!
33
+ setup_connection_pools
34
+ end
35
+
36
+ def with_connection(name, database_name = nil, &block)
37
+ connection_pool = find_connection_pool(name)
38
+
39
+ connection_pool.with_connection do |connection|
40
+ connection.connection_name = name
41
+
42
+ if database_name
43
+ connection.database_name = database_name
44
+ connection.execute("use #{database_name}")
45
+ end
46
+
47
+ change_connection_reference(connection) do
48
+ yield(connection)
49
+ end
50
+ end
51
+ end
52
+
53
+ def find_connection_pool(name)
54
+ @connection_pools[name] || raise(Octoshark::Error::NoConnection, "No such database connection '#{name}'")
55
+ end
56
+
57
+ def disconnect!
58
+ @connection_pools.values.each do |connection_pool|
59
+ connection_pool.disconnect!
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def setup_connection_pools
66
+ @connection_pools = HashWithIndifferentAccess.new
67
+
68
+ @configs.each_pair do |name, config|
69
+ @connection_pools[name] = create_connection_pool(name, config)
70
+ end
71
+ end
72
+
73
+ def create_connection_pool(name, config)
74
+ spec =
75
+ if defined?(ActiveRecord::ConnectionAdapters::PoolConfig)
76
+ env_name = defined?(Rails) ? Rails.env : nil
77
+ db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, name, config)
78
+ ActiveRecord::ConnectionAdapters::PoolConfig.new(owner_name = ActiveRecord::Base, db_config)
79
+ else
80
+ adapter_method = "#{config[:adapter]}_connection"
81
+ if defined?(ActiveRecord::ConnectionAdapters::ConnectionSpecification)
82
+ spec_class = ActiveRecord::ConnectionAdapters::ConnectionSpecification
83
+
84
+ if spec_class.instance_method(:initialize).arity == 3
85
+ spec_class.new(name, config, adapter_method)
86
+ else
87
+ spec_class.new(config, adapter_method)
88
+ end
89
+ else
90
+ ActiveRecord::Base::ConnectionSpecification.new(config, adapter_method)
91
+ end
92
+ end
93
+
94
+ ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
95
+ end
96
+ end
97
+ end