active_tenant 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_tenant.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 gabriel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # ActiveTenant
2
+
3
+ ActiveRecord extensions for multi tenant applications
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_tenant'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_tenant
18
+
19
+ ## Usage
20
+
21
+ ActiveRecord::Base.create_tenant 'customer_name'
22
+
23
+ ActiveRecord::Migration.migrate_tenant 'customer_name'
24
+ # or
25
+ ActiveRecord::Migration.migrate_all_tenants
26
+
27
+ ActiveRecord::Base.with_tenant 'customer_name' do
28
+ Porduct.find(1234)
29
+ end
30
+
31
+ ActiveRecord::Base.remove_tenant 'customer_name'
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/active_tenant/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'active_tenant'
6
+ s.version = ActiveTenant::VERSION
7
+ s.authors = ['Gabriel Naiman']
8
+ s.email = ['gabynaiman@gmail.com']
9
+ s.description = 'ActiveRecord extensions for multi tenant applications'
10
+ s.summary = 'ActiveRecord extensions for multi tenant applications'
11
+ s.homepage = 'https://github.com/gabynaiman/active_tenant'
12
+
13
+ s.files = `git ls-files`.split($\)
14
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency 'activerecord', '>= 3.0.0'
19
+
20
+ s.add_development_dependency 'pg'
21
+ s.add_development_dependency 'sqlite3'
22
+ s.add_development_dependency 'rspec'
23
+ end
@@ -0,0 +1,52 @@
1
+ module ActiveTenant
2
+ module ActiveRecord
3
+ module Base
4
+
5
+ def all_tenants
6
+ ActiveTenant.current.all
7
+ end
8
+
9
+ def create_tenant(name)
10
+ ActiveTenant.current.create name
11
+ end
12
+
13
+ def remove_tenant(name)
14
+ ActiveTenant.current.remove name
15
+ end
16
+
17
+ def with_tenant(name)
18
+ ActiveTenant.current.with(name) { yield }
19
+ end
20
+
21
+ def tenant_name
22
+ ActiveTenant.current.name
23
+ end
24
+
25
+ end
26
+
27
+ module Migration
28
+
29
+ def tenant(name=nil)
30
+ name ? @tenant_name = name : @tenant_name
31
+ end
32
+
33
+ def migrate_global(version=nil)
34
+ ActiveTenant.current.migrate_global version
35
+ end
36
+
37
+ def migrate_tenant(name, version=nil)
38
+ ActiveTenant.current.migrate name, version
39
+ end
40
+
41
+ def migrate_all_tenants(version=nil)
42
+ ActiveTenant.current.migrate_all version
43
+ end
44
+
45
+ def migrate_all(version=nil)
46
+ migrate_global version
47
+ migrate_all_tenants version
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,66 @@
1
+ module ActiveTenant
2
+ class PostgresAdapter
3
+ delegate :connection_config, :establish_connection, :connection, to: ::ActiveRecord::Base
4
+
5
+ def initialize
6
+ self.global = ActiveTenant.configuration.global if ActiveTenant.configuration.global
7
+ end
8
+
9
+ def all
10
+ connection.select_values("SELECT nspname FROM pg_namespace WHERE nspname <> 'information_schema' AND nspname NOT LIKE 'pg%'") - [global]
11
+ end
12
+
13
+ def create(name)
14
+ unless all.include? name
15
+ connection.execute "CREATE SCHEMA \"#{name}\""
16
+ end
17
+ end
18
+
19
+ def remove(name)
20
+ if all.include? name
21
+ connection.execute "DROP SCHEMA \"#{name}\" CASCADE"
22
+ end
23
+ end
24
+
25
+ def with(name)
26
+ return yield if name == search_path
27
+
28
+ ex = nil
29
+ current_schema = search_path
30
+ search_path name
31
+ begin
32
+ result = yield
33
+ rescue => e
34
+ ex = e
35
+ ensure
36
+ search_path current_schema
37
+ raise ex unless ex.nil?
38
+ result
39
+ end
40
+ end
41
+
42
+ def name
43
+ search_path
44
+ end
45
+
46
+ def global
47
+ @global || 'public'
48
+ end
49
+
50
+ private
51
+
52
+ def global=(name)
53
+ @global = name
54
+ end
55
+
56
+ def search_path(name=nil)
57
+ if name
58
+ connection.execute("SET SEARCH_PATH TO \"#{name}\"")
59
+ establish_connection connection_config.merge(schema_search_path: name)
60
+ else
61
+ connection_config[:schema_search_path]
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,68 @@
1
+ module ActiveTenant
2
+ class SQLiteAdapter
3
+ delegate :connection_config, :establish_connection, :connection, to: ::ActiveRecord::Base
4
+
5
+ def initialize
6
+ self.global = ActiveTenant.configuration.global if ActiveTenant.configuration.global
7
+ end
8
+
9
+ def all
10
+ path = database_path
11
+ Dir.glob("#{path}/*.sqlite3").map { |f| File.basename(f, '.sqlite3') } - [global]
12
+ end
13
+
14
+ def create(name)
15
+ unless all.include? name
16
+ current_config = connection_config
17
+ establish_connection current_config.merge(database: file_name(name))
18
+ connection
19
+ establish_connection current_config
20
+ end
21
+ end
22
+
23
+ def remove(name)
24
+ file = file_name name
25
+ FileUtils.rm(file) if File.exist?(file)
26
+ end
27
+
28
+ def with(name)
29
+ return yield if name == self.name
30
+
31
+ current_config = connection_config
32
+ ex = nil
33
+ begin
34
+ establish_connection current_config.merge(database: file_name(name))
35
+ result = yield
36
+ rescue => e
37
+ ex = e
38
+ ensure
39
+ establish_connection current_config
40
+ raise ex unless ex.nil?
41
+ result
42
+ end
43
+ end
44
+
45
+ def name
46
+ File.basename(connection_config[:database], '.sqlite3')
47
+ end
48
+
49
+ def global
50
+ @global
51
+ end
52
+
53
+ private
54
+
55
+ def global=(name)
56
+ @global = name
57
+ end
58
+
59
+ def database_path
60
+ File.dirname(connection_config[:database])
61
+ end
62
+
63
+ def file_name(name)
64
+ "#{database_path}/#{name}.sqlite3"
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveTenant
2
+ class Base
3
+ ADAPTERS = {
4
+ sqlite3: SQLiteAdapter,
5
+ postgresql: PostgresAdapter
6
+ }
7
+
8
+ delegate :all, :create, :remove, :with, :name, :global, to: :adapter
9
+
10
+ def migrate(name, version=nil)
11
+ with name do
12
+ ::ActiveRecord::Migrator.migrate(::ActiveRecord::Migrator.migrations_path, version) do |migration_proxy|
13
+ [:all, ::ActiveRecord::Base.tenant_name.to_sym].include? migration_proxy.send(:migration).class.tenant
14
+ end
15
+ end
16
+ end
17
+
18
+ def migrate_all(version=nil)
19
+ all.each do |tenant|
20
+ migrate tenant, version
21
+ end
22
+ end
23
+
24
+ def migrate_global(version=nil)
25
+ with global do
26
+ ::ActiveRecord::Migrator.migrate(::ActiveRecord::Migrator.migrations_path, version) do |migration_proxy|
27
+ migration_proxy.send(:migration).class.tenant.nil?
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def adapter
35
+ @adapter ||= ADAPTERS[::ActiveRecord::Base.connection_config[:adapter].to_sym].new
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveTenant
2
+ class Configuration
3
+ attr_accessor :global
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveTenant
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_record'
2
+
3
+ require 'active_tenant/version'
4
+ require 'active_tenant/adapters/sqlite_adapter'
5
+ require 'active_tenant/adapters/postgres_adapter'
6
+ require 'active_tenant/base'
7
+ require 'active_tenant/active_record_extensions'
8
+ require 'active_tenant/configuration'
9
+
10
+ module ActiveTenant
11
+
12
+ def self.configuration
13
+ @@configuration ||= Configuration.new
14
+ end
15
+
16
+ def self.configure
17
+ yield(configuration)
18
+ end
19
+
20
+ def self.current
21
+ ActiveTenant::Base.new
22
+ end
23
+
24
+ end
25
+
26
+ ActiveRecord::Base.send :extend, ActiveTenant::ActiveRecord::Base
27
+ ActiveRecord::Migration.send :extend, ActiveTenant::ActiveRecord::Migration
@@ -0,0 +1,209 @@
1
+ require 'spec_helper'
2
+
3
+ ActiveTenant::Base::ADAPTERS.keys.each do |adapter_name|
4
+ adapter = ActiveTenant::Base::ADAPTERS[adapter_name]
5
+
6
+ describe adapter do
7
+
8
+ before :all do
9
+ AdapterTestHelper.before_all adapter_name
10
+ end
11
+
12
+ after :all do
13
+ AdapterTestHelper.after_all adapter_name
14
+ end
15
+
16
+ before :each do
17
+ AdapterTestHelper.before_each adapter_name
18
+ end
19
+
20
+ after :each do
21
+ AdapterTestHelper.after_each adapter_name
22
+ end
23
+
24
+ context 'Specific adapter' do
25
+
26
+ let(:tenant_adapter) { adapter.new }
27
+
28
+ it 'List all tenants' do
29
+ tenants = tenant_adapter.all
30
+
31
+ tenants.should be_a Array
32
+ tenants.should have(:no).items
33
+ end
34
+
35
+ it 'Create a new tenant' do
36
+ tenant_adapter.create 'new_tenant'
37
+ tenants = tenant_adapter.all
38
+
39
+ tenants.should be_a Array
40
+ tenants.should have(1).items
41
+ tenants.should include 'new_tenant'
42
+ end
43
+
44
+ it 'Remove an existing tenant' do
45
+ tenant_adapter.create 'tenant_to_remove'
46
+
47
+ tenant_adapter.all.should include 'tenant_to_remove'
48
+
49
+ tenant_adapter.remove 'tenant_to_remove'
50
+
51
+ tenant_adapter.all.should_not include 'tenant_to_remove'
52
+ end
53
+
54
+ it 'Evaluate a block into a tenant' do
55
+ tenant_adapter.name.should eq tenant_adapter.global
56
+
57
+ tenant_adapter.create 'dummy'
58
+
59
+ tenant_adapter.name.should eq tenant_adapter.global
60
+
61
+ tenant_adapter.with 'dummy' do
62
+ tenant_adapter.name.should eq 'dummy'
63
+ end
64
+
65
+ tenant_adapter.name.should eq tenant_adapter.global
66
+
67
+ tenant_adapter.remove 'dummy'
68
+
69
+ tenant_adapter.name.should eq tenant_adapter.global
70
+ end
71
+
72
+ end
73
+
74
+ context 'Global adapter' do
75
+
76
+ it 'Adapter operations' do
77
+ ActiveTenant.current.create 'dummy'
78
+ ActiveTenant.current.all.should include 'dummy'
79
+
80
+ ActiveTenant.current.name.should eq ActiveTenant.current.global
81
+
82
+ ActiveTenant.current.with 'dummy' do
83
+ ActiveTenant.current.name.should eq 'dummy'
84
+ end
85
+
86
+ ActiveTenant.current.name.should eq ActiveTenant.current.global
87
+
88
+ ActiveTenant.current.remove 'dummy'
89
+ ActiveTenant.current.all.should_not include 'dummy'
90
+ end
91
+
92
+ it 'Migrate global' do
93
+ ActiveTenant.current.create 'dummy'
94
+
95
+ ActiveTenant.current.migrate_global
96
+
97
+ ActiveRecord::Base.connection.table_exists?('globals').should be_true
98
+ ActiveRecord::Base.connection.table_exists?('tenants').should_not be_true
99
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should_not be_true
100
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
101
+
102
+ ActiveTenant.current.remove 'dummy'
103
+ end
104
+
105
+ it 'Migrate one tenant' do
106
+ ActiveTenant.current.create 'dummy_1'
107
+ ActiveTenant.current.create 'dummy_2'
108
+
109
+ ActiveTenant.current.migrate 'dummy_1'
110
+
111
+ ActiveTenant.current.with 'dummy_1' do
112
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
113
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
114
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should be_true
115
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
116
+ end
117
+
118
+ ActiveTenant.current.with 'dummy_2' do
119
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
120
+ ActiveRecord::Base.connection.table_exists?('tenants').should_not be_true
121
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should_not be_true
122
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
123
+ end
124
+
125
+ ActiveTenant.current.remove 'dummy_1'
126
+ ActiveTenant.current.remove 'dummy_2'
127
+ end
128
+
129
+ it 'Migrate all tenants' do
130
+ ActiveTenant.current.create 'dummy_1'
131
+ ActiveTenant.current.create 'dummy_2'
132
+
133
+ ActiveTenant.current.migrate_all
134
+
135
+ ActiveTenant.current.with 'dummy_1' do
136
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
137
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
138
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should be_true
139
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
140
+ end
141
+
142
+ ActiveTenant.current.with 'dummy_2' do
143
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
144
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
145
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should be_true
146
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
147
+ end
148
+
149
+ ActiveTenant.current.remove 'dummy_1'
150
+ ActiveTenant.current.remove 'dummy_2'
151
+ end
152
+
153
+ it 'Migrate custom tenant' do
154
+ ActiveTenant.current.create 'custom'
155
+
156
+ ActiveTenant.current.migrate 'custom'
157
+
158
+ ActiveTenant.current.with 'custom' do
159
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
160
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
161
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should be_true
162
+ ActiveRecord::Base.connection.table_exists?('customs').should be_true
163
+ end
164
+
165
+ ActiveTenant.current.remove 'custom'
166
+ end
167
+
168
+ it 'Migrate to specific version' do
169
+ ActiveTenant.current.create 'dummy'
170
+
171
+ ActiveTenant.current.migrate_all 20120823132854
172
+
173
+ ActiveTenant.current.with 'dummy' do
174
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
175
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should_not be_true
176
+ end
177
+
178
+ ActiveTenant.current.remove 'dummy'
179
+ end
180
+
181
+ end
182
+
183
+ context 'ActiveRecord extensions' do
184
+
185
+ it 'Create, migrate and remove' do
186
+ ActiveRecord::Base.create_tenant 'dummy'
187
+
188
+ ActiveRecord::Migration.migrate_all
189
+
190
+ ActiveRecord::Base.connection.table_exists?('globals').should be_true
191
+ ActiveRecord::Base.connection.table_exists?('tenants').should_not be_true
192
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should_not be_true
193
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
194
+
195
+ ActiveRecord::Base.with_tenant 'dummy' do
196
+ ActiveRecord::Base.connection.table_exists?('globals').should_not be_true
197
+ ActiveRecord::Base.connection.table_exists?('tenants').should be_true
198
+ ActiveRecord::Base.connection.table_exists?('other_tenants').should be_true
199
+ ActiveRecord::Base.connection.table_exists?('customs').should_not be_true
200
+ end
201
+
202
+ ActiveRecord::Base.remove_tenant 'dummy'
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+
209
+ end
@@ -0,0 +1,10 @@
1
+ class CreateGlobals < ActiveRecord::Migration
2
+ def change
3
+ create_table :globals do |t|
4
+ t.string :key, null: false
5
+ t.string :value, null: false
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ class CreateTenants < ActiveRecord::Migration
2
+ tenant :all
3
+
4
+ def change
5
+ create_table :tenants do |t|
6
+ t.string :key, null: false
7
+ t.string :value, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class CreateOtherTenants < ActiveRecord::Migration
2
+ tenant :all
3
+
4
+ def change
5
+ create_table :other_tenants do |t|
6
+ t.string :key, null: false
7
+ t.string :value, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class CreateCustoms < ActiveRecord::Migration
2
+ tenant :custom
3
+
4
+ def change
5
+ create_table :customs do |t|
6
+ t.string :key, null: false
7
+ t.string :value, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'active_tenant'
2
+
3
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
4
+
5
+ TEMP_PATH = ENV['TMP'].gsub("\\", '/')
6
+
7
+ ActiveRecord::Migrator.migrations_path = "#{File.dirname(__FILE__)}/migrations"
8
+
9
+ RSpec.configure do |config|
10
+ end
@@ -0,0 +1,59 @@
1
+ module AdapterTestHelper
2
+
3
+ def self.before_all(adapter_name)
4
+ method = "#{adapter_name}_before_all"
5
+ send method if respond_to? method
6
+ end
7
+
8
+ def self.after_all(adapter_name)
9
+ method = "#{adapter_name}_after_all"
10
+ send method if respond_to? method
11
+ end
12
+
13
+ def self.before_each(adapter_name)
14
+ method = "#{adapter_name}_before_each"
15
+ send method if respond_to? method
16
+ end
17
+
18
+ def self.after_each(adapter_name)
19
+ method = "#{adapter_name}_after_each"
20
+ send method if respond_to? method
21
+ end
22
+
23
+ private
24
+
25
+ def self.sqlite3_before_each
26
+ ActiveTenant.configuration.global = 'test'
27
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: "#{TEMP_PATH}/test.sqlite3"
28
+ ActiveRecord::Base.connection
29
+ end
30
+
31
+ def self.sqlite3_after_each
32
+ ActiveRecord::Base.connection.disconnect!
33
+ Dir.glob("#{TEMP_PATH}/*.sqlite3").each do |file|
34
+ FileUtils.rm(file)
35
+ end
36
+ end
37
+
38
+ def self.postgresql_before_all
39
+ ActiveTenant.configuration.global = 'public'
40
+ config = {
41
+ adapter: 'postgresql',
42
+ database: 'active_tenant_test',
43
+ schema_search_path: 'public',
44
+ username: 'postgres',
45
+ password: 'password'
46
+ }
47
+ ActiveRecord::Base.establish_connection config.merge database: 'postgres'
48
+ ActiveRecord::Base.connection.drop_database config[:database] rescue nil
49
+ ActiveRecord::Base.connection.create_database config[:database]
50
+ ActiveRecord::Base.establish_connection config
51
+ end
52
+
53
+ def self.postgresql_after_all
54
+ config = ActiveRecord::Base.connection_config
55
+ ActiveRecord::Base.establish_connection config.merge database: 'postgres'
56
+ ActiveRecord::Base.connection.drop_database config[:database]
57
+ end
58
+
59
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_tenant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gabriel Naiman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &25487856 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *25487856
25
+ - !ruby/object:Gem::Dependency
26
+ name: pg
27
+ requirement: &25463208 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *25463208
36
+ - !ruby/object:Gem::Dependency
37
+ name: sqlite3
38
+ requirement: &25414248 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *25414248
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &25336344 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *25336344
58
+ description: ActiveRecord extensions for multi tenant applications
59
+ email:
60
+ - gabynaiman@gmail.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - active_tenant.gemspec
71
+ - lib/active_tenant.rb
72
+ - lib/active_tenant/active_record_extensions.rb
73
+ - lib/active_tenant/adapters/postgres_adapter.rb
74
+ - lib/active_tenant/adapters/sqlite_adapter.rb
75
+ - lib/active_tenant/base.rb
76
+ - lib/active_tenant/configuration.rb
77
+ - lib/active_tenant/version.rb
78
+ - spec/adapters_spec.rb
79
+ - spec/migrations/20120823132512_create_globals.rb
80
+ - spec/migrations/20120823132854_create_tenants.rb
81
+ - spec/migrations/20120823132856_create_other_tenants.rb
82
+ - spec/migrations/20120823132902_create_customs.rb
83
+ - spec/spec_helper.rb
84
+ - spec/support/adapter_test_helper.rb
85
+ homepage: https://github.com/gabynaiman/active_tenant
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.16
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: ActiveRecord extensions for multi tenant applications
109
+ test_files:
110
+ - spec/adapters_spec.rb
111
+ - spec/migrations/20120823132512_create_globals.rb
112
+ - spec/migrations/20120823132854_create_tenants.rb
113
+ - spec/migrations/20120823132856_create_other_tenants.rb
114
+ - spec/migrations/20120823132902_create_customs.rb
115
+ - spec/spec_helper.rb
116
+ - spec/support/adapter_test_helper.rb