octoshark 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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