cohabit 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,19 @@
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
+
19
+ test/debug.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cohabit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mike Campbell
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,47 @@
1
+ # Cohabit
2
+
3
+ Cohabit adds comprehensive scoped multi-tenancy functionality to any application, simply set your options up in `config/cohabit.rb` using the DSL (inspired by capistrano).
4
+
5
+ It adds:
6
+
7
+ - Model scoping (duh)
8
+ - Custom scoping strategies
9
+ - Scope validations
10
+ - Scope URL helpers
11
+ - Rake task for importing single-tenanted databases into a multi-tenant one
12
+ - Rake task for generating multi-tenanted scoped schema
13
+
14
+ ## Todo
15
+
16
+ Still a WIP. Need to:
17
+
18
+ - Develop snippets to be included in strategies, i.e. scope_validations snippet (and remove that setting)
19
+ - Should snippets just be nested strategies? wah, probably.
20
+ - Work out how to integrate the url helper scopes as an option
21
+ - Write the rake tasks
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ gem 'cohabit'
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install cohabit
36
+
37
+ ## Usage
38
+
39
+ TODO: Write usage instructions here
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = ['test/all_tests.rb'] #FileList['test/*_test.rb']
7
+ # t.verbose = true
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
data/cohabit.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cohabit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cohabit"
8
+ spec.version = Cohabit::VERSION
9
+ spec.authors = ["Mike Campbell"]
10
+ spec.email = ["mike@wordofmike.net"]
11
+ spec.description = %q{Handle application scoping for multi-tenant applications with table scopes.}
12
+ spec.summary = %q{Scope multi-tenant applications.}
13
+ spec.homepage = "http://github.com/mikecmpbll/cohabit"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activerecord"
22
+ spec.add_dependency "activesupport"
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,35 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Scopes
4
+
5
+ def self.included(base)
6
+ base.send :alias_method, :initialize_without_scopes, :initialize
7
+ base.send :alias_method, :initialize, :initialize_with_scopes
8
+ end
9
+
10
+ def initialize_with_scopes(*args)
11
+ initialize_without_scopes(*args)
12
+ @scopes = []
13
+ end
14
+
15
+ # deez are our scopes for our configuration instance
16
+ attr_reader :scopes
17
+
18
+ def scope(*args, &block)
19
+ args[1] &&= find_strategy_by_name(args[1])
20
+ scope = Scope.new(*args, &block)
21
+ add_scope(scope)
22
+ end
23
+
24
+ def apply_scopes!
25
+ @scopes.each{ |s| s.apply! }
26
+ end
27
+
28
+ private
29
+ def add_scope(scope)
30
+ scopes << scope
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Settings
4
+
5
+ DEFULT_SETTINGZ = {
6
+ scope_validations: false,
7
+ scope_url_helpers: false,
8
+ association: :tenant
9
+ }
10
+
11
+ def self.included(base)
12
+ base.send :alias_method, :initialize_without_settings, :initialize
13
+ base.send :alias_method, :initialize, :initialize_with_settings
14
+ end
15
+
16
+ # deez are our global settings for this configuration instance
17
+ attr_reader :settings
18
+
19
+ def initialize_with_settings(*args, &block)
20
+ @settings = DEFULT_SETTINGZ.dup
21
+ initialize_without_settings(*args, &block)
22
+ end
23
+
24
+ def merge_settings!(settings)
25
+ settings.delete_if{ |s| !DEFULT_SETTINGZ.include?(s) }
26
+ @settings.merge!(settings)
27
+ end
28
+
29
+ def generate_settings_hash!(args)
30
+ if args.last.is_a?(Hash)
31
+ args[args.length-1] = @settings.merge(args.last)
32
+ else
33
+ args << @settings.dup
34
+ end
35
+ end
36
+
37
+ def set(setting, value)
38
+ if !DEFULT_SETTINGZ.include?(setting.to_sym)
39
+ raise ArgumentError, "what the fuck are you doing.. that's not a setting"
40
+ end
41
+ @settings[setting.to_sym] = value
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ module Cohabit
2
+ class Configuration
3
+ module Strategies
4
+
5
+ def self.included(base)
6
+ base.send :alias_method, :initialize_without_strategies, :initialize
7
+ base.send :alias_method, :initialize, :initialize_with_strategies
8
+ end
9
+
10
+ def initialize_with_strategies(*args)
11
+ initialize_without_strategies(*args)
12
+ @strategies = []
13
+ end
14
+
15
+ # deez are our strategies for our configuration instance
16
+ attr_reader :strategies
17
+
18
+ # defines a strategy. woah there batman!
19
+ def strategy(*args, &block)
20
+ strategy = Strategy.new(*args, &block)
21
+ add_strategy(strategy)
22
+ end
23
+
24
+ def find_strategy_by_name(name)
25
+ strategy = @strategies.find{|s| s.name == name}
26
+ return strategy if strategy
27
+ raise StrategyNotFoundError
28
+ end
29
+
30
+ private
31
+ def add_strategy(strategy)
32
+ raise StrategyNameExistsError if named_strategy_exists?(strategy.name)
33
+ strategies << strategy
34
+ end
35
+
36
+ def named_strategy_exists?(strategy_name)
37
+ strategies.any?{|s| s.name == strategy_name}
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ require "cohabit/version"
2
+ require "cohabit/configuration/settings"
3
+ require "cohabit/configuration/strategies"
4
+ require "cohabit/configuration/scopes"
5
+ require "active_record"
6
+
7
+ module Cohabit
8
+ class Configuration
9
+
10
+ attr_reader :load_paths
11
+
12
+ def initialize(config_file = nil)
13
+ @load_paths = [".", File.expand_path(File.join(File.dirname(__FILE__), "strategies"))]
14
+ end
15
+
16
+ def load(*args, &block)
17
+ options = args.last.is_a?(Hash) ? args.pop : {}
18
+
19
+ if block
20
+ raise ArgumentError, "loading a block requires 0 arguments" unless options.empty? && args.empty?
21
+ instance_eval(&block)
22
+ elsif options[:file]
23
+ load string: File.read(options[:file])
24
+ elsif options[:string]
25
+ instance_eval(options[:string])
26
+ end
27
+ end
28
+
29
+ # simple require to pull in config files, eg 'basic'
30
+ def require(files)
31
+ [files].flatten.each do |file|
32
+ load_paths.each do |path|
33
+ if file.match(/\.rb\z/)
34
+ name = File.join(path, file)
35
+ else
36
+ name = File.join(path, "#{file}.rb")
37
+ end
38
+ load(file: name) if File.file?(name)
39
+ end
40
+ end
41
+ end
42
+
43
+ include Settings, Strategies, Scopes
44
+
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ module Cohabit
2
+
3
+ Error = Class.new(RuntimeError)
4
+
5
+ StrategyNameExistsError = Class.new(Cohabit::Error)
6
+ StrategyNotFoundError = Class.new(Cohabit::Error)
7
+ InvalidScopeError = Class.new(Cohabit::Error)
8
+
9
+ end
@@ -0,0 +1,57 @@
1
+ require "cohabit/configuration/settings"
2
+ require "active_record"
3
+ require "active_support/inflector"
4
+
5
+ module Cohabit
6
+ class Scope
7
+
8
+ def initialize(*args, &block)
9
+ merge_settings!(args.pop) if args.last.is_a?(Hash)
10
+ apply_to(args[0])
11
+ use_strategy(args[1])
12
+ instance_eval(&block) unless block.nil?
13
+ merge_settings!(@strategy.settings)
14
+ unless valid?
15
+ raise InvalidScopeError, "provide valid model(s) and strategy"
16
+ end
17
+ end
18
+
19
+ include Configuration::Settings
20
+
21
+ attr_reader :strategy
22
+
23
+ def use_strategy(strategy)
24
+ unless strategy.nil?
25
+ @strategy = strategy
26
+ end
27
+ end
28
+
29
+ def apply_to(models)
30
+ @models = parse_models(models)
31
+ end
32
+
33
+ def apply!
34
+ # apply yourself, that's what my teachers always said.
35
+ @models.each do |model|
36
+ model._apply_cohabit_scope(self)
37
+ end
38
+ end
39
+
40
+ private
41
+ def valid?
42
+ return false if @models.empty?
43
+ return false if @strategy.nil?
44
+ @models.each do |model|
45
+ return false if !ActiveRecord::Base.descendants.include?(model)
46
+ end
47
+ return true
48
+ end
49
+
50
+ def parse_models(models)
51
+ [models].flatten.compact.map do |model|
52
+ model.to_s.classify.constantize
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,4 @@
1
+ module Cohabit
2
+ class Snippets
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ strategy :basic do
2
+ model_eval do |_scope|
3
+ belongs_to _scope.settings[:association]
4
+ reflection = reflect_on_association _scope.settings[:association]
5
+ scope_validators(reflection.foreign_key) if _scope.settings[:scope_validations]
6
+ before_create Proc.new {|m|
7
+ return unless Cohabit.current_tenant
8
+ m.send "#{_scope.settings[:association]}=".to_sym, Cohabit.current_tenant
9
+ }
10
+ default_scope lambda {
11
+ where(reflection.foreign_key => Cohabit.current_tenant) if Cohabit.current_tenant
12
+ }
13
+ end
14
+ end
@@ -0,0 +1,2 @@
1
+ require 'basic'
2
+ require 'multi'
@@ -0,0 +1,13 @@
1
+ # strategy :multi do
2
+ # model_eval do
3
+ # reflection = reflect_on_association _scope.settings[:association]
4
+ # scope_validators(reflection.foreign_key) if _scope.settings[:scope_validations]
5
+ # before_create Proc.new {|m|
6
+ # return unless _scope.current_school
7
+ # m.send "#{_scope.settings[:association]}=".to_sym, _scope.current_school
8
+ # }
9
+ # default_scope lambda {
10
+ # where(reflection.foreign_key => _scope.current_scope) if _scope.current_scope
11
+ # }
12
+ # end
13
+ # end
@@ -0,0 +1,22 @@
1
+ require "cohabit/configuration/settings"
2
+
3
+ module Cohabit
4
+ class Strategy
5
+
6
+ def initialize(*args, &block)
7
+ raise ArgumentError, "you must supply a name" if args.empty?
8
+ @name = args.shift.to_sym
9
+ @settings = args.last.is_a?(Hash) ? args.last : {}
10
+ instance_eval(&block) unless block.nil?
11
+ end
12
+
13
+ include Configuration::Settings
14
+
15
+ attr_reader :name, :model_code
16
+
17
+ def model_eval(&block)
18
+ @model_code = block
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Cohabit
2
+ VERSION = "0.0.1"
3
+ end
data/lib/cohabit.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'cohabit/errors'
2
+ require 'cohabit/configuration'
3
+ require 'cohabit/strategy'
4
+ require 'cohabit/scope'
5
+
6
+ module Cohabit
7
+ class << self
8
+ attr_accessor :current_tenant
9
+ end
10
+
11
+ module ActiveRecordExtensions
12
+ def _apply_cohabit_scope(_scope)
13
+ proc = _scope.strategy.model_code
14
+ instance_exec(_scope, &proc) if proc
15
+ end
16
+ end
17
+ end
18
+
19
+ ActiveRecord::Base.extend Cohabit::ActiveRecordExtensions
20
+
21
+ if defined? ::Rails::Railtie
22
+ module Cohabit
23
+ class Railtie < Rails::Railtie
24
+ initializer "cohabit.configure" do |app|
25
+ config = Cohabit::Configuration.new
26
+ config.load(file: File.join(Rails.root, "config/cohabit.rb"))
27
+ config.apply_scopes!
28
+ end
29
+ end
30
+ end
31
+ else
32
+ config = Cohabit::Configuration.new
33
+ config.load(file: File.join(Rails.root, "config/cohabit.rb"))
34
+ config.apply_scopes!
35
+ end
data/test/all_tests.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..')
3
+ $LOAD_PATH << File.dirname(__FILE__)
4
+ Dir.glob('test/*_test.rb', &method(:require))
5
+ load_schema
data/test/database.yml ADDED
@@ -0,0 +1,6 @@
1
+ sqlite:
2
+ adapter: sqlite
3
+ database: ":memory:"
4
+ sqlite3:
5
+ adapter: sqlite3
6
+ database: ":memory:"
data/test/models.rb ADDED
@@ -0,0 +1,7 @@
1
+ # something to scope!
2
+ class Ybur < ActiveRecord::Base
3
+ end
4
+
5
+ # wonderful tenant class!
6
+ class Client < ActiveRecord::Base
7
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ create_table :yburs, :force => true do |t|
3
+ t.column :joke, :string
4
+ t.column :client_id, :integer
5
+ end
6
+
7
+ create_table :clients, :force => true do |t|
8
+ t.column :name, :string
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ class ScopesTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def teardown
8
+ Ybur.default_scopes.clear
9
+ Ybur._validators.clear
10
+ [:validate, :validation, :save, :create, :update, :destroy].each do |type|
11
+ Ybur.reset_callbacks(type)
12
+ end
13
+ Ybur.reflections.clear
14
+
15
+ Client.delete_all
16
+ Ybur.delete_all
17
+ end
18
+
19
+ def test_add_valid_scope
20
+ # load basic strategy
21
+ @c.load do
22
+ require 'basic'
23
+ scope :ybur, :basic, association: :client
24
+ end
25
+ assert(@c.scopes.any?)
26
+ end
27
+
28
+ def test_settings_for_scope
29
+ @c.load do
30
+ require 'basic'
31
+ scope :ybur, :basic, association: :client
32
+ end
33
+ assert_equal(:client, @c.scopes.first.settings[:association])
34
+ end
35
+
36
+ def test_apply_scope_to_model
37
+ c = Client.create(name: "fubar")
38
+ Cohabit.current_tenant = c
39
+ @c.load do
40
+ require 'basic'
41
+ scope :ybur, :basic
42
+ end
43
+ @c.apply_scopes!
44
+ assert_not_equal(Ybur.unscoped.to_sql, Ybur.scoped.to_sql)
45
+ end
46
+
47
+ def test_setting_association_name
48
+ c = Client.create(name: "fubar")
49
+ Cohabit.current_tenant = c
50
+ @c.load do
51
+ require 'basic'
52
+ scope :ybur, :basic, association: :client
53
+ end
54
+ @c.apply_scopes!
55
+ assert_match(/client_id/, Ybur.scoped.to_sql)
56
+ end
57
+
58
+ end
@@ -0,0 +1,27 @@
1
+ class SettingsTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def test_set_real_setting
8
+ assert_not_equal(@c.settings[:scope_validations], true)
9
+ @c.set :scope_validations, true
10
+ assert_equal(true, @c.settings[:scope_validations])
11
+ end
12
+
13
+ def test_set_nonexitant_setting
14
+ assert_raise(ArgumentError) do
15
+ @c.set :wtf_not_a_real_setting, "dis is a value, innit"
16
+ end
17
+ end
18
+
19
+ def test_set_setting_with_config
20
+ assert_equal(false, @c.settings[:scope_validations])
21
+ @c.load do
22
+ set :scope_validations, true
23
+ end
24
+ assert_equal(true, @c.settings[:scope_validations])
25
+ end
26
+
27
+ end
@@ -0,0 +1,57 @@
1
+ class StrategiesTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def test_define_strategy
8
+ @c.strategy(:frankel) do
9
+ model_eval do
10
+ puts "do this in the model! hurah."
11
+ end
12
+ end
13
+ assert(@c.strategies.one?)
14
+ end
15
+
16
+ def test_define_strategy_with_config
17
+ @c.load do
18
+ strategy :frankel do
19
+ model_eval do
20
+ puts "do this in the model! hurah."
21
+ end
22
+ end
23
+ end
24
+ assert(@c.strategies.one?)
25
+ end
26
+
27
+ def test_cant_add_same_named_strategies
28
+ assert_raise(Cohabit::StrategyNameExistsError) do
29
+ @c.load do
30
+ strategy :frankel
31
+ strategy :frankel # eh-uhhh, no can do.
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_strategy_inherits_correct_settings
37
+ # strategy block defaults > strategy arg defaults
38
+
39
+ # should take on strategy default settings when passed in
40
+ setup
41
+ @c.load do
42
+ strategy :frankel, { scope_validations: true }
43
+ end
44
+ assert_equal(true, @c.strategies.first.settings[:scope_validations])
45
+
46
+ # should take on strategy default settings when set in block
47
+ # overriding any defaults passed as arguments
48
+ setup
49
+ @c.load do
50
+ strategy :frankel, { scope_validations: "henry cecil" } do
51
+ set :scope_validations, true
52
+ end
53
+ end
54
+ assert_equal(true, @c.strategies.first.settings[:scope_validations])
55
+ end
56
+
57
+ end
@@ -0,0 +1,39 @@
1
+ class StrategyTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @c = Cohabit::Configuration.new
5
+ end
6
+
7
+ def teardown
8
+ Ybur.default_scopes.clear
9
+ Ybur._validators.clear
10
+ [:validate, :validation, :save, :create, :update, :destroy].each do |type|
11
+ Ybur.reset_callbacks(type)
12
+ end
13
+ Ybur.reflections.clear
14
+
15
+ Client.delete_all
16
+ Ybur.delete_all
17
+ end
18
+
19
+ def test_basic_strategy
20
+ @c.load do
21
+ require 'basic'
22
+ scope :ybur, :basic, association: :client
23
+ end
24
+ @c.apply_scopes!
25
+
26
+ # test before_validation to add scope association
27
+ c = Client.create(name: "fubar")
28
+ Cohabit.current_tenant = c
29
+ y = Ybur.create(joke: "I took my tomcats to get neutered today. No hard felines")
30
+ assert_same(c, y.client)
31
+
32
+ # test default_scope
33
+ c2 = Client.create(name: "rabuf")
34
+ Cohabit.current_tenant = c2
35
+ y2 = Ybur.create(joke: "I just ordered 10,000 bottles of TippEx. I made a massive mistake.")
36
+ assert_equal(1, Ybur.count)
37
+ end
38
+
39
+ end
@@ -0,0 +1,32 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require "active_record"
7
+ require "models"
8
+ require "cohabit"
9
+
10
+ def load_schema
11
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
12
+ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
13
+ db_adapter = ENV['DB']
14
+ # no db passed, try one of these fine config-free DBs before bombing.
15
+ db_adapter ||= begin
16
+ require 'rubygems'
17
+ require 'sqlite'
18
+ 'sqlite'
19
+ rescue MissingSourceFile
20
+ begin
21
+ require 'sqlite3'
22
+ 'sqlite3'
23
+ rescue MissingSourceFile
24
+ end
25
+ end
26
+
27
+ if db_adapter.nil?
28
+ raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
29
+ end
30
+ ActiveRecord::Base.establish_connection(config[db_adapter])
31
+ load(File.dirname(__FILE__) + "/schema.rb")
32
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cohabit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Campbell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Handle application scoping for multi-tenant applications with table scopes.
79
+ email:
80
+ - mike@wordofmike.net
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - cohabit.gemspec
91
+ - lib/cohabit.rb
92
+ - lib/cohabit/configuration.rb
93
+ - lib/cohabit/configuration/scopes.rb
94
+ - lib/cohabit/configuration/settings.rb
95
+ - lib/cohabit/configuration/strategies.rb
96
+ - lib/cohabit/errors.rb
97
+ - lib/cohabit/scope.rb
98
+ - lib/cohabit/snippets.rb
99
+ - lib/cohabit/strategies/basic.rb
100
+ - lib/cohabit/strategies/defaults.rb
101
+ - lib/cohabit/strategies/multi.rb
102
+ - lib/cohabit/strategy.rb
103
+ - lib/cohabit/version.rb
104
+ - test/all_tests.rb
105
+ - test/database.yml
106
+ - test/models.rb
107
+ - test/schema.rb
108
+ - test/scopes_test.rb
109
+ - test/settings_test.rb
110
+ - test/strategies_test.rb
111
+ - test/strategy_test.rb
112
+ - test/test_helper.rb
113
+ homepage: http://github.com/mikecmpbll/cohabit
114
+ licenses:
115
+ - MIT
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.25
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Scope multi-tenant applications.
138
+ test_files:
139
+ - test/all_tests.rb
140
+ - test/database.yml
141
+ - test/models.rb
142
+ - test/schema.rb
143
+ - test/scopes_test.rb
144
+ - test/settings_test.rb
145
+ - test/strategies_test.rb
146
+ - test/strategy_test.rb
147
+ - test/test_helper.rb