secondbase 0.5.0 → 0.6.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/CHANGELOG.md +8 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +9 -5
- data/VERSION +1 -1
- data/lib/secondbase.rb +2 -1
- data/lib/secondbase/active_record/associations/has_and_belongs_to_many_association.rb +66 -0
- data/lib/secondbase/active_record/base.rb +13 -0
- data/lib/secondbase/{fixtures.rb → active_record/fixtures.rb} +1 -3
- data/lib/secondbase/active_record/patches.rb +13 -0
- data/lib/secondbase/active_record/test_fixtures.rb +32 -0
- data/lib/secondbase/model.rb +1 -2
- data/secondbase.gemspec +14 -13
- metadata +27 -23
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## 0.6
|
4
|
+
|
5
|
+
* This version of the gem ONLY SUPPORTS Rails 3.x. For 2.x support, check out the branch 'rails_2_3' (or version .5 of the gem)
|
6
|
+
* patched has_and_belongs_to_many associations, for secondbase models, so that ActiveRecord understands that the join table is in the secondbase.
|
7
|
+
* patched ActiveRecord::TestFixtures so that transactional fixture support is respected for the SecondBase.
|
8
|
+
* reorganized monkey patches to make it easier to work in fixes for different versions of rails.
|
data/Gemfile
CHANGED
@@ -7,7 +7,7 @@ source "http://rubygems.org"
|
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
9
|
gem "shoulda", ">= 0"
|
10
|
-
gem "bundler", "
|
11
|
-
gem "jeweler", "~> 1.
|
10
|
+
gem "bundler", ">= 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.8.2"
|
12
12
|
gem "activerecord", "~> 3.0.0"
|
13
13
|
end
|
data/Gemfile.lock
CHANGED
@@ -16,11 +16,15 @@ GEM
|
|
16
16
|
builder (2.1.2)
|
17
17
|
git (1.2.5)
|
18
18
|
i18n (0.4.1)
|
19
|
-
jeweler (1.
|
20
|
-
bundler (~> 1.0
|
19
|
+
jeweler (1.8.4)
|
20
|
+
bundler (~> 1.0)
|
21
21
|
git (>= 1.2.5)
|
22
22
|
rake
|
23
|
-
|
23
|
+
rdoc
|
24
|
+
json (1.7.5)
|
25
|
+
rake (0.9.2.2)
|
26
|
+
rdoc (3.12)
|
27
|
+
json (~> 1.4)
|
24
28
|
shoulda (2.11.1)
|
25
29
|
tzinfo (0.3.23)
|
26
30
|
|
@@ -29,6 +33,6 @@ PLATFORMS
|
|
29
33
|
|
30
34
|
DEPENDENCIES
|
31
35
|
activerecord (~> 3.0.0)
|
32
|
-
bundler (
|
33
|
-
jeweler (~> 1.
|
36
|
+
bundler (>= 1.0.0)
|
37
|
+
jeweler (~> 1.8.2)
|
34
38
|
shoulda
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/lib/secondbase.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'active_record'
|
2
|
+
require 'secondbase/active_record/patches'
|
2
3
|
|
3
4
|
module SecondBase
|
4
5
|
CONNECTION_PREFIX = 'secondbase'
|
5
6
|
|
6
|
-
require 'secondbase/railtie'
|
7
|
+
require 'secondbase/railtie'
|
7
8
|
require 'secondbase/rake_method_chain'
|
8
9
|
|
9
10
|
def self.do
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
# = Active Record Has And Belongs To Many Association
|
3
|
+
module Associations
|
4
|
+
class HasAndBelongsToManyAssociation < AssociationCollection
|
5
|
+
|
6
|
+
# determines the appropriate engine for the join table's parent klass
|
7
|
+
def arel_engine
|
8
|
+
Arel::Sql::Engine.new(@reflection.klass.engine)
|
9
|
+
end
|
10
|
+
|
11
|
+
# This method is entirely replicated, except for line 25. We simply
|
12
|
+
# need to pass in the appropriate engine to Arel.
|
13
|
+
def insert_record(record, force = true, validate = true)
|
14
|
+
if record.new_record?
|
15
|
+
if force
|
16
|
+
record.save!
|
17
|
+
else
|
18
|
+
return false unless record.save(:validate => validate)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if @reflection.options[:insert_sql]
|
23
|
+
@owner.connection.insert(interpolate_and_sanitize_sql(@reflection.options[:insert_sql], record))
|
24
|
+
else
|
25
|
+
relation = Arel::Table.new(@reflection.options[:join_table], arel_engine)
|
26
|
+
timestamps = record_timestamp_columns(record)
|
27
|
+
timezone = record.send(:current_time_from_proper_timezone) if timestamps.any?
|
28
|
+
|
29
|
+
attributes = Hash[columns.map do |column|
|
30
|
+
name = column.name
|
31
|
+
value = case name.to_s
|
32
|
+
when @reflection.primary_key_name.to_s
|
33
|
+
@owner.id
|
34
|
+
when @reflection.association_foreign_key.to_s
|
35
|
+
record.id
|
36
|
+
when *timestamps
|
37
|
+
timezone
|
38
|
+
else
|
39
|
+
@owner.send(:quote_value, record[name], column) if record.has_attribute?(name)
|
40
|
+
end
|
41
|
+
[relation[name], value] unless value.nil?
|
42
|
+
end]
|
43
|
+
|
44
|
+
relation.insert(attributes)
|
45
|
+
end
|
46
|
+
|
47
|
+
return true
|
48
|
+
end
|
49
|
+
|
50
|
+
# This method is entirely replicated, except for line 57. We simply
|
51
|
+
# need to pass in the appropriate engine to Arel.
|
52
|
+
def delete_records(records)
|
53
|
+
if sql = @reflection.options[:delete_sql]
|
54
|
+
records.each { |record| @owner.connection.delete(interpolate_and_sanitize_sql(sql, record)) }
|
55
|
+
else
|
56
|
+
|
57
|
+
relation = Arel::Table.new(@reflection.options[:join_table], arel_engine)
|
58
|
+
|
59
|
+
relation.where(relation[@reflection.primary_key_name].eq(@owner.id).
|
60
|
+
and(relation[@reflection.association_foreign_key].in(records.map { |x| x.id }.compact))
|
61
|
+
).delete
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class Base
|
3
|
+
|
4
|
+
# Arel is concerned with "engines". Normally the engine defaults to the primary
|
5
|
+
# connection (ActiveRecord::Base). This will let us easily override the engine
|
6
|
+
# when dealing with Seoncdbase models (deep in ActiveRecord code).
|
7
|
+
# Since SecondBase::Base inherits from ActiveRecord::Base, this will pass the
|
8
|
+
# right engine around.
|
9
|
+
def self.engine
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'secondbase/model'
|
2
|
-
|
3
1
|
###########################
|
4
2
|
# Monkey patch Fixtures
|
5
3
|
# Fixtures needs to load fixtures into the database defined by the parent class!
|
@@ -7,7 +5,7 @@ require 'secondbase/model'
|
|
7
5
|
# I feel like the concepts here could be incorporated directly into Fixtures.
|
8
6
|
# I mean, they shouldn't be so presumptions to think that every model lives in the
|
9
7
|
# same database....
|
10
|
-
class Fixtures
|
8
|
+
class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
|
11
9
|
def self.create_fixtures(fixtures_directory, table_names, class_names = {})
|
12
10
|
table_names = [table_names].flatten.map { |n| n.to_s }
|
13
11
|
table_names.each { |n| class_names[n.tr('/', '_').to_sym] = n.classify if n.include?('/') }
|
@@ -0,0 +1,13 @@
|
|
1
|
+
####################
|
2
|
+
## ActiveRecord patches for all versions of rails
|
3
|
+
require 'secondbase/active_record/base'
|
4
|
+
|
5
|
+
|
6
|
+
####################
|
7
|
+
## ActiveRecord patches for specific versions of rails
|
8
|
+
if Rails.env.test?
|
9
|
+
require 'secondbase/active_record/fixtures'
|
10
|
+
require 'secondbase/active_record/test_fixtures'
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'secondbase/active_record/associations/has_and_belongs_to_many_association'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
## ActiveRecord::TestFixtures
|
2
|
+
## Monkey patch active record's test_fixtures module to manage
|
3
|
+
## transactions for the SecondBase
|
4
|
+
module ActiveRecord
|
5
|
+
module TestFixtures
|
6
|
+
alias_method :original_setup_fixtures, :setup_fixtures
|
7
|
+
alias_method :original_teardown_fixtures, :teardown_fixtures
|
8
|
+
|
9
|
+
def setup_fixtures
|
10
|
+
original_setup_fixtures
|
11
|
+
# start tx for secondbase, if required
|
12
|
+
# Load fixtures once and begin transaction.
|
13
|
+
if run_in_transaction?
|
14
|
+
SecondBase::Base.connection.increment_open_transactions
|
15
|
+
SecondBase::Base.connection.transaction_joinable = false
|
16
|
+
SecondBase::Base.connection.begin_db_transaction
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown_fixtures
|
21
|
+
original_teardown_fixtures
|
22
|
+
|
23
|
+
# Rollback secondbase changes if a transaction is active.
|
24
|
+
if run_in_transaction? && SecondBase::Base.connection.open_transactions != 0
|
25
|
+
SecondBase::Base.connection.rollback_db_transaction
|
26
|
+
SecondBase::Base.connection.decrement_open_transactions
|
27
|
+
end
|
28
|
+
|
29
|
+
SecondBase::Base.clear_active_connections!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/secondbase/model.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
#
|
3
3
|
# NOTE: By extending this model, you assume that the underlying table will be located in your Second (Data)base
|
4
4
|
module SecondBase
|
5
|
-
require 'active_record'
|
6
5
|
|
7
6
|
class Base < ActiveRecord::Base
|
8
|
-
establish_connection ActiveRecord::Base.configurations[CONNECTION_PREFIX][Rails.env]
|
7
|
+
establish_connection ActiveRecord::Base.configurations[SecondBase::CONNECTION_PREFIX][Rails.env]
|
9
8
|
|
10
9
|
self.abstract_class = true
|
11
10
|
end
|
data/secondbase.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{secondbase}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["karledurante"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2012-08-31}
|
13
13
|
s.description = %q{Secondbase provides support to Rails to create a homogeneous environment for a dual database project. Using the rake tasks already familiar to you, this gem enables Rails to work with two primary databases, instead of just one.}
|
14
14
|
s.email = %q{kdurante@customink.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
+
"CHANGELOG.md",
|
21
22
|
"Gemfile",
|
22
23
|
"Gemfile.lock",
|
23
24
|
"LICENSE.txt",
|
@@ -28,7 +29,11 @@ Gem::Specification.new do |s|
|
|
28
29
|
"lib/generators/secondbase/migration_generator.rb",
|
29
30
|
"lib/generators/secondbase/templates/migration.rb",
|
30
31
|
"lib/secondbase.rb",
|
31
|
-
"lib/secondbase/
|
32
|
+
"lib/secondbase/active_record/associations/has_and_belongs_to_many_association.rb",
|
33
|
+
"lib/secondbase/active_record/base.rb",
|
34
|
+
"lib/secondbase/active_record/fixtures.rb",
|
35
|
+
"lib/secondbase/active_record/patches.rb",
|
36
|
+
"lib/secondbase/active_record/test_fixtures.rb",
|
32
37
|
"lib/secondbase/model.rb",
|
33
38
|
"lib/secondbase/railtie.rb",
|
34
39
|
"lib/secondbase/rake_method_chain.rb",
|
@@ -45,31 +50,27 @@ Gem::Specification.new do |s|
|
|
45
50
|
s.require_paths = ["lib"]
|
46
51
|
s.rubygems_version = %q{1.4.2}
|
47
52
|
s.summary = %q{Allow Rails manage second database in your projects}
|
48
|
-
s.test_files = [
|
49
|
-
"test/helper.rb",
|
50
|
-
"test/test_secondbase.rb"
|
51
|
-
]
|
52
53
|
|
53
54
|
if s.respond_to? :specification_version then
|
54
55
|
s.specification_version = 3
|
55
56
|
|
56
57
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
57
58
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
58
|
-
s.add_development_dependency(%q<bundler>, ["
|
59
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.
|
59
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
60
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.2"])
|
60
61
|
s.add_development_dependency(%q<activerecord>, ["~> 3.0.0"])
|
61
62
|
s.add_development_dependency(%q<activerecord>, ["~> 3.0.0"])
|
62
63
|
else
|
63
64
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
64
|
-
s.add_dependency(%q<bundler>, ["
|
65
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
65
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
66
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.2"])
|
66
67
|
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
67
68
|
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
68
69
|
end
|
69
70
|
else
|
70
71
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
71
|
-
s.add_dependency(%q<bundler>, ["
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
72
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.2"])
|
73
74
|
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
74
75
|
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
75
76
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: secondbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- karledurante
|
@@ -15,11 +15,11 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-08-31 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
22
|
+
prerelease: false
|
23
23
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
25
25
|
requirements:
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
- 0
|
31
31
|
version: "0"
|
32
32
|
requirement: *id001
|
33
|
-
|
33
|
+
type: :development
|
34
34
|
name: shoulda
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
|
36
|
+
prerelease: false
|
37
37
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
38
|
none: false
|
39
39
|
requirements:
|
40
|
-
- -
|
40
|
+
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
hash: 23
|
43
43
|
segments:
|
@@ -46,26 +46,26 @@ dependencies:
|
|
46
46
|
- 0
|
47
47
|
version: 1.0.0
|
48
48
|
requirement: *id002
|
49
|
-
|
49
|
+
type: :development
|
50
50
|
name: bundler
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
|
-
|
52
|
+
prerelease: false
|
53
53
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
54
|
none: false
|
55
55
|
requirements:
|
56
56
|
- - ~>
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
hash:
|
58
|
+
hash: 51
|
59
59
|
segments:
|
60
60
|
- 1
|
61
|
-
-
|
62
|
-
-
|
63
|
-
version: 1.
|
61
|
+
- 8
|
62
|
+
- 2
|
63
|
+
version: 1.8.2
|
64
64
|
requirement: *id003
|
65
|
-
|
65
|
+
type: :development
|
66
66
|
name: jeweler
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
|
-
|
68
|
+
prerelease: false
|
69
69
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
71
71
|
requirements:
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
- 0
|
79
79
|
version: 3.0.0
|
80
80
|
requirement: *id004
|
81
|
-
|
81
|
+
type: :development
|
82
82
|
name: activerecord
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
|
84
|
+
prerelease: false
|
85
85
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
@@ -94,7 +94,7 @@ dependencies:
|
|
94
94
|
- 0
|
95
95
|
version: 3.0.0
|
96
96
|
requirement: *id005
|
97
|
-
|
97
|
+
type: :development
|
98
98
|
name: activerecord
|
99
99
|
description: Secondbase provides support to Rails to create a homogeneous environment for a dual database project. Using the rake tasks already familiar to you, this gem enables Rails to work with two primary databases, instead of just one.
|
100
100
|
email: kdurante@customink.com
|
@@ -107,6 +107,7 @@ extra_rdoc_files:
|
|
107
107
|
- README.rdoc
|
108
108
|
files:
|
109
109
|
- .document
|
110
|
+
- CHANGELOG.md
|
110
111
|
- Gemfile
|
111
112
|
- Gemfile.lock
|
112
113
|
- LICENSE.txt
|
@@ -117,7 +118,11 @@ files:
|
|
117
118
|
- lib/generators/secondbase/migration_generator.rb
|
118
119
|
- lib/generators/secondbase/templates/migration.rb
|
119
120
|
- lib/secondbase.rb
|
120
|
-
- lib/secondbase/
|
121
|
+
- lib/secondbase/active_record/associations/has_and_belongs_to_many_association.rb
|
122
|
+
- lib/secondbase/active_record/base.rb
|
123
|
+
- lib/secondbase/active_record/fixtures.rb
|
124
|
+
- lib/secondbase/active_record/patches.rb
|
125
|
+
- lib/secondbase/active_record/test_fixtures.rb
|
121
126
|
- lib/secondbase/model.rb
|
122
127
|
- lib/secondbase/railtie.rb
|
123
128
|
- lib/secondbase/rake_method_chain.rb
|
@@ -162,6 +167,5 @@ rubygems_version: 1.4.2
|
|
162
167
|
signing_key:
|
163
168
|
specification_version: 3
|
164
169
|
summary: Allow Rails manage second database in your projects
|
165
|
-
test_files:
|
166
|
-
|
167
|
-
- test/test_secondbase.rb
|
170
|
+
test_files: []
|
171
|
+
|