storey 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/README.md +83 -0
  5. data/Rakefile +7 -0
  6. data/lib/storey/duplicator.rb +61 -0
  7. data/lib/storey/exceptions.rb +6 -0
  8. data/lib/storey/migrator.rb +28 -0
  9. data/lib/storey/railtie.rb +47 -0
  10. data/lib/storey/version.rb +3 -0
  11. data/lib/storey.rb +161 -0
  12. data/lib/tasks/storey.rake +57 -0
  13. data/spec/config/database.yml.sample +6 -0
  14. data/spec/dummy/Rakefile +7 -0
  15. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  16. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  17. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  18. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  19. data/spec/dummy/app/mailers/.gitkeep +0 -0
  20. data/spec/dummy/app/models/.gitkeep +0 -0
  21. data/spec/dummy/app/models/company.rb +2 -0
  22. data/spec/dummy/app/models/fake.rb +2 -0
  23. data/spec/dummy/app/models/post.rb +2 -0
  24. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/spec/dummy/config/application.rb +45 -0
  26. data/spec/dummy/config/boot.rb +10 -0
  27. data/spec/dummy/config/database.yml.sample +6 -0
  28. data/spec/dummy/config/environment.rb +5 -0
  29. data/spec/dummy/config/environments/development.rb +30 -0
  30. data/spec/dummy/config/environments/production.rb +60 -0
  31. data/spec/dummy/config/environments/test.rb +39 -0
  32. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/spec/dummy/config/initializers/inflections.rb +10 -0
  34. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  35. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  36. data/spec/dummy/config/initializers/session_store.rb +8 -0
  37. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/spec/dummy/config/locales/en.yml +5 -0
  39. data/spec/dummy/config/routes.rb +2 -0
  40. data/spec/dummy/config.ru +4 -0
  41. data/spec/dummy/db/migrate/20120115060713_create_companies.rb +8 -0
  42. data/spec/dummy/db/migrate/20120115060728_create_posts.rb +8 -0
  43. data/spec/dummy/db/schema.rb +25 -0
  44. data/spec/dummy/lib/assets/.gitkeep +0 -0
  45. data/spec/dummy/log/.gitkeep +0 -0
  46. data/spec/dummy/log/development.log +0 -0
  47. data/spec/dummy/public/404.html +26 -0
  48. data/spec/dummy/public/422.html +26 -0
  49. data/spec/dummy/public/500.html +26 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/script/rails +6 -0
  52. data/spec/fixtures/.gitkeep +0 -0
  53. data/spec/migrator_spec.rb +63 -0
  54. data/spec/spec_helper.rb +47 -0
  55. data/spec/storey/configuration_spec.rb +13 -0
  56. data/spec/storey/create_spec.rb +87 -0
  57. data/spec/storey/drop_spec.rb +31 -0
  58. data/spec/storey/duplicate_spec.rb +49 -0
  59. data/spec/storey/excluded_models_spec.rb +15 -0
  60. data/spec/storey/schema_spec.rb +31 -0
  61. data/spec/storey/schemas_spec.rb +51 -0
  62. data/spec/storey/switch_spec.rb +102 -0
  63. data/spec/tasks/storey_rake_spec.rb +106 -0
  64. data/storey.gemspec +27 -0
  65. metadata +204 -0
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Storey, "#schemas" do
4
+ context "when suffix is set" do
5
+ before do
6
+ Storey.suffix = "_roboto"
7
+ end
8
+
9
+ it "should return an array of the schemas without the suffix by default" do
10
+ Storey.create "mr"
11
+ Storey.schemas.should include("mr")
12
+ end
13
+
14
+ it "should include the public schema by default" do
15
+ Storey.schemas.should include("public")
16
+ end
17
+
18
+ it "should not include any postgres schemas" do
19
+ Storey.schemas do |schema|
20
+ schema.should_not include("pg_")
21
+ schema.should_not == "information_schema"
22
+ end
23
+ end
24
+
25
+ context "when suffix => true" do
26
+ it "should return an array of the schemas with the suffix" do
27
+ Storey.create "mr"
28
+ Storey.schemas(:suffix => true).should include("mr_roboto")
29
+ end
30
+ end
31
+
32
+ context "when suffix => false" do
33
+ it "should return an array of the schemas without the suffix" do
34
+ Storey.create "mr"
35
+ Storey.schemas(:suffix => false).should include("mr")
36
+ end
37
+ end
38
+
39
+ context "when :public => true" do
40
+ it "should return an array of the schemas without the public schema" do
41
+ Storey.schemas(:public => true).should include("public")
42
+ end
43
+ end
44
+
45
+ context "when :public => false" do
46
+ it "should return an array of the schemas with the public schema" do
47
+ Storey.schemas(:public => false).should_not include("public")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Storey, "#switch" do
4
+ it "should return the last execution of code in the block" do
5
+ Storey.create "foo"
6
+ post = Storey.switch "foo" do
7
+ Post.create
8
+ end
9
+ post.should be_kind_of(Post)
10
+ end
11
+
12
+ context "with a schema set" do
13
+ before do
14
+ Storey.suffix = "_hello"
15
+ Storey.create "foobar"
16
+ end
17
+
18
+ it "should switch to that schema with the suffix appended" do
19
+ Storey.switch "foobar" do
20
+ Storey.schema(:suffix => true).should == "foobar_hello"
21
+ end
22
+ end
23
+ end
24
+
25
+ context "with a schema passed" do
26
+ before do
27
+ Storey.create "foobar"
28
+ end
29
+
30
+ context "with a block passed" do
31
+ it "should execute the block in that schema" do
32
+ Storey.switch "foobar" do
33
+ Post.create :name => "hi"
34
+ Post.count.should == 1
35
+ end
36
+ Post.count.should be_zero
37
+ end
38
+
39
+ it "should return to the schema that the app was previously in" do
40
+ Storey.create "tintin"
41
+ Storey.switch "foobar"
42
+ Storey.switch "tintin" do; end
43
+ Storey.schema.should == "foobar"
44
+ end
45
+ end
46
+
47
+ context "without a block passed" do
48
+ it "should switch the context to the schema specified" do
49
+ Storey.schema.should_not == "foobar"
50
+ Storey.switch "foobar"
51
+ Storey.schema.should == "foobar"
52
+ end
53
+ end
54
+ end
55
+
56
+ context "when the schema passed does not exist" do
57
+ context "when the suffix is set" do
58
+ before do
59
+ Storey.suffix = "_rock"
60
+ end
61
+
62
+ it "should raise an error naming the schema with suffix" do
63
+ expect {Storey.switch "babo"}.to raise_error(Storey::SchemaNotFound, %{The schema "babo_rock" cannot be found.})
64
+ end
65
+ end
66
+
67
+ context "when the suffix is not set" do
68
+ it "should raise an error" do
69
+ expect {Storey.switch "babo"}.to raise_error(Storey::SchemaNotFound, %{The schema "babo" cannot be found.})
70
+ end
71
+ end
72
+ end
73
+
74
+ context "with no schema passed" do
75
+ before do
76
+ Storey.create "foobar"
77
+ end
78
+
79
+ context "with a block passed" do
80
+ it "should execute the block in the default schema" do
81
+ Storey.switch "foobar"
82
+ Storey.switch { Post.create }
83
+ Post.count.should be_zero
84
+ Storey.switch { Post.count.should == 1 }
85
+ end
86
+
87
+ it "should return to the schema that the app was previously in" do
88
+ Storey.switch "foobar"
89
+ Storey.switch do; end
90
+ Storey.schema.should == "foobar"
91
+ end
92
+ end
93
+
94
+ context "without a block passed" do
95
+ it "should switch the context to the default schema" do
96
+ Storey.switch "foobar"
97
+ Storey.switch
98
+ Storey.schema.should == %{"$user",public}
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Storey, "rake tasks" do
4
+
5
+ before do
6
+ @migration_version_1 = 20120115060713
7
+ @migration_version_2 = 20120115060728
8
+
9
+ @number_of_dbs = rand(3) + 1
10
+ @number_of_dbs.times do |db|
11
+ Storey.create "schema_#{db}"
12
+ end
13
+ end
14
+
15
+ describe "storey:migrate" do
16
+ before do
17
+ # We don't care how it's migrated
18
+ ActiveRecord::Migrator.stub(:migrate)
19
+ end
20
+
21
+ it "should migrate all schemas including public" do
22
+ # +1 to take into account the public schema
23
+ ActiveRecord::Migrator.should_receive(:migrate).exactly(@number_of_dbs + 1).times
24
+ @rake["storey:migrate"].invoke
25
+ end
26
+ end
27
+
28
+ describe "storey:migrate:up" do
29
+ context "without a version" do
30
+ before do
31
+ ENV['VERSION'] = nil
32
+ end
33
+
34
+ it "requires a version to migrate to" do
35
+ expect { @rake['storey:migrate:up'].invoke }.to raise_error("VERSION is required")
36
+ end
37
+ end
38
+
39
+ context "with version" do
40
+ before do
41
+ ENV['VERSION'] = @migration_version_2.to_s
42
+ end
43
+
44
+ it "migrates up to a specific version" do
45
+ # +1 to take into account the public schema
46
+ Storey::Migrator.should_receive(:run).with(
47
+ :up,
48
+ anything,
49
+ @migration_version_2.to_i
50
+ ).exactly(@number_of_dbs+1).times
51
+
52
+ @rake['storey:migrate:up'].invoke
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "storey:migrate:down" do
58
+ context "without a version" do
59
+ before do
60
+ ENV['VERSION'] = nil
61
+ end
62
+
63
+ it "requires a version to migrate to" do
64
+ expect { @rake['storey:migrate:down'].invoke }.should raise_error("VERSION is required")
65
+ end
66
+ end
67
+
68
+ context "with version" do
69
+ before do
70
+ ENV['VERSION'] = @migration_version_1.to_s
71
+ end
72
+
73
+ it "migrates up to a specific version" do
74
+ Storey::Migrator.should_receive(:run).with(
75
+ :down,
76
+ anything,
77
+ @migration_version_1
78
+ ).exactly(@number_of_dbs+1).times
79
+
80
+ @rake['storey:migrate:down'].invoke
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "storey:rollback" do
86
+ before do
87
+ @step = 2
88
+ end
89
+
90
+ it "should rollback dbs" do
91
+ Storey::Migrator.should_receive(:rollback).exactly(@number_of_dbs+1).times
92
+ @rake['storey:rollback'].invoke
93
+ end
94
+
95
+ it "should rollback dbs STEP amt" do
96
+ Storey::Migrator.should_receive(:rollback).with(
97
+ anything,
98
+ @step
99
+ ).exactly(@number_of_dbs+1).times
100
+
101
+ ENV['STEP'] = @step.to_s
102
+ @rake['storey:rollback'].invoke
103
+ end
104
+ end
105
+
106
+ end
data/storey.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "storey/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "storey"
7
+ s.version = Storey::VERSION
8
+ s.authors = ["Ramon Tayag"]
9
+ s.email = ["ramon@tayag.net"]
10
+ s.homepage = ""
11
+ s.summary = %q{Manage multiple PostgreSQL schemas in your multi-tenant app.}
12
+ s.description = %q{Heavily inspired by the Apartment gem, Storey aims to simplify the implementation of managing a multi-tenant application. This aims to be just the PostgreSQL schema specific portion of Apartment.}
13
+
14
+ s.rubyforge_project = "storey"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec-rails"
23
+ s.add_development_dependency "pg", "~> 0.12.2"
24
+ s.add_development_dependency "database_cleaner"
25
+ s.add_development_dependency "ruby-debug"
26
+ s.add_runtime_dependency "rails", "~> 3.1.3"
27
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: storey
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ramon Tayag
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-01-21 00:00:00 +08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec-rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: pg
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 43
44
+ segments:
45
+ - 0
46
+ - 12
47
+ - 2
48
+ version: 0.12.2
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: database_cleaner
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: ruby-debug
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: rails
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 5
88
+ segments:
89
+ - 3
90
+ - 1
91
+ - 3
92
+ version: 3.1.3
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ description: Heavily inspired by the Apartment gem, Storey aims to simplify the implementation of managing a multi-tenant application. This aims to be just the PostgreSQL schema specific portion of Apartment.
96
+ email:
97
+ - ramon@tayag.net
98
+ executables: []
99
+
100
+ extensions: []
101
+
102
+ extra_rdoc_files: []
103
+
104
+ files:
105
+ - .gitignore
106
+ - .rspec
107
+ - Gemfile
108
+ - README.md
109
+ - Rakefile
110
+ - lib/storey.rb
111
+ - lib/storey/duplicator.rb
112
+ - lib/storey/exceptions.rb
113
+ - lib/storey/migrator.rb
114
+ - lib/storey/railtie.rb
115
+ - lib/storey/version.rb
116
+ - lib/tasks/storey.rake
117
+ - spec/config/database.yml.sample
118
+ - spec/dummy/Rakefile
119
+ - spec/dummy/app/assets/javascripts/application.js
120
+ - spec/dummy/app/assets/stylesheets/application.css
121
+ - spec/dummy/app/controllers/application_controller.rb
122
+ - spec/dummy/app/helpers/application_helper.rb
123
+ - spec/dummy/app/mailers/.gitkeep
124
+ - spec/dummy/app/models/.gitkeep
125
+ - spec/dummy/app/models/company.rb
126
+ - spec/dummy/app/models/fake.rb
127
+ - spec/dummy/app/models/post.rb
128
+ - spec/dummy/app/views/layouts/application.html.erb
129
+ - spec/dummy/config.ru
130
+ - spec/dummy/config/application.rb
131
+ - spec/dummy/config/boot.rb
132
+ - spec/dummy/config/database.yml.sample
133
+ - spec/dummy/config/environment.rb
134
+ - spec/dummy/config/environments/development.rb
135
+ - spec/dummy/config/environments/production.rb
136
+ - spec/dummy/config/environments/test.rb
137
+ - spec/dummy/config/initializers/backtrace_silencers.rb
138
+ - spec/dummy/config/initializers/inflections.rb
139
+ - spec/dummy/config/initializers/mime_types.rb
140
+ - spec/dummy/config/initializers/secret_token.rb
141
+ - spec/dummy/config/initializers/session_store.rb
142
+ - spec/dummy/config/initializers/wrap_parameters.rb
143
+ - spec/dummy/config/locales/en.yml
144
+ - spec/dummy/config/routes.rb
145
+ - spec/dummy/db/migrate/20120115060713_create_companies.rb
146
+ - spec/dummy/db/migrate/20120115060728_create_posts.rb
147
+ - spec/dummy/db/schema.rb
148
+ - spec/dummy/lib/assets/.gitkeep
149
+ - spec/dummy/log/.gitkeep
150
+ - spec/dummy/log/development.log
151
+ - spec/dummy/public/404.html
152
+ - spec/dummy/public/422.html
153
+ - spec/dummy/public/500.html
154
+ - spec/dummy/public/favicon.ico
155
+ - spec/dummy/script/rails
156
+ - spec/fixtures/.gitkeep
157
+ - spec/migrator_spec.rb
158
+ - spec/spec_helper.rb
159
+ - spec/storey/configuration_spec.rb
160
+ - spec/storey/create_spec.rb
161
+ - spec/storey/drop_spec.rb
162
+ - spec/storey/duplicate_spec.rb
163
+ - spec/storey/excluded_models_spec.rb
164
+ - spec/storey/schema_spec.rb
165
+ - spec/storey/schemas_spec.rb
166
+ - spec/storey/switch_spec.rb
167
+ - spec/tasks/storey_rake_spec.rb
168
+ - storey.gemspec
169
+ has_rdoc: true
170
+ homepage: ""
171
+ licenses: []
172
+
173
+ post_install_message:
174
+ rdoc_options: []
175
+
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ hash: 3
184
+ segments:
185
+ - 0
186
+ version: "0"
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ hash: 3
193
+ segments:
194
+ - 0
195
+ version: "0"
196
+ requirements: []
197
+
198
+ rubyforge_project: storey
199
+ rubygems_version: 1.6.2
200
+ signing_key:
201
+ specification_version: 3
202
+ summary: Manage multiple PostgreSQL schemas in your multi-tenant app.
203
+ test_files: []
204
+