schema_qualified_tables 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG.markdown +37 -0
- data/LICENSE +20 -0
- data/README.markdown +82 -0
- data/Rakefile +54 -0
- data/VERSION.yml +5 -0
- data/lib/bcdatabase/active_record/schema_qualified_tables.rb +80 -0
- data/spec/bcdatabase/active_record/schema_qualified_tables_spec.rb +357 -0
- data/spec/spec_helper.rb +9 -0
- metadata +85 -0
data/.gitignore
ADDED
data/CHANGELOG.markdown
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
1.0.0
|
2
|
+
=====
|
3
|
+
- Split out from NUBIC internal `bcdatabase` project.
|
4
|
+
(Changelog entries below reflect the relevant changes & version numbers from that project.)
|
5
|
+
|
6
|
+
0.6.2
|
7
|
+
=====
|
8
|
+
- Fix infinite recursion bug when schema-qualified tables are enabled on a
|
9
|
+
database which doesn't support sequences.
|
10
|
+
|
11
|
+
0.6.1
|
12
|
+
=====
|
13
|
+
- Schema-qualified names are dynamically determined, removing the order
|
14
|
+
dependency between setting ActiveRecord::Base.schemas and defining any
|
15
|
+
particular model. Side effect: schema-qualified names do not work with
|
16
|
+
anonymous models at all (previously they only worked in certain
|
17
|
+
circumstances).
|
18
|
+
|
19
|
+
0.6.0
|
20
|
+
=====
|
21
|
+
- Make the schema part of SchemaQualifiedTables inherited so that it can be
|
22
|
+
set just once in a base class for a whole hierarchy.
|
23
|
+
- Ensure that set_schema does not throw an exception when invoked before the
|
24
|
+
connection is established.
|
25
|
+
|
26
|
+
0.5.2
|
27
|
+
=====
|
28
|
+
- Works with CPKs
|
29
|
+
|
30
|
+
0.5.1
|
31
|
+
=====
|
32
|
+
- Support schema-qualified sequence names in SchemaQualifiedTables, too
|
33
|
+
|
34
|
+
0.5.0
|
35
|
+
=====
|
36
|
+
- Extension Bcdatabase:Rails::SchemaQualifiedTables to add schema-qualified
|
37
|
+
table name support to active record.
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Rhett Sutphin and Peter Nyberg
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
SchemaQualifiedTables
|
2
|
+
=====================
|
3
|
+
|
4
|
+
`Bcdatabase::ActiveRecord::SchemaQualifiedTables` is a mix-in for [ActiveRecord][]. It makes it easier to use AR in an application which contains models which map to tables in different schemas.
|
5
|
+
|
6
|
+
[ActiveRecord]: http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html
|
7
|
+
|
8
|
+
For example
|
9
|
+
===========
|
10
|
+
|
11
|
+
Say you have an application using a legacy schema that has models like this:
|
12
|
+
|
13
|
+
class Surgery < ActiveRecord::Base
|
14
|
+
belongs_to :surgeon, :class_name => "Person", :foreign_key => "surgeon_id"
|
15
|
+
set_table_name "t_surgeries"
|
16
|
+
end
|
17
|
+
|
18
|
+
class Person < ActiveRecord::Base
|
19
|
+
set_table_name "hr.t_personnel"
|
20
|
+
end
|
21
|
+
|
22
|
+
These models map to tables in two schemas: the default schema, which contains `t_surgeries`; and the schema `hr`, which contains `t_personnel`.
|
23
|
+
|
24
|
+
Contention
|
25
|
+
----------
|
26
|
+
|
27
|
+
Being explicit about the schema name works for production, but what about development? You'll need separate database instances for development deployment and for test. Depending on what database you're using, this can be more or less fun (I'm looking at you, Oracle).
|
28
|
+
|
29
|
+
Also consider continuous integration: if you have several applications in CI which all refer to the `hr` schema, their test data sets will stomp all over each other if you try to run them in parallel.
|
30
|
+
|
31
|
+
Solution
|
32
|
+
--------
|
33
|
+
|
34
|
+
`SchemaQualifiedTables` solves this problem by letting you configure a logical schema name for your models which is resolved into the actual schema name based on runtime configuration. In this case, you'd re-write `Person` like so:
|
35
|
+
|
36
|
+
class Person < ActiveRecord::Base
|
37
|
+
set_schema :hr
|
38
|
+
set_table_name :t_personnel
|
39
|
+
end
|
40
|
+
|
41
|
+
Then, if you need to override the actual schema name in some environments, configure `ActiveRecord::Base.schemas`:
|
42
|
+
|
43
|
+
# in test.rb
|
44
|
+
config.after_initialize do
|
45
|
+
ActiveRecord::Base.schemas = {
|
46
|
+
:hr => 'hr_test',
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
This way in the test environment, AR will map `Person` to `hr_test.t_personnel`. In any environment where you don't provide an explicit override, the logical schema name will be used as the actual schema name — i.e., in development and production, AR will map `Person` to `hr.t_personnel`.
|
51
|
+
|
52
|
+
Installing
|
53
|
+
==========
|
54
|
+
|
55
|
+
Install the gem:
|
56
|
+
|
57
|
+
$ gem install schema_qualified_tables
|
58
|
+
|
59
|
+
If you're using rails, configure it in environment.rb:
|
60
|
+
|
61
|
+
config.gem 'schema_qualified_tables', :version => '>= 1.0.0',
|
62
|
+
:lib => 'bcdatabase/active_record/schema_qualified_tables',
|
63
|
+
:source => 'http://gemcutter.org'
|
64
|
+
|
65
|
+
Otherwise, just require 'bcdatabase/activerecord/schema_qualified_tables' sometime during initialization (before your models are loaded).
|
66
|
+
|
67
|
+
Problems?
|
68
|
+
=========
|
69
|
+
|
70
|
+
Please send any questions to Rhett Sutphin (rhett@detailedbalance.net).
|
71
|
+
|
72
|
+
Credits
|
73
|
+
=======
|
74
|
+
|
75
|
+
`SchemaQualifiedTables` was developed at the [Northwestern University Biomedical Informatics Center][NUBIC].
|
76
|
+
|
77
|
+
[NUBIC]: http://www.nucats.northwestern.edu/centers/nubic/index.html
|
78
|
+
|
79
|
+
Copyright
|
80
|
+
---------
|
81
|
+
|
82
|
+
Copyright (c) 2009 Rhett Sutphin and Peter Nyberg. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "schema_qualified_tables"
|
8
|
+
gem.summary = %Q{Logical schema names for ActiveRecord models}
|
9
|
+
gem.description = %Q{An ActiveRecord mix-in that makes it easier to use AR in an application which contains models which map to tables in different schemas.}
|
10
|
+
gem.email = "rhett@detailedbalance.net"
|
11
|
+
gem.homepage = "http://github.com/rsutphin/schema_qualified_tables"
|
12
|
+
gem.authors = ["Rhett Sutphin", "Peter Nyberg"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2"
|
14
|
+
gem.add_dependency 'activerecord', '>= 2.3'
|
15
|
+
|
16
|
+
gem.files.include("lib/**/*")
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
25
|
+
spec.libs << 'lib' << 'spec'
|
26
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
30
|
+
spec.libs << 'lib' << 'spec'
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
+
spec.rcov = true
|
33
|
+
# rcov can't tell that /Library/Ruby is a system path
|
34
|
+
spec.rcov_opts = ['--exclude', "spec/*,/Library/Ruby/*"]
|
35
|
+
end
|
36
|
+
|
37
|
+
task :spec => :check_dependencies
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "schema_qualified_tables #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
50
|
+
|
51
|
+
# Disable github release since I don't want to commit the gemspec
|
52
|
+
Rake::Task[:release].prerequisites.delete 'github:release'
|
53
|
+
|
54
|
+
task :build => [:gemspec]
|
data/VERSION.yml
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Bcdatabase
|
4
|
+
module ActiveRecord
|
5
|
+
module SchemaQualifiedTables
|
6
|
+
def self.included(clz)
|
7
|
+
clz.instance_eval do
|
8
|
+
extend ClassMethods
|
9
|
+
class_inheritable_accessor :schema
|
10
|
+
|
11
|
+
class << self
|
12
|
+
alias_method_chain :set_table_name, :schema
|
13
|
+
alias_method_chain :set_sequence_name, :schema
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
attr_accessor :schemas
|
20
|
+
|
21
|
+
def set_schema(schema)
|
22
|
+
self.schema = schema
|
23
|
+
unless abstract_class?
|
24
|
+
begin
|
25
|
+
update_qualified_table_name
|
26
|
+
update_qualified_sequence_name unless self.respond_to?(:primary_keys)
|
27
|
+
rescue ::ActiveRecord::ConnectionNotEstablished
|
28
|
+
# Defer
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_table_name_with_schema(name)
|
34
|
+
update_qualified_table_name(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_sequence_name_with_schema(name)
|
38
|
+
if name
|
39
|
+
update_qualified_sequence_name(name)
|
40
|
+
else
|
41
|
+
set_sequence_name_without_schema(name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def schemas
|
46
|
+
@schemas ||= { }
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
def schema_name
|
52
|
+
::ActiveRecord::Base.schemas[self.schema] || self.schema
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_qualified_table_name(table = nil)
|
56
|
+
update_qualified(:table_name, table)
|
57
|
+
end
|
58
|
+
|
59
|
+
def update_qualified_sequence_name(sequence = nil)
|
60
|
+
update_qualified(:sequence_name, sequence)
|
61
|
+
end
|
62
|
+
|
63
|
+
def update_qualified(thing, new_value)
|
64
|
+
unless new_value
|
65
|
+
current = self.send(thing) # invoke once only because of side effects
|
66
|
+
new_value =
|
67
|
+
if current.respond_to?(:include?) && current.include?('.')
|
68
|
+
current.split('.', 2).last
|
69
|
+
else
|
70
|
+
current
|
71
|
+
end
|
72
|
+
end
|
73
|
+
self.send(:"set_#{thing}_without_schema", nil) { new_value ? [schema_name, new_value].compact.join('.') : nil }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
::ActiveRecord::Base.send(:include, Bcdatabase::ActiveRecord::SchemaQualifiedTables)
|
@@ -0,0 +1,357 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", File.dirname(__FILE__))
|
2
|
+
require 'active_record'
|
3
|
+
ActiveRecord.load_all! if ActiveRecord.respond_to?(:load_all!) # Lazy loading of active_record was added to rails 2.3.2
|
4
|
+
# so we have to explicitly load it this way for cpk to work.
|
5
|
+
require 'composite_primary_keys'
|
6
|
+
require 'bcdatabase/active_record/schema_qualified_tables'
|
7
|
+
|
8
|
+
describe "SchemaQualifiedTables" do
|
9
|
+
before do
|
10
|
+
@conn = mock(ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
11
|
+
@conn.stub!(:default_sequence_name).and_return("default_sequence_name")
|
12
|
+
ActiveRecord::Base.connection_handler.stub!(:retrieve_connection).and_return(@conn)
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
Object.class_eval do
|
17
|
+
%w(ReadingMaterialBase Book Magazine Newspaper Pamphlet).each do |clazz|
|
18
|
+
remove_const clazz if const_defined? clazz
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "tables" do
|
24
|
+
describe "with no schema name" do
|
25
|
+
it "uses the inferred table name" do
|
26
|
+
class Book < ActiveRecord::Base
|
27
|
+
end
|
28
|
+
|
29
|
+
Book.table_name.should == 'books'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "uses just the explicit tablename" do
|
33
|
+
class Novel < ActiveRecord::Base
|
34
|
+
set_table_name "books"
|
35
|
+
end
|
36
|
+
|
37
|
+
Novel.table_name.should == 'books'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "with schema name" do
|
42
|
+
it "uses the inferred table name" do
|
43
|
+
class Magazine < ActiveRecord::Base
|
44
|
+
set_schema :reading_material
|
45
|
+
end
|
46
|
+
|
47
|
+
Magazine.table_name.should == 'reading_material.magazines'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "uses the explicit table name, if first" do
|
51
|
+
class Magazine < ActiveRecord::Base
|
52
|
+
set_table_name "some_magazines"
|
53
|
+
set_schema :reading_material
|
54
|
+
end
|
55
|
+
|
56
|
+
Magazine.table_name.should == "reading_material.some_magazines"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "uses the explicit table name, if second" do
|
60
|
+
class Magazine < ActiveRecord::Base
|
61
|
+
set_schema :reading_material
|
62
|
+
set_table_name "some_magazines"
|
63
|
+
end
|
64
|
+
|
65
|
+
Magazine.table_name.should == "reading_material.some_magazines"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "preserves the schema name if the table name is set several times" do
|
69
|
+
class Magazine < ActiveRecord::Base
|
70
|
+
set_schema :reading_material
|
71
|
+
set_table_name "some_magazines"
|
72
|
+
|
73
|
+
set_table_name "other_magazines"
|
74
|
+
end
|
75
|
+
|
76
|
+
Magazine.table_name.should == "reading_material.other_magazines"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "uses the last schema if set several times" do
|
80
|
+
class Magazine < ActiveRecord::Base
|
81
|
+
set_schema :reading_material
|
82
|
+
set_table_name "some_magazines"
|
83
|
+
set_schema :periodicals
|
84
|
+
end
|
85
|
+
|
86
|
+
Magazine.table_name.should == "periodicals.some_magazines"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "works if set_schema is called without a connection" do
|
90
|
+
ActiveRecord::Base.connection_handler.should_receive(:retrieve_connection).
|
91
|
+
and_raise(ActiveRecord::ConnectionNotEstablished)
|
92
|
+
lambda {
|
93
|
+
class Magazine < ActiveRecord::Base
|
94
|
+
set_schema :periodicals
|
95
|
+
end
|
96
|
+
}.should_not raise_error
|
97
|
+
|
98
|
+
Magazine.table_name.should == "periodicals.magazines"
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "from the parent" do
|
102
|
+
before do
|
103
|
+
class ReadingMaterialBase < ActiveRecord::Base
|
104
|
+
self.abstract_class = true
|
105
|
+
set_schema :reading_material
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "inherits the schema from its parent class" do
|
110
|
+
class Magazine < ReadingMaterialBase
|
111
|
+
set_table_name "some_magazines"
|
112
|
+
end
|
113
|
+
|
114
|
+
Magazine.schema.should == :reading_material
|
115
|
+
Magazine.table_name.should == "reading_material.some_magazines"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "uses the inferred table name for a child" do
|
119
|
+
pending "bug in ActiveRecord::Base.reset_table_name"
|
120
|
+
# Fails because the first call to reset_table_name
|
121
|
+
# always returns just the inferred table name. Usually
|
122
|
+
# the first call is during set_table_name or set_schema.
|
123
|
+
# In this spec, it is in the call to table_name, below.
|
124
|
+
class Newspaper < ReadingMaterialBase; end
|
125
|
+
|
126
|
+
Newspaper.schema.should == :reading_material
|
127
|
+
Newspaper.table_name.should == "reading_material.newspapers"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "uses separate schemas for subclasses" do
|
131
|
+
class Magazine < ReadingMaterialBase
|
132
|
+
set_table_name "some_magazines"
|
133
|
+
set_schema :periodicals
|
134
|
+
end
|
135
|
+
class Newspaper < ReadingMaterialBase
|
136
|
+
set_schema :deprecated
|
137
|
+
end
|
138
|
+
|
139
|
+
Magazine.table_name.should == "periodicals.some_magazines"
|
140
|
+
Newspaper.table_name.should == "deprecated.newspapers"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "with name overrides" do
|
145
|
+
before do
|
146
|
+
ActiveRecord::Base.schemas = {
|
147
|
+
:reading_material => 'reading_material_test'
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
after do
|
152
|
+
ActiveRecord::Base.schemas.clear
|
153
|
+
end
|
154
|
+
|
155
|
+
it "uses the inferred table name" do
|
156
|
+
class Pamphlet < ActiveRecord::Base
|
157
|
+
set_schema :reading_material
|
158
|
+
end
|
159
|
+
|
160
|
+
Pamphlet.table_name.should == 'reading_material_test.pamphlets'
|
161
|
+
end
|
162
|
+
|
163
|
+
it "uses the explicit table name, if first" do
|
164
|
+
class Pamphlet < ActiveRecord::Base
|
165
|
+
set_table_name "some_pamphlets"
|
166
|
+
set_schema :reading_material
|
167
|
+
end
|
168
|
+
|
169
|
+
Pamphlet.table_name.should == "reading_material_test.some_pamphlets"
|
170
|
+
end
|
171
|
+
|
172
|
+
it "uses the explicit table name, if second" do
|
173
|
+
class Pamphlet < ActiveRecord::Base
|
174
|
+
set_schema :reading_material
|
175
|
+
set_table_name "some_pamphlets"
|
176
|
+
end
|
177
|
+
|
178
|
+
Pamphlet.table_name.should == "reading_material_test.some_pamphlets"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "applies name overrides that come after the model is loaded" do
|
182
|
+
class Newspaper < ActiveRecord::Base
|
183
|
+
set_table_name "newspaperos"
|
184
|
+
set_schema :periodicals
|
185
|
+
end
|
186
|
+
|
187
|
+
ActiveRecord::Base.schemas = { :periodicals => "periodicals_test" }
|
188
|
+
|
189
|
+
Newspaper.table_name.should == "periodicals_test.newspaperos"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "applies name overrides that come after the model is loaded when using the inferred table name" do
|
193
|
+
class Newspaper < ActiveRecord::Base
|
194
|
+
set_schema :periodicals
|
195
|
+
end
|
196
|
+
|
197
|
+
ActiveRecord::Base.schemas = { :periodicals => "periodicals_test" }
|
198
|
+
|
199
|
+
Newspaper.table_name.should == "periodicals_test.newspapers"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# TODO: bad, bad, bad copying
|
206
|
+
describe "sequences" do
|
207
|
+
describe "with no schema name" do
|
208
|
+
it "uses the inferred sequence name" do
|
209
|
+
class Book < ActiveRecord::Base
|
210
|
+
end
|
211
|
+
|
212
|
+
Book.sequence_name.should == 'default_sequence_name'
|
213
|
+
end
|
214
|
+
|
215
|
+
it "uses just the explicit sequencename" do
|
216
|
+
class Novel < ActiveRecord::Base
|
217
|
+
set_sequence_name "books"
|
218
|
+
end
|
219
|
+
|
220
|
+
Novel.sequence_name.should == 'books'
|
221
|
+
end
|
222
|
+
|
223
|
+
it "gives nil if the adapter doesn't specify a default sequence name" do
|
224
|
+
conn = mock(ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
225
|
+
conn.stub!(:default_sequence_name).and_return(nil)
|
226
|
+
ActiveRecord::Base.connection_handler.stub!(:retrieve_connection).and_return(conn)
|
227
|
+
|
228
|
+
class Book < ActiveRecord::Base
|
229
|
+
end
|
230
|
+
|
231
|
+
Book.sequence_name.should be_nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "with schema name" do
|
236
|
+
it "uses the inferred sequence name" do
|
237
|
+
class Magazine < ActiveRecord::Base
|
238
|
+
set_schema :reading_material
|
239
|
+
end
|
240
|
+
|
241
|
+
Magazine.sequence_name.should == 'reading_material.default_sequence_name'
|
242
|
+
end
|
243
|
+
|
244
|
+
it "gives nil if the adapter doesn't specify a default sequence name" do
|
245
|
+
conn = mock(ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
246
|
+
conn.stub!(:default_sequence_name).and_return(nil)
|
247
|
+
ActiveRecord::Base.connection_handler.stub!(:retrieve_connection).and_return(conn)
|
248
|
+
|
249
|
+
class Book < ActiveRecord::Base
|
250
|
+
set_schema :reading_material
|
251
|
+
end
|
252
|
+
|
253
|
+
Book.sequence_name.should be_nil
|
254
|
+
end
|
255
|
+
|
256
|
+
describe "with CPK" do
|
257
|
+
it "doesn't fail when setting the schema" do
|
258
|
+
class Newspaper < ActiveRecord::Base
|
259
|
+
set_primary_keys "address", "telephone"
|
260
|
+
set_schema :reading_material
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
it "uses the explicit sequence name, if first" do
|
266
|
+
class Magazine < ActiveRecord::Base
|
267
|
+
set_sequence_name "some_magazines_seq"
|
268
|
+
set_schema :reading_material
|
269
|
+
end
|
270
|
+
|
271
|
+
Magazine.sequence_name.should == "reading_material.some_magazines_seq"
|
272
|
+
end
|
273
|
+
|
274
|
+
it "uses the explicit sequence name, if second" do
|
275
|
+
class Magazine < ActiveRecord::Base
|
276
|
+
set_schema :reading_material
|
277
|
+
set_sequence_name "some_magazines_seq"
|
278
|
+
end
|
279
|
+
|
280
|
+
Magazine.sequence_name.should == "reading_material.some_magazines_seq"
|
281
|
+
end
|
282
|
+
|
283
|
+
it "preserves the schema name if the sequence name is set several times" do
|
284
|
+
class Magazine < ActiveRecord::Base
|
285
|
+
set_schema :reading_material
|
286
|
+
set_sequence_name "some_magazines_seq"
|
287
|
+
|
288
|
+
set_sequence_name "other_magazines_seq"
|
289
|
+
end
|
290
|
+
|
291
|
+
Magazine.sequence_name.should == "reading_material.other_magazines_seq"
|
292
|
+
end
|
293
|
+
|
294
|
+
it "uses the last schema if set several times" do
|
295
|
+
class Magazine < ActiveRecord::Base
|
296
|
+
set_schema :reading_material
|
297
|
+
set_sequence_name "some_magazines_seq"
|
298
|
+
set_schema :periodicals
|
299
|
+
end
|
300
|
+
|
301
|
+
Magazine.sequence_name.should == "periodicals.some_magazines_seq"
|
302
|
+
end
|
303
|
+
|
304
|
+
it "works if set_schema is called without a connection" do
|
305
|
+
ActiveRecord::Base.connection_handler.should_receive(:retrieve_connection).
|
306
|
+
and_raise(ActiveRecord::ConnectionNotEstablished)
|
307
|
+
lambda {
|
308
|
+
class Magazine < ActiveRecord::Base
|
309
|
+
set_schema :periodicals
|
310
|
+
set_sequence_name 'mag_seq'
|
311
|
+
end
|
312
|
+
}.should_not raise_error
|
313
|
+
|
314
|
+
Magazine.sequence_name.should == "periodicals.mag_seq"
|
315
|
+
end
|
316
|
+
|
317
|
+
describe "with name overrides" do
|
318
|
+
before do
|
319
|
+
ActiveRecord::Base.schemas = {
|
320
|
+
:reading_material => 'reading_material_test'
|
321
|
+
}
|
322
|
+
end
|
323
|
+
|
324
|
+
after do
|
325
|
+
ActiveRecord::Base.schemas.clear
|
326
|
+
end
|
327
|
+
|
328
|
+
it "uses the inferred sequence name" do
|
329
|
+
class Pamphlet < ActiveRecord::Base
|
330
|
+
set_schema :reading_material
|
331
|
+
end
|
332
|
+
|
333
|
+
Pamphlet.sequence_name.should == 'reading_material_test.default_sequence_name'
|
334
|
+
end
|
335
|
+
|
336
|
+
it "uses the explicit sequence name, if first" do
|
337
|
+
class Pamphlet < ActiveRecord::Base
|
338
|
+
set_sequence_name "some_pamphlets"
|
339
|
+
set_schema :reading_material
|
340
|
+
end
|
341
|
+
|
342
|
+
Pamphlet.sequence_name.should == "reading_material_test.some_pamphlets"
|
343
|
+
end
|
344
|
+
|
345
|
+
it "uses the explicit sequence name, if second" do
|
346
|
+
class Pamphlet < ActiveRecord::Base
|
347
|
+
set_schema :reading_material
|
348
|
+
set_sequence_name "some_pamphlets"
|
349
|
+
end
|
350
|
+
|
351
|
+
Pamphlet.sequence_name.should == "reading_material_test.some_pamphlets"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: schema_qualified_tables
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rhett Sutphin
|
8
|
+
- Peter Nyberg
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-12-07 00:00:00 -06:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
type: :development
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "1.2"
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: activerecord
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "2.3"
|
35
|
+
version:
|
36
|
+
description: An ActiveRecord mix-in that makes it easier to use AR in an application which contains models which map to tables in different schemas.
|
37
|
+
email: rhett@detailedbalance.net
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- LICENSE
|
44
|
+
- README.markdown
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- CHANGELOG.markdown
|
48
|
+
- LICENSE
|
49
|
+
- README.markdown
|
50
|
+
- Rakefile
|
51
|
+
- VERSION.yml
|
52
|
+
- lib/bcdatabase/active_record/schema_qualified_tables.rb
|
53
|
+
- spec/bcdatabase/active_record/schema_qualified_tables_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/rsutphin/schema_qualified_tables
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Logical schema names for ActiveRecord models
|
83
|
+
test_files:
|
84
|
+
- spec/bcdatabase/active_record/schema_qualified_tables_spec.rb
|
85
|
+
- spec/spec_helper.rb
|