orm_adapter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ .rvmrc
3
+ .bundle
4
+ .yardoc
5
+ pkg
6
+ doc
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "yard"
4
+
5
+ group :test do
6
+ gem "activerecord", "~>3.0.0"
7
+ gem "mongoid", "~>2.0.0.beta.17"
8
+ gem "rspec", "~>2.0.0.beta.22"
9
+ gem "jeweler"
10
+ gem "rake"
11
+ gem "sqlite3-ruby"
12
+ gem "datamapper"
13
+ gem "dm-sqlite-adapter"
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,115 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.0)
5
+ activesupport (= 3.0.0)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4.1)
8
+ activerecord (3.0.0)
9
+ activemodel (= 3.0.0)
10
+ activesupport (= 3.0.0)
11
+ arel (~> 1.0.0)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.0)
14
+ addressable (2.2.1)
15
+ arel (1.0.1)
16
+ activesupport (~> 3.0.0)
17
+ bson (1.0.9)
18
+ builder (2.1.2)
19
+ data_objects (0.10.2)
20
+ addressable (~> 2.1)
21
+ datamapper (1.0.2)
22
+ dm-aggregates (= 1.0.2)
23
+ dm-constraints (= 1.0.2)
24
+ dm-core (= 1.0.2)
25
+ dm-migrations (= 1.0.2)
26
+ dm-serializer (= 1.0.2)
27
+ dm-timestamps (= 1.0.2)
28
+ dm-transactions (= 1.0.2)
29
+ dm-types (= 1.0.2)
30
+ dm-validations (= 1.0.2)
31
+ diff-lcs (1.1.2)
32
+ dm-aggregates (1.0.2)
33
+ dm-core (~> 1.0.2)
34
+ dm-constraints (1.0.2)
35
+ dm-core (~> 1.0.2)
36
+ dm-migrations (~> 1.0.2)
37
+ dm-core (1.0.2)
38
+ addressable (~> 2.2)
39
+ extlib (~> 0.9.15)
40
+ dm-do-adapter (1.0.2)
41
+ data_objects (~> 0.10.2)
42
+ dm-core (~> 1.0.2)
43
+ dm-migrations (1.0.2)
44
+ dm-core (~> 1.0.2)
45
+ dm-serializer (1.0.2)
46
+ dm-core (~> 1.0.2)
47
+ fastercsv (~> 1.5.3)
48
+ json_pure (~> 1.4)
49
+ dm-sqlite-adapter (1.0.2)
50
+ dm-do-adapter (~> 1.0.2)
51
+ do_sqlite3 (~> 0.10.2)
52
+ dm-timestamps (1.0.2)
53
+ dm-core (~> 1.0.2)
54
+ dm-transactions (1.0.2)
55
+ dm-core (~> 1.0.2)
56
+ dm-types (1.0.2)
57
+ dm-core (~> 1.0.2)
58
+ fastercsv (~> 1.5.3)
59
+ json_pure (~> 1.4)
60
+ stringex (~> 1.1.0)
61
+ uuidtools (~> 2.1.1)
62
+ dm-validations (1.0.2)
63
+ dm-core (~> 1.0.2)
64
+ do_sqlite3 (0.10.2)
65
+ data_objects (= 0.10.2)
66
+ extlib (0.9.15)
67
+ fastercsv (1.5.3)
68
+ gemcutter (0.6.1)
69
+ git (1.2.5)
70
+ i18n (0.4.1)
71
+ jeweler (1.4.0)
72
+ gemcutter (>= 0.1.0)
73
+ git (>= 1.2.5)
74
+ rubyforge (>= 2.0.0)
75
+ json_pure (1.4.6)
76
+ mongo (1.0.9)
77
+ bson (>= 1.0.5)
78
+ mongoid (2.0.0.beta.19)
79
+ activemodel (~> 3.0)
80
+ mongo (= 1.0.9)
81
+ tzinfo (~> 0.3.22)
82
+ will_paginate (~> 3.0.pre)
83
+ rake (0.8.7)
84
+ rspec (2.0.0.beta.22)
85
+ rspec-core (= 2.0.0.beta.22)
86
+ rspec-expectations (= 2.0.0.beta.22)
87
+ rspec-mocks (= 2.0.0.beta.22)
88
+ rspec-core (2.0.0.beta.22)
89
+ rspec-expectations (2.0.0.beta.22)
90
+ diff-lcs (>= 1.1.2)
91
+ rspec-mocks (2.0.0.beta.22)
92
+ rspec-core (= 2.0.0.beta.22)
93
+ rspec-expectations (= 2.0.0.beta.22)
94
+ rubyforge (2.0.4)
95
+ json_pure (>= 1.1.7)
96
+ sqlite3-ruby (1.3.1)
97
+ stringex (1.1.0)
98
+ tzinfo (0.3.23)
99
+ uuidtools (2.1.1)
100
+ will_paginate (3.0.pre2)
101
+ yard (0.6.1)
102
+
103
+ PLATFORMS
104
+ ruby
105
+
106
+ DEPENDENCIES
107
+ activerecord (~> 3.0.0)
108
+ datamapper
109
+ dm-sqlite-adapter
110
+ jeweler
111
+ mongoid (~> 2.0.0.beta.17)
112
+ rake
113
+ rspec (~> 2.0.0.beta.22)
114
+ sqlite3-ruby
115
+ yard
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1
2
+
3
+ * Initial release [Ian White, José Valim]
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Ian White and José Valim
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.rdoc ADDED
@@ -0,0 +1,31 @@
1
+ = orm_adapter
2
+
3
+ Provides a single point of entry for popular ruby ORMs. Its target audience is gem authors who want to support more than one ORM.
4
+
5
+ Currently supported ORMs are ActiveRecord, DataMapper and MongoId.
6
+
7
+
8
+ == Example of use
9
+
10
+ require 'orm_adapter'
11
+
12
+ User # is it an ActiveRecord, DM Resource, or MongoId Document?
13
+
14
+ User.to_adapter.find_first :name => 'Fred' # we don't care!
15
+
16
+ user_model = User.to_adapter
17
+ user_model.get!(1) # find a record by id
18
+ user_model.find_first(:name => 'fred') # find first fred
19
+ user_model.find_all(:name => 'fred') # find all freds
20
+ user_model.create!(:name => 'fred') # create a fred
21
+
22
+
23
+ == History
24
+
25
+
26
+ orm_adapter is an extraction from {pickle}[http://github.com/ianwhite/pickle] by {Ian White}[http://github.com/ianwhite]. Pickle's orm adapter included work by {Daniel Neighman}[http://github.com/hassox] and {Josh Bassett}[http://github.com/nullobject]. {José Valim}[http://github.com/josevalim] suggested the extraction, and worked on the first release with Ian.
27
+
28
+
29
+ == Copyright
30
+
31
+ Copyright (c) 2010 Ian White and José Valim. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+ require 'yard'
5
+
6
+ $:.unshift File.expand_path('lib')
7
+ require 'orm_adapter/version'
8
+
9
+ task :spec => :check_dependencies
10
+ task :default => :spec
11
+
12
+ desc "Run the specs"
13
+ RSpec::Core::RakeTask.new(:spec)
14
+
15
+ begin
16
+ require 'jeweler'
17
+ Jeweler::Tasks.new do |gem|
18
+ gem.name = "orm_adapter"
19
+ gem.version = OrmAdapter::Version::String
20
+ gem.summary = %Q{Provides a single point of entry for using basic features of ruby ORMs}
21
+ gem.description = %Q{Provides a single point of entry for using basic features of ruby ORMs}
22
+ gem.email = "ian.w.white@gmail.com"
23
+ gem.homepage = "http://github.com/ianwhite/orm_adapter"
24
+ gem.authors = ["Ian White", "Jose Valim"]
25
+ end
26
+ Jeweler::GemcutterTasks.new
27
+
28
+ namespace :release do
29
+ desc "release to github and gemcutter"
30
+ task :all => ['release', 'gemcutter:release']
31
+ end
32
+
33
+ rescue LoadError
34
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
35
+ end
36
+
37
+ YARD::Rake::YardocTask.new(:doc) do |t|
38
+ t.files = ['lib/**/*.rb', 'README.rdoc']
39
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
@@ -0,0 +1,75 @@
1
+ begin
2
+ require 'activerecord'
3
+ rescue LoadError
4
+ require 'active_record'
5
+ end
6
+
7
+ class ActiveRecord::Base
8
+ extend OrmAdapter::ToAdapter
9
+
10
+ class OrmAdapter < ::OrmAdapter::Base
11
+
12
+ # Do not consider these to be part of the class list
13
+ def self.except_classes
14
+ @@except_classes ||= [
15
+ "CGI::Session::ActiveRecordStore::Session",
16
+ "ActiveRecord::SessionStore::Session"
17
+ ]
18
+ end
19
+
20
+ # Gets a list of the available models for this adapter
21
+ def self.model_classes
22
+ begin
23
+ klasses = ::ActiveRecord::Base.__send__(:descendants) # Rails 3
24
+ rescue
25
+ klasses = ::ActiveRecord::Base.__send__(:subclasses) # Rails 2
26
+ end
27
+
28
+ klasses.select do |klass|
29
+ !klass.abstract_class? && !except_classes.include?(klass.name)
30
+ end
31
+ end
32
+
33
+ # Return list of column/property names
34
+ def column_names
35
+ klass.column_names
36
+ end
37
+
38
+ # Get an instance by id of the model
39
+ def get!(id)
40
+ klass.find(id)
41
+ end
42
+
43
+ # Find the first instance matching conditions
44
+ def find_first(conditions)
45
+ klass.first :conditions => conditions_to_fields(conditions)
46
+ end
47
+
48
+ # Find all models matching conditions
49
+ def find_all(conditions)
50
+ klass.all :conditions => conditions_to_fields(conditions)
51
+ end
52
+
53
+ # Create a model using attributes
54
+ def create!(attributes)
55
+ klass.create!(attributes)
56
+ end
57
+
58
+ protected
59
+
60
+ # Introspects the klass to convert and objects in conditions into foreign key and type fields
61
+ def conditions_to_fields(conditions)
62
+ conditions.inject({}) do |fields, (key, value)|
63
+ if value.is_a?(ActiveRecord::Base) && klass.column_names.include?("#{key}_id")
64
+ if klass.column_names.include?("#{key}_type")
65
+ fields.merge("#{key}_id" => value.id, "#{key}_type" => value.class.base_class.name)
66
+ else
67
+ fields.merge("#{key}_id" => value.id)
68
+ end
69
+ else
70
+ fields.merge(key => value)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,47 @@
1
+ require 'dm-core'
2
+
3
+ module DataMapper
4
+ module Model
5
+ include OrmAdapter::ToAdapter
6
+ end
7
+
8
+ module Resource
9
+ class OrmAdapter < ::OrmAdapter::Base
10
+
11
+ # Do not consider these to be part of the class list
12
+ def self.except_classes
13
+ @@except_classes ||= []
14
+ end
15
+
16
+ # Gets a list of the available models for this adapter
17
+ def self.model_classes
18
+ ::DataMapper::Model.descendants.to_a.select{|k| !except_classes.include?(k.name)}
19
+ end
20
+
21
+ # get a list of column names for a given class
22
+ def column_names
23
+ klass.properties.map(&:name)
24
+ end
25
+
26
+ # Get an instance by id of the model
27
+ def get!(id)
28
+ klass.get!(id)
29
+ end
30
+
31
+ # Find the first instance matching conditions
32
+ def find_first(conditions)
33
+ klass.first(conditions)
34
+ end
35
+
36
+ # Find all models matching conditions
37
+ def find_all(conditions)
38
+ klass.all(conditions)
39
+ end
40
+
41
+ # Create a model using attributes
42
+ def create!(attributes)
43
+ klass.create(attributes)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,59 @@
1
+ require 'mongoid'
2
+
3
+ module Mongoid
4
+ module Document
5
+ module ClassMethods
6
+ include OrmAdapter::ToAdapter
7
+ end
8
+
9
+ class OrmAdapter < ::OrmAdapter::Base
10
+ # Do not consider these to be part of the class list
11
+ def self.except_classes
12
+ @@except_classes ||= []
13
+ end
14
+
15
+ # Gets a list of the available models for this adapter
16
+ def self.model_classes
17
+ ObjectSpace.each_object(Class).to_a.select {|klass| klass.ancestors.include? Mongoid::Document}
18
+ end
19
+
20
+ # get a list of column names for a given class
21
+ def column_names
22
+ klass.fields.keys
23
+ end
24
+
25
+ # Get an instance by id of the model
26
+ def get!(id)
27
+ klass.find(id)
28
+ end
29
+
30
+ # Find the first instance matching conditions
31
+ def find_first(conditions)
32
+ klass.first(:conditions => conditions_to_fields(conditions))
33
+ end
34
+
35
+ # Find all models matching conditions
36
+ def find_all(conditions)
37
+ klass.all(:conditions => conditions_to_fields(conditions))
38
+ end
39
+
40
+ # Create a model with given attributes
41
+ def create!(attributes)
42
+ klass.create!(attributes)
43
+ end
44
+
45
+ protected
46
+
47
+ # converts and documents to ids
48
+ def conditions_to_fields(conditions)
49
+ conditions.inject({}) do |fields, (key, value)|
50
+ if value.is_a?(Mongoid::Document) && klass.fields.keys.include?("#{key}_id")
51
+ fields.merge("#{key}_id" => value.id)
52
+ else
53
+ fields.merge(key => value)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,57 @@
1
+ module OrmAdapter
2
+ class Base
3
+ attr_reader :klass
4
+
5
+ # Your ORM adapter needs to inherit from this Base class and its adapter
6
+ # will be registered. To create an adapter you should create an inner
7
+ # constant "OrmAdapter" e.g. ActiveRecord::Base::OrmAdapter
8
+ #
9
+ # @see orm_adapters/active_record
10
+ # @see orm_adapters/datamapper
11
+ # @see orm_adapters/mongoid
12
+ def self.inherited(adapter)
13
+ OrmAdapter.adapters << adapter
14
+ super
15
+ end
16
+
17
+ # Gets a list of the available models for this adapter
18
+ def self.model_classes
19
+ raise NotImplementedError, "return a list of available models for this adapter"
20
+ end
21
+
22
+ def initialize(klass)
23
+ @klass = klass
24
+ end
25
+
26
+ # Get a list of column/property/field names
27
+ def column_names
28
+ raise NotSupportedError
29
+ end
30
+
31
+ # Get an instance by id of the model
32
+ def get!(id)
33
+ raise NotSupportedError
34
+ end
35
+
36
+ # Find the first instance matching conditions
37
+ def find_first(conditions)
38
+ raise NotSupportedError
39
+ end
40
+
41
+ # Find all models matching conditions
42
+ def find_all(conditions)
43
+ raise NotSupportedError
44
+ end
45
+
46
+ # Create a model using attributes
47
+ def create!(attributes)
48
+ raise NotSupportedError
49
+ end
50
+ end
51
+
52
+ class NotSupportedError < RuntimeError
53
+ def to_s
54
+ "method not supported by this orm adapter"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ module OrmAdapter
2
+ # Extend into a class that has an OrmAdapter
3
+ module ToAdapter
4
+ def to_adapter
5
+ @_to_adapter ||= self::OrmAdapter.new(self)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'yaml'
2
+
3
+ module OrmAdapter
4
+ module Version
5
+ Hash = YAML.load_file(File.dirname(__FILE__) + '/../../VERSION.yml')
6
+ Major = Hash[:major]
7
+ Minor = Hash[:minor]
8
+ Patch = Hash[:patch]
9
+ Build = Hash[:build]
10
+ String = "#{Major}.#{Minor}.#{Patch}#{".#{Build}" if Build}"
11
+
12
+ def self.to_s
13
+ String
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'orm_adapter/base'
2
+ require 'orm_adapter/to_adapter'
3
+ require 'orm_adapter/version'
4
+
5
+ module OrmAdapter
6
+ # A collection of registered adapters
7
+ def self.adapters
8
+ @@adapters ||= []
9
+ end
10
+
11
+ # All model classes from all registered adapters
12
+ def self.model_classes
13
+ self.adapters.map { |a| a.model_classes }.flatten
14
+ end
15
+ end
16
+
17
+ require 'orm_adapter/adapters/active_record' if defined?(ActiveRecord::Base)
18
+ require 'orm_adapter/adapters/data_mapper' if defined?(DataMapper::Resource)
19
+ require 'orm_adapter/adapters/mongoid' if defined?(Mongoid::Document)
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{orm_adapter}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ian White", "Jose Valim"]
12
+ s.date = %q{2010-10-06}
13
+ s.description = %q{Provides a single point of entry for using basic features of ruby ORMs}
14
+ s.email = %q{ian.w.white@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "History.txt",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION.yml",
28
+ "lib/orm_adapter.rb",
29
+ "lib/orm_adapter/adapters/active_record.rb",
30
+ "lib/orm_adapter/adapters/data_mapper.rb",
31
+ "lib/orm_adapter/adapters/mongoid.rb",
32
+ "lib/orm_adapter/base.rb",
33
+ "lib/orm_adapter/to_adapter.rb",
34
+ "lib/orm_adapter/version.rb",
35
+ "orm_adapter.gemspec",
36
+ "spec/orm_adapter/adapters/active_record_spec.rb",
37
+ "spec/orm_adapter/adapters/data_mapper_spec.rb",
38
+ "spec/orm_adapter/adapters/mongoid_spec.rb",
39
+ "spec/orm_adapter_spec.rb",
40
+ "spec/spec_helper.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/ianwhite/orm_adapter}
43
+ s.rdoc_options = ["--charset=UTF-8"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{Provides a single point of entry for using basic features of ruby ORMs}
47
+ s.test_files = [
48
+ "spec/orm_adapter/adapters/active_record_spec.rb",
49
+ "spec/orm_adapter/adapters/data_mapper_spec.rb",
50
+ "spec/orm_adapter/adapters/mongoid_spec.rb",
51
+ "spec/orm_adapter_spec.rb",
52
+ "spec/spec_helper.rb"
53
+ ]
54
+
55
+ if s.respond_to? :specification_version then
56
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
57
+ s.specification_version = 3
58
+
59
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
60
+ else
61
+ end
62
+ else
63
+ end
64
+ end
65
+
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ if !defined?(ActiveRecord::Base)
4
+ puts "** require 'active_record' to run the specs in #{__FILE__}"
5
+ else
6
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:")
7
+
8
+ ActiveRecord::Migration.suppress_messages do
9
+ ActiveRecord::Schema.define(:version => 0) do
10
+ create_table(:users, :force => true) {|t| t.string :name; t.belongs_to :site }
11
+ create_table(:sites, :force => true) {|t| t.string :name }
12
+ create_table(:notes, :force => true) {|t| t.belongs_to :owner, :polymorphic => true }
13
+ end
14
+ end
15
+
16
+ module ArOrmSpec
17
+ class User < ActiveRecord::Base
18
+ belongs_to :site, :class_name => "ArOrmSpec::Site"
19
+ has_many :ar_notes, :as => :owner
20
+ end
21
+
22
+ class Site < ActiveRecord::Base
23
+ has_many :users, :class_name => 'ArOrmSpec::User'
24
+ has_many :notes, :as => :owner, :class_name => 'ArOrmSpec::Note'
25
+ end
26
+
27
+ class AbstractNoteClass < ActiveRecord::Base
28
+ self.abstract_class = true
29
+ end
30
+
31
+ class Note < AbstractNoteClass
32
+ belongs_to :owner, :polymorphic => true
33
+ end
34
+
35
+ # here be the specs!
36
+ describe ActiveRecord::Base::OrmAdapter do
37
+ before do
38
+ User.delete_all
39
+ Note.delete_all
40
+ Site.delete_all
41
+ end
42
+
43
+ subject { ActiveRecord::Base::OrmAdapter }
44
+
45
+ specify "except_classes should return the names of active record session store classes" do
46
+ subject.except_classes.should == ["CGI::Session::ActiveRecordStore::Session", "ActiveRecord::SessionStore::Session"]
47
+ end
48
+
49
+ specify "model_classes should return all of the non abstract model classes (that are not in except_classes)" do
50
+ subject.model_classes.should == [User, Site, Note]
51
+ end
52
+
53
+ describe "get!(id)" do
54
+ specify "should return the instance of klass with id if it exists" do
55
+ user = User.create!
56
+ User.to_adapter.get!(user.id).should == user
57
+ end
58
+
59
+ specify "should raise an error if the klass does not have an instance with that id" do
60
+ lambda { User.to_adapter.get!(1) }.should raise_error
61
+ end
62
+ end
63
+
64
+ describe "find_first(klass, conditions)" do
65
+ specify "should return first model matching conditions, if it exists" do
66
+ user = User.create! :name => "Fred"
67
+ User.to_adapter.find_first(:name => "Fred").should == user
68
+ end
69
+
70
+ specify "should return nil if no conditions match" do
71
+ User.to_adapter.find_first(:name => "Betty").should == nil
72
+ end
73
+
74
+ specify "should handle belongs_to objects in attributes hash" do
75
+ site = Site.create!
76
+ user = User.create! :name => "Fred", :site => site
77
+ User.to_adapter.find_first(:site => site).should == user
78
+ end
79
+
80
+ specify "should handle belongs_to :polymorphic objects in attributes hash" do
81
+ site = Site.create!
82
+ note = Note.create! :owner => site
83
+ Note.to_adapter.find_first(:owner => site).should == note
84
+ end
85
+ end
86
+
87
+ describe "find_all(klass, conditions)" do
88
+ specify "should return all models matching conditions" do
89
+ user1 = User.create! :name => "Fred"
90
+ user2 = User.create! :name => "Fred"
91
+ user3 = User.create! :name => "Betty"
92
+ User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
93
+ end
94
+
95
+ specify "should return empty array if no conditions match" do
96
+ User.to_adapter.find_all(:name => "Betty").should == []
97
+ end
98
+
99
+ specify "should handle belongs_to objects in conditions hash" do
100
+ site1, site2 = Site.create!, Site.create!
101
+ user1, user2 = User.create!(:site => site1), User.create!(:site => site2)
102
+ User.to_adapter.find_all(:site => site1).should == [user1]
103
+ end
104
+
105
+ specify "should handle polymorphic belongs_to objects in conditions hash" do
106
+ site1, site2 = Site.create!, Site.create!
107
+ note1, note2 = site1.notes.create!, site2.notes.create!
108
+ Note.to_adapter.find_all(:owner => site1).should == [note1]
109
+ end
110
+ end
111
+
112
+ describe "create!(klass, attributes)" do
113
+ it "should create a model using the given attributes" do
114
+ User.to_adapter.create!(:name => "Fred")
115
+ User.last.name.should == "Fred"
116
+ end
117
+
118
+ it "should raise error if the create fails" do
119
+ lambda { User.to_adapter.create!(:non_existent => true) }.should raise_error
120
+ end
121
+
122
+ it "should handle belongs_to objects in attributes hash" do
123
+ site = Site.create!
124
+ User.to_adapter.create!(:site => site)
125
+ User.last.site.should == site
126
+ end
127
+
128
+ it "should handle polymorphic belongs_to objects in attributes hash" do
129
+ site = Site.create!
130
+ Note.to_adapter.create!(:owner => site)
131
+ Note.last.owner.should == site
132
+ end
133
+
134
+ it "should handle has_many objects in attributes hash" do
135
+ users = [User.create!, User.create!]
136
+ Site.to_adapter.create!(:users => users)
137
+ Site.last.users.should == users
138
+ end
139
+ end
140
+
141
+ describe "<model class>#to_adapter" do
142
+ it "should return an adapter instance for the receiver" do
143
+ User.to_adapter.should be_a(OrmAdapter::Base)
144
+ User.to_adapter.klass.should == User
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ if !defined?(DataMapper)
4
+ puts "** require 'dm-core' to run the specs in #{__FILE__}"
5
+ else
6
+
7
+ DataMapper.setup(:default, 'sqlite::memory:')
8
+
9
+ module DmOrmSpec
10
+ class User
11
+ include DataMapper::Resource
12
+ property :id, Serial
13
+ property :name, String
14
+ has n, :notes, :child_key => [:owner_id]
15
+ end
16
+
17
+ class Note
18
+ include DataMapper::Resource
19
+ property :id, Serial
20
+ property :body, String
21
+ belongs_to :owner, 'User'
22
+ end
23
+
24
+ require 'dm-migrations'
25
+ DataMapper.finalize
26
+ DataMapper.auto_migrate!
27
+
28
+ # here be the specs!
29
+ describe DataMapper::Resource::OrmAdapter do
30
+ before do
31
+ User.destroy
32
+ Note.destroy
33
+ end
34
+
35
+ subject { DataMapper::Resource::OrmAdapter }
36
+
37
+ specify "model_classes should return all of datamapper resources" do
38
+ subject.model_classes.should == [User, Note]
39
+ end
40
+
41
+ describe "get!(klass, id)" do
42
+ specify "should return the instance of klass with id if it exists" do
43
+ user = User.create!
44
+ User.to_adapter.get!(user.id).should == user
45
+ end
46
+
47
+ specify "should raise an error if the klass does not have an instance with that id" do
48
+ lambda { User.to_adapter.get!(1) }.should raise_error
49
+ end
50
+ end
51
+
52
+ describe "find_first(klass, conditions)" do
53
+ specify "should return first model matching conditions, if it exists" do
54
+ user = User.create! :name => "Fred"
55
+ User.to_adapter.find_first(:name => "Fred").should == user
56
+ end
57
+
58
+ specify "should return nil if no conditions match" do
59
+ User.to_adapter.find_first(:name => "Betty").should == nil
60
+ end
61
+
62
+ specify "should handle belongs_to objects in attributes hash" do
63
+ user = User.create!
64
+ note = Note.create! :owner => user
65
+ Note.to_adapter.find_first(:owner => user).should == note
66
+ end
67
+ end
68
+
69
+ describe "find_all(klass, conditions)" do
70
+ specify "should return all models matching conditions" do
71
+ user1 = User.create! :name => "Fred"
72
+ user2 = User.create! :name => "Fred"
73
+ user3 = User.create! :name => "Betty"
74
+ User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
75
+ end
76
+
77
+ specify "should return empty array if no conditions match" do
78
+ User.to_adapter.find_all(:name => "Betty").should == []
79
+ end
80
+
81
+ specify "should handle belongs_to objects in conditions hash" do
82
+ user1, user2 = User.create!, User.create!
83
+ note1, note2 = user1.notes.create!, user2.notes.create!
84
+ Note.to_adapter.find_all(:owner => user1).should == [note1]
85
+ end
86
+ end
87
+
88
+ describe "create!(klass, attributes)" do
89
+ it "should create a model using the given attributes" do
90
+ User.to_adapter.create!(:name => "Fred")
91
+ User.last.name.should == "Fred"
92
+ end
93
+
94
+ it "should raise error if the create fails" do
95
+ lambda { subject.create!(:non_existent => true) }.should raise_error
96
+ end
97
+
98
+ it "should handle belongs_to objects in attributes hash" do
99
+ user = User.create!
100
+ Note.to_adapter.create!(:owner => user)
101
+ Note.last.owner.should == user
102
+ end
103
+
104
+ it "should handle has_many objects in attributes hash" do
105
+ notes = [Note.create!, Note.create!]
106
+ User.to_adapter.create!(:notes => notes)
107
+ User.last.notes.should == notes
108
+ end
109
+ end
110
+
111
+ describe "<model class>#to_adapter" do
112
+ it "should return an adapter instance for the receiver" do
113
+ User.to_adapter.should be_a(OrmAdapter::Base)
114
+ User.to_adapter.klass.should == User
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ if !defined?(Mongoid) || !(Mongo::Connection.new.db('orm_adapter_spec') rescue nil)
4
+ puts "** require 'mongoid' start mongod to run the specs in #{__FILE__}"
5
+ else
6
+
7
+ Mongoid.configure do |config|
8
+ config.master = Mongo::Connection.new.db('orm_adapter_spec')
9
+ end
10
+
11
+ module MongoidOrmSpec
12
+ class User
13
+ include Mongoid::Document
14
+ field :name
15
+ has_many_related :notes, :foreign_key => :owner_id, :class_name => 'MongoidOrmSpec::Note'
16
+ end
17
+
18
+ class Note
19
+ include Mongoid::Document
20
+ field :body, :default => "made by orm"
21
+ belongs_to_related :owner, :class_name => 'MongoidOrmSpec::User'
22
+ end
23
+
24
+ # here be the specs!
25
+ describe Mongoid::Document::OrmAdapter do
26
+ before do
27
+ User.delete_all
28
+ Note.delete_all
29
+ end
30
+
31
+ subject { Mongoid::Document::OrmAdapter }
32
+
33
+ specify "model_classes should return all of mongoid resources" do
34
+ (subject.model_classes & [User, Note]).to_set.should == [User, Note].to_set
35
+ end
36
+
37
+ describe "get!(klass, id)" do
38
+ specify "should return the instance of klass with id if it exists" do
39
+ user = User.create!
40
+ User.to_adapter.get!(user.id).should == user
41
+ end
42
+
43
+ specify "should raise an error if the klass does not have an instance with that id" do
44
+ lambda { User.to_adapter.get!(1) }.should raise_error
45
+ end
46
+ end
47
+
48
+ describe "find_first(klass, conditions)" do
49
+ specify "should return first model matching conditions, if it exists" do
50
+ user = User.create! :name => "Fred"
51
+ User.to_adapter.find_first(:name => "Fred").should == user
52
+ end
53
+
54
+ specify "should return nil if no conditions match" do
55
+ User.to_adapter.find_first(:name => "Betty").should == nil
56
+ end
57
+
58
+ specify "should handle belongs_to objects in attributes hash" do
59
+ user = User.create!
60
+ note = Note.create! :owner => user
61
+ Note.to_adapter.find_first(:owner => user).should == note
62
+ end
63
+ end
64
+
65
+ describe "find_all(klass, conditions)" do
66
+ specify "should return all models matching conditions" do
67
+ user1 = User.create! :name => "Fred"
68
+ user2 = User.create! :name => "Fred"
69
+ user3 = User.create! :name => "Betty"
70
+ User.to_adapter.find_all(:name => "Fred").should == [user1, user2]
71
+ end
72
+
73
+ specify "should return empty array if no conditions match" do
74
+ User.to_adapter.find_all(:name => "Betty").should == []
75
+ end
76
+
77
+ specify "should handle belongs_to objects in conditions hash" do
78
+ user1, user2 = User.create!, User.create!
79
+ note1, note2 = Note.create!(:owner_id => user1.id), Note.create!(:owner_id => user2.id)
80
+ Note.to_adapter.find_all(:owner => user1).should == [note1]
81
+ end
82
+ end
83
+
84
+ describe "create!(klass, attributes)" do
85
+ it "should create a model using the given attributes" do
86
+ User.to_adapter.create!(:name => "Fred")
87
+ User.last.name.should == "Fred"
88
+ end
89
+
90
+ it "should raise error if the create fails" do
91
+ lambda { User.to_adapter.create!(foo) }.should raise_error
92
+ end
93
+
94
+ it "should handle belongs_to objects in attributes hash" do
95
+ user = User.create!
96
+ Note.to_adapter.create!(:owner => user)
97
+ Note.last.owner.should == user
98
+ end
99
+ end
100
+
101
+ describe "<model class>#to_adapter" do
102
+ it "should return an adapter instance for the receiver" do
103
+ User.to_adapter.should be_a(OrmAdapter::Base)
104
+ User.to_adapter.klass.should == User
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe OrmAdapter do
4
+ subject { OrmAdapter }
5
+
6
+ describe "when a new adapter is created (by inheriting form OrmAdapter::Base)" do
7
+ let!(:adapter) { Class.new(OrmAdapter::Base) }
8
+
9
+ its(:adapters) { should include(adapter) }
10
+
11
+ describe "and the adapter has a model class" do
12
+ let(:model) { mock('model class') }
13
+
14
+ before { adapter.stub!(:model_classes).and_return([model]) }
15
+
16
+ its(:model_classes) { should include(model) }
17
+ end
18
+
19
+ after { OrmAdapter.adapters.delete(adapter) }
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+
4
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
5
+
6
+ ['dm-core', 'mongoid', 'active_record'].each do |orm|
7
+ begin
8
+ require orm
9
+ rescue LoadError
10
+ puts "#{orm} not available"
11
+ end
12
+ end
13
+
14
+ require 'orm_adapter'
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: orm_adapter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ian White
14
+ - Jose Valim
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-10-06 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Provides a single point of entry for using basic features of ruby ORMs
24
+ email: ian.w.white@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - LICENSE
31
+ - README.rdoc
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - Gemfile.lock
36
+ - History.txt
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION.yml
41
+ - lib/orm_adapter.rb
42
+ - lib/orm_adapter/adapters/active_record.rb
43
+ - lib/orm_adapter/adapters/data_mapper.rb
44
+ - lib/orm_adapter/adapters/mongoid.rb
45
+ - lib/orm_adapter/base.rb
46
+ - lib/orm_adapter/to_adapter.rb
47
+ - lib/orm_adapter/version.rb
48
+ - orm_adapter.gemspec
49
+ - spec/orm_adapter/adapters/active_record_spec.rb
50
+ - spec/orm_adapter/adapters/data_mapper_spec.rb
51
+ - spec/orm_adapter/adapters/mongoid_spec.rb
52
+ - spec/orm_adapter_spec.rb
53
+ - spec/spec_helper.rb
54
+ has_rdoc: true
55
+ homepage: http://github.com/ianwhite/orm_adapter
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --charset=UTF-8
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.7
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Provides a single point of entry for using basic features of ruby ORMs
88
+ test_files:
89
+ - spec/orm_adapter/adapters/active_record_spec.rb
90
+ - spec/orm_adapter/adapters/data_mapper_spec.rb
91
+ - spec/orm_adapter/adapters/mongoid_spec.rb
92
+ - spec/orm_adapter_spec.rb
93
+ - spec/spec_helper.rb