ar-octopus 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/.rspec +1 -1
- data/.rubocop.yml +46 -0
- data/.rubocop_todo.yml +52 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -9
- data/Appraisals +4 -0
- data/Rakefile +17 -16
- data/ar-octopus.gemspec +22 -16
- data/gemfiles/rails41.gemfile +7 -0
- data/init.rb +1 -1
- data/lib/ar-octopus.rb +1 -1
- data/lib/octopus.rb +38 -37
- data/lib/octopus/abstract_adapter.rb +0 -2
- data/lib/octopus/association.rb +8 -6
- data/lib/octopus/association_shard_tracking.rb +80 -81
- data/lib/octopus/collection_association.rb +7 -5
- data/lib/octopus/collection_proxy.rb +11 -9
- data/lib/octopus/has_and_belongs_to_many_association.rb +5 -3
- data/lib/octopus/load_balancing.rb +3 -2
- data/lib/octopus/load_balancing/round_robin.rb +12 -8
- data/lib/octopus/migration.rb +117 -108
- data/lib/octopus/model.rb +130 -134
- data/lib/octopus/persistence.rb +1 -1
- data/lib/octopus/proxy.rb +345 -339
- data/lib/octopus/railtie.rb +2 -2
- data/lib/octopus/relation_proxy.rb +6 -1
- data/lib/octopus/scope_proxy.rb +38 -36
- data/lib/octopus/shard_tracking.rb +36 -35
- data/lib/octopus/shard_tracking/attribute.rb +12 -14
- data/lib/octopus/shard_tracking/dynamic.rb +7 -3
- data/lib/octopus/singular_association.rb +5 -3
- data/lib/octopus/slave_group.rb +10 -8
- data/lib/octopus/version.rb +1 -1
- data/rails/init.rb +1 -1
- data/sample_app/autotest/discover.rb +2 -2
- data/sample_app/config/application.rb +1 -1
- data/sample_app/config/boot.rb +1 -1
- data/sample_app/config/environments/test.rb +1 -1
- data/sample_app/config/initializers/session_store.rb +1 -1
- data/sample_app/config/initializers/wrap_parameters.rb +1 -1
- data/sample_app/config/routes.rb +1 -1
- data/sample_app/db/migrate/20100720210335_create_sample_users.rb +2 -2
- data/sample_app/db/schema.rb +10 -10
- data/sample_app/db/seeds.rb +3 -3
- data/sample_app/features/step_definitions/seeds_steps.rb +4 -4
- data/sample_app/features/step_definitions/web_steps.rb +3 -4
- data/sample_app/features/support/env.rb +3 -4
- data/sample_app/features/support/paths.rb +4 -4
- data/sample_app/spec/spec_helper.rb +3 -3
- data/spec/migrations/10_create_users_using_replication.rb +3 -3
- data/spec/migrations/11_add_field_in_all_slaves.rb +3 -3
- data/spec/migrations/12_create_users_using_block.rb +7 -7
- data/spec/migrations/13_create_users_using_block_and_using.rb +4 -4
- data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +2 -2
- data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +2 -2
- data/spec/migrations/1_create_users_on_master.rb +3 -3
- data/spec/migrations/2_create_users_on_canada.rb +3 -3
- data/spec/migrations/3_create_users_on_both_shards.rb +3 -3
- data/spec/migrations/4_create_users_on_shards_of_a_group.rb +3 -3
- data/spec/migrations/5_create_users_on_multiples_groups.rb +2 -2
- data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +3 -3
- data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +3 -3
- data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +3 -3
- data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +4 -4
- data/spec/octopus/association_shard_tracking_spec.rb +413 -417
- data/spec/octopus/collection_proxy_spec.rb +6 -5
- data/spec/octopus/log_subscriber_spec.rb +4 -4
- data/spec/octopus/migration_spec.rb +48 -48
- data/spec/octopus/model_spec.rb +267 -292
- data/spec/octopus/octopus_spec.rb +40 -41
- data/spec/octopus/proxy_spec.rb +124 -124
- data/spec/octopus/relation_proxy_spec.rb +32 -32
- data/spec/octopus/replicated_slave_grouped_spec.rb +23 -23
- data/spec/octopus/replication_spec.rb +61 -66
- data/spec/octopus/scope_proxy_spec.rb +56 -10
- data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +29 -29
- data/spec/octopus/sharded_spec.rb +10 -10
- data/spec/spec_helper.rb +6 -6
- data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +1 -3
- data/spec/support/database_connection.rb +2 -2
- data/spec/support/database_models.rb +16 -17
- data/spec/support/octopus_helper.rb +19 -21
- data/spec/support/query_count.rb +1 -3
- data/spec/support/shared_contexts.rb +3 -3
- data/spec/tasks/octopus.rake_spec.rb +10 -10
- metadata +43 -26
@@ -2,7 +2,6 @@
|
|
2
2
|
module Octopus
|
3
3
|
module AbstractAdapter
|
4
4
|
module OctopusShard
|
5
|
-
|
6
5
|
parent = Octopus.rails3? ? ActiveSupport::BasicObject : ActiveSupport::ProxyObject
|
7
6
|
|
8
7
|
class InstrumenterDecorator < parent
|
@@ -33,7 +32,6 @@ module Octopus
|
|
33
32
|
initialize_without_octopus_shard(*args)
|
34
33
|
@instrumenter = InstrumenterDecorator.new(self, @instrumenter)
|
35
34
|
end
|
36
|
-
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
data/lib/octopus/association.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
module Octopus
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Octopus
|
2
|
+
module Association
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:include, Octopus::ShardTracking::Dynamic)
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def current_shard
|
8
|
+
owner.current_shard
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -1,104 +1,103 @@
|
|
1
|
-
module Octopus
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module QueryOnCurrentShard
|
1
|
+
module Octopus
|
2
|
+
module AssociationShardTracking
|
3
|
+
def self.extended(base)
|
4
|
+
base.send(:include, InstanceMethods)
|
5
|
+
end
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
7
|
+
module QueryOnCurrentShard
|
8
|
+
METHODS = %w(
|
9
|
+
all
|
10
|
+
average
|
11
|
+
count
|
12
|
+
empty?
|
13
|
+
exists?
|
14
|
+
find
|
15
|
+
find_by_sql
|
16
|
+
first
|
17
|
+
last
|
18
|
+
maximum
|
19
|
+
minimum
|
20
|
+
pluck
|
21
|
+
scoping
|
22
|
+
size
|
23
|
+
sum
|
24
|
+
to_a
|
25
|
+
)
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
METHODS.each do |m|
|
28
|
+
define_method m.to_sym do |*args, &block|
|
29
|
+
if self.respond_to?(:proxy_association) && proxy_association
|
30
|
+
proxy_association.owner.run_on_shard { super(*args, &block) }
|
31
|
+
else
|
32
|
+
super(*args, &block)
|
33
|
+
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
|
+
module InstanceMethods
|
39
|
+
def connection_on_association=(record)
|
40
|
+
return unless ::Octopus.enabled?
|
41
|
+
return if !self.class.connection.respond_to?(:current_shard) || !self.respond_to?(:current_shard)
|
42
|
+
if !record.current_shard.nil? && !current_shard.nil? && record.current_shard != current_shard
|
43
|
+
fail 'Association Error: Records are from different shards'
|
44
|
+
end
|
38
45
|
|
39
|
-
|
40
|
-
def set_connection_on_association(record)
|
41
|
-
return unless ::Octopus.enabled?
|
42
|
-
return if !self.class.connection.respond_to?(:current_shard) || !self.respond_to?(:current_shard)
|
43
|
-
if !record.current_shard.nil? && !self.current_shard.nil? && record.current_shard != self.current_shard
|
44
|
-
raise "Association Error: Records are from different shards"
|
46
|
+
record.current_shard = self.class.connection.current_shard = current_shard if should_set_current_shard?
|
45
47
|
end
|
46
|
-
|
47
|
-
record.current_shard = self.class.connection.current_shard = self.current_shard if should_set_current_shard?
|
48
48
|
end
|
49
|
-
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
if Octopus.rails4?
|
51
|
+
def has_many(association_id, scope = nil, options = {}, &extension)
|
52
|
+
if options == {} && scope.is_a?(Hash)
|
53
|
+
default_octopus_opts(scope)
|
54
|
+
else
|
55
|
+
default_octopus_opts(options)
|
56
|
+
end
|
57
|
+
super
|
58
|
+
end
|
59
|
+
else
|
60
|
+
def has_many(association_id, options = {}, &extension)
|
56
61
|
default_octopus_opts(options)
|
62
|
+
super
|
57
63
|
end
|
58
|
-
super
|
59
|
-
end
|
60
|
-
else
|
61
|
-
def has_many(association_id, options={}, &extension)
|
62
|
-
default_octopus_opts(options)
|
63
|
-
super
|
64
64
|
end
|
65
|
-
end
|
66
|
-
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
if Octopus.rails4?
|
67
|
+
def has_and_belongs_to_many(association_id, scope = nil, options = {}, &extension)
|
68
|
+
if options == {} && scope.is_a?(Hash)
|
69
|
+
default_octopus_opts(scope)
|
70
|
+
else
|
71
|
+
default_octopus_opts(options)
|
72
|
+
end
|
73
|
+
super
|
74
|
+
end
|
75
|
+
else
|
76
|
+
def has_and_belongs_to_many(association_id, options = {}, &extension)
|
73
77
|
default_octopus_opts(options)
|
78
|
+
super
|
74
79
|
end
|
75
|
-
super
|
76
|
-
end
|
77
|
-
else
|
78
|
-
def has_and_belongs_to_many(association_id, options={}, &extension)
|
79
|
-
default_octopus_opts(options)
|
80
|
-
super
|
81
80
|
end
|
82
|
-
end
|
83
81
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
def default_octopus_opts(options)
|
83
|
+
if options[:before_add].is_a?(Array)
|
84
|
+
options[:before_add] << :connection_on_association=
|
85
|
+
elsif options[:before_add].is_a?(Symbol)
|
86
|
+
options[:before_add] = [:connection_on_association=, options[:before_add]]
|
87
|
+
else
|
88
|
+
options[:before_add] = :connection_on_association=
|
89
|
+
end
|
92
90
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
91
|
+
if options[:before_remove].is_a?(Array)
|
92
|
+
options[:before_remove] << :connection_on_association=
|
93
|
+
elsif options[:before_remove].is_a?(Symbol)
|
94
|
+
options[:before_remove] = [:connection_on_association=, options[:before_remove]]
|
95
|
+
else
|
96
|
+
options[:before_remove] = :connection_on_association=
|
97
|
+
end
|
100
98
|
|
101
|
-
|
99
|
+
options[:extend] = [Octopus::AssociationShardTracking::QueryOnCurrentShard, options[:extend]].flatten.compact
|
100
|
+
end
|
102
101
|
end
|
103
102
|
end
|
104
103
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
module Octopus
|
2
|
-
|
3
|
-
base
|
4
|
-
|
5
|
-
|
1
|
+
module Octopus
|
2
|
+
module CollectionAssociation
|
3
|
+
def self.included(base)
|
4
|
+
base.sharded_methods :reader, :writer, :ids_reader, :ids_writer, :create, :create!,
|
5
|
+
:build, :any?, :count, :empty?, :first, :include?, :last, :length,
|
6
|
+
:load_target, :many?, :reload, :size, :select, :uniq
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
8
10
|
|
@@ -1,13 +1,15 @@
|
|
1
|
-
module Octopus
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Octopus
|
2
|
+
module CollectionProxy
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:include, Octopus::ShardTracking::Dynamic)
|
5
|
+
base.sharded_methods :any?, :build, :count, :create, :create!, :concat, :delete, :delete_all,
|
6
|
+
:destroy, :destroy_all, :empty?, :find, :first, :include?, :last, :length,
|
7
|
+
:many?, :pluck, :replace, :select, :size, :sum, :to_a, :uniq
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
def current_shard
|
11
|
+
@association.owner.current_shard
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
@@ -2,14 +2,18 @@ require 'octopus/load_balancing'
|
|
2
2
|
|
3
3
|
# The round-robin load balancing of slaves belonging to the same shard.
|
4
4
|
# It is a pool that contains slaves which queries are distributed to.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
module Octopus
|
6
|
+
module LoadBalancing
|
7
|
+
class RoundRobin
|
8
|
+
def initialize(slaves_list)
|
9
|
+
@slaves_list = slaves_list
|
10
|
+
@slave_index = 0
|
11
|
+
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
# Returns the next available slave in the pool
|
14
|
+
def next
|
15
|
+
@slaves_list[@slave_index = (@slave_index + 1) % @slaves_list.length]
|
16
|
+
end
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
data/lib/octopus/migration.rb
CHANGED
@@ -1,155 +1,164 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
module Octopus
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
require 'set'
|
2
|
+
require 'active_support/core_ext/module/aliasing'
|
3
|
+
require 'active_support/core_ext/array/wrap'
|
4
|
+
|
5
|
+
module Octopus
|
6
|
+
module Migration
|
7
|
+
module InstanceOrClassMethods
|
8
|
+
def announce_with_octopus(message)
|
9
|
+
announce_without_octopus("#{message} - #{current_shard}")
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
def current_shard
|
13
|
+
"Shard: #{connection.current_shard}" if connection.respond_to?(:current_shard)
|
14
|
+
end
|
13
15
|
end
|
14
|
-
end
|
15
16
|
|
16
|
-
|
17
|
+
include InstanceOrClassMethods
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
def self.included(base)
|
20
|
+
base.extend(ClassMethods)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
base.alias_method_chain :announce, :octopus
|
23
|
+
base.class_attribute :current_shard, :current_group, :current_group_specified, :instance_reader => false, :instance_writer => false
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
module ClassMethods
|
27
|
+
def using(*args)
|
28
|
+
return self unless connection.is_a?(Octopus::Proxy)
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
self.current_shard = args
|
31
|
+
self
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
def using_group(*groups)
|
35
|
+
return self unless connection.is_a?(Octopus::Proxy)
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
self.current_group = groups
|
38
|
+
self.current_group_specified = true
|
39
|
+
self
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
def shards
|
43
|
+
shards = Set.new
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
if (groups = (current_group_specified ? current_group : Octopus.config[:default_migration_group]))
|
46
|
+
Array.wrap(groups).each do |group|
|
47
|
+
group_shards = connection.shards_for_group(group)
|
48
|
+
shards.merge(group_shards) if group_shards
|
49
|
+
end
|
50
|
+
elsif (shard = current_shard)
|
51
|
+
shards.merge(Array.wrap(shard))
|
48
52
|
end
|
49
|
-
elsif shard = current_shard
|
50
|
-
shards.merge(Array.wrap(shard))
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
+
shards.to_a.presence || [:master]
|
55
|
+
end
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
module Octopus
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
60
|
+
module Octopus
|
61
|
+
module Migrator
|
62
|
+
def self.included(base)
|
63
|
+
base.extend(ClassMethods)
|
64
|
+
|
65
|
+
base.class_eval do
|
66
|
+
class << self
|
67
|
+
alias_method_chain :migrate, :octopus
|
68
|
+
alias_method_chain :up, :octopus
|
69
|
+
alias_method_chain :down, :octopus
|
70
|
+
alias_method_chain :run, :octopus
|
71
|
+
end
|
68
72
|
end
|
69
|
-
end
|
70
73
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
base.alias_method_chain :run, :octopus
|
75
|
+
base.alias_method_chain :migrate, :octopus
|
76
|
+
base.alias_method_chain :migrations, :octopus
|
77
|
+
end
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
def run_with_octopus(&block)
|
80
|
+
run_without_octopus(&block)
|
81
|
+
rescue ActiveRecord::UnknownMigrationVersionError => e
|
82
|
+
raise unless migrations(true).detect { |m| m.version == e.version }
|
83
|
+
end
|
81
84
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
def migrate_with_octopus(&block)
|
86
|
+
migrate_without_octopus(&block)
|
87
|
+
rescue ActiveRecord::UnknownMigrationVersionError => e
|
88
|
+
raise unless migrations(true).detect { |m| m.version == e.version }
|
89
|
+
end
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
91
|
+
def migrations_with_octopus(shard_agnostic = false)
|
92
|
+
connection = ActiveRecord::Base.connection
|
93
|
+
migrations = migrations_without_octopus
|
94
|
+
return migrations if !connection.is_a?(Octopus::Proxy) || shard_agnostic
|
92
95
|
|
93
|
-
|
94
|
-
|
96
|
+
migrations.select { |m| m.shards.include?(connection.current_shard.to_sym) }
|
97
|
+
end
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
+
module ClassMethods
|
100
|
+
def migrate_with_octopus(migrations_paths, target_version = nil, &block)
|
101
|
+
return migrate_without_octopus(migrations_paths, target_version, &block) unless connection.is_a?(Octopus::Proxy)
|
99
102
|
|
100
|
-
|
101
|
-
|
103
|
+
connection.send_queries_to_multiple_shards(connection.shard_names) do
|
104
|
+
migrate_without_octopus(migrations_paths, target_version, &block)
|
105
|
+
end
|
102
106
|
end
|
103
|
-
end
|
104
107
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
def up_with_octopus(migrations_paths, target_version = nil, &block)
|
109
|
+
return up_without_octopus(migrations_paths, target_version, &block) unless connection.is_a?(Octopus::Proxy)
|
110
|
+
return up_without_octopus(migrations_paths, target_version, &block) unless connection.current_shard == :master
|
108
111
|
|
109
|
-
|
110
|
-
|
112
|
+
connection.send_queries_to_multiple_shards(connection.shard_names) do
|
113
|
+
up_without_octopus(migrations_paths, target_version, &block)
|
114
|
+
end
|
111
115
|
end
|
112
|
-
end
|
113
116
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
+
def down_with_octopus(migrations_paths, target_version = nil, &block)
|
118
|
+
return down_without_octopus(migrations_paths, target_version, &block) unless connection.is_a?(Octopus::Proxy)
|
119
|
+
return down_without_octopus(migrations_paths, target_version, &block) unless connection.current_shard == :master
|
117
120
|
|
118
|
-
|
119
|
-
|
121
|
+
connection.send_queries_to_multiple_shards(connection.shard_names) do
|
122
|
+
down_without_octopus(migrations_paths, target_version, &block)
|
123
|
+
end
|
120
124
|
end
|
121
|
-
end
|
122
125
|
|
123
|
-
|
124
|
-
|
126
|
+
def run_with_octopus(direction, migrations_paths, target_version)
|
127
|
+
return run_without_octopus(direction, migrations_paths, target_version) unless connection.is_a?(Octopus::Proxy)
|
125
128
|
|
126
|
-
|
127
|
-
|
129
|
+
connection.send_queries_to_multiple_shards(connection.shard_names) do
|
130
|
+
run_without_octopus(direction, migrations_paths, target_version)
|
131
|
+
end
|
128
132
|
end
|
129
|
-
end
|
130
133
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
+
private
|
135
|
+
|
136
|
+
def connection
|
137
|
+
ActiveRecord::Base.connection
|
138
|
+
end
|
134
139
|
end
|
135
140
|
end
|
136
141
|
end
|
137
142
|
|
138
|
-
module Octopus
|
139
|
-
|
140
|
-
|
143
|
+
module Octopus
|
144
|
+
module MigrationProxy
|
145
|
+
def shards
|
146
|
+
migration.class.shards
|
147
|
+
end
|
141
148
|
end
|
142
149
|
end
|
143
150
|
|
144
|
-
module Octopus
|
145
|
-
|
146
|
-
base
|
147
|
-
|
148
|
-
|
151
|
+
module Octopus
|
152
|
+
module UnknownMigrationVersionError
|
153
|
+
def self.included(base)
|
154
|
+
base.alias_method_chain :initialize, :octopus
|
155
|
+
base.send(:attr_accessor, :version)
|
156
|
+
end
|
149
157
|
|
150
|
-
|
151
|
-
|
152
|
-
|
158
|
+
def initialize_with_octopus(version)
|
159
|
+
@version = version
|
160
|
+
initialize_without_octopus(version)
|
161
|
+
end
|
153
162
|
end
|
154
163
|
end
|
155
164
|
|