orm_adapter-0.5.0/0000755000004100000410000000000012261216643014044 5ustar www-datawww-dataorm_adapter-0.5.0/Rakefile0000644000004100000410000000107412261216643015513 0ustar www-datawww-data#!/usr/bin/env rake begin require 'bundler/setup' rescue LoadError puts 'You must `gem install bundler` and `bundle install` to run rake tasks' end require 'rake' require 'rspec/core/rake_task' $:.push File.expand_path("../lib", __FILE__) require "orm_adapter/version" task :default => :spec RSpec::Core::RakeTask.new(:spec) begin require 'yard' YARD::Rake::YardocTask.new(:doc) do |t| t.files = ['lib/**/*.rb', 'README.rdoc'] end rescue LoadError task :doc do puts "install yard to generate the docs" end end Bundler::GemHelper.install_tasks orm_adapter-0.5.0/Gemfile0000644000004100000410000000004712261216643015340 0ustar www-datawww-datasource "https://rubygems.org" gemspec orm_adapter-0.5.0/.rspec0000644000004100000410000000001112261216643015151 0ustar www-datawww-data--colour orm_adapter-0.5.0/History.txt0000644000004100000410000000334412261216643016252 0ustar www-datawww-data== 0.5.0 * Only send relation modifiers to ActiveRecord if they apply (don't send #order, #limit, #offset unless specified) Fixes plataformatec/devise#2711, ianwhite/orm_adapter#22 == 0.4.1 * Adds activerecord 4 to the test suite == 0.4.0 * Adds :limit, and :offset options to #find_all [Fred Wu] == 0.3.0 * Removes OrmAdapter::Base.model_classes and friends. This is a BC breaking change if you use .model_classes [Ian White] * Add note about the scope of ORM Adapter re: model instance methods == 0.2.0 * Normalise :id in find conditions [Tim Galeckas, Ian White] * Allow find_first and find_all to take no arguments [Tim Galeckas, Ian White] == 0.1.0 * Add #destroy(object) to the API [Fred Wu] == 0.0.7 * Lazy load Active Record [José Valim] == 0.0.6 * Active Record 3.1 association compatibility [Ian White] * Compatibility with mongoid master wrt. OrmAdapter::Base#get [Frank Wöckener]. Closes #9 [Ian White] == 0.0.5 * Adds Mongo Mapper adapter [Luke Cunningham] == 0.0.4 * Adds ability to order results from #find_first and #find_all [Ian White] * Rationalise development dependencies and release process [Ian White] == 0.0.3 * ActiveRecord's OrmAdapter handles non standard foreign key names [Ian White] * fix ruby 1.9.2 problems. [Ian White] - removes "can't add a new key into hash during iteration" problem with ActiveRecord OrmAdapter - removes problem with rspec 2 mocks interacting with ruby 1.9.2 #to_ary == 0.0.2 * Add #get to the API. Ensure both #get and #get! complies with to_key requirements. [José Valim] * Extract tests into shared example. Give instructions on how to write a new adapter. [Ian White] == 0.0.1 * Initial release [Ian White, José Valim] orm_adapter-0.5.0/spec/0000755000004100000410000000000012261216643014776 5ustar www-datawww-dataorm_adapter-0.5.0/spec/orm_adapter_spec.rb0000644000004100000410000000050612261216643020633 0ustar www-datawww-datarequire 'spec_helper' describe OrmAdapter do subject { OrmAdapter } describe "when a new adapter is created (by inheriting form OrmAdapter::Base)" do let!(:adapter) { Class.new(OrmAdapter::Base) } its(:adapters) { should include(adapter) } after { OrmAdapter.adapters.delete(adapter) } end end orm_adapter-0.5.0/spec/spec_helper.rb0000644000004100000410000000043012261216643017611 0ustar www-datawww-datarequire 'rubygems' require 'rspec' $:.unshift(File.dirname(__FILE__) + '/../lib') ['dm-core', 'dm-active_model','mongoid', 'active_record', 'mongo_mapper'].each do |orm| begin require orm rescue LoadError puts "#{orm} not available" end end require 'orm_adapter' orm_adapter-0.5.0/spec/orm_adapter/0000755000004100000410000000000012261216643017273 5ustar www-datawww-dataorm_adapter-0.5.0/spec/orm_adapter/example_app_shared.rb0000644000004100000410000002241312261216643023443 0ustar www-datawww-data# to test your new orm_adapter, make an example app that matches the functionality # found in the existing specs for example, look at spec/orm_adapter/adapters/active_record_spec.rb # # Then you can execute this shared spec as follows: # # it_should_behave_like "execute app with orm_adapter" do # let(:user_class) { User } # let(:note_class) { Note } # # # optionaly define the following functions if the ORM does not support # # this syntax - this should NOT use the orm_adapter, because we're testing that # def create_model(klass, attrs = {}) # klass.create!(attrs) # end # # def reload_model(model) # model.class.find(model.id) # end # end # shared_examples_for "example app with orm_adapter" do def create_model(klass, attrs = {}) klass.create!(attrs) end def reload_model(model) model.class.find(model.id) end describe "an ORM class" do subject { note_class } it "#to_adapter should return an adapter instance" do subject.to_adapter.should be_a(OrmAdapter::Base) end it "#to_adapter should return an adapter for the receiver" do subject.to_adapter.klass.should == subject end it "#to_adapter should be cached" do subject.to_adapter.object_id.should == subject.to_adapter.object_id end end describe "adapter instance" do let(:note_adapter) { note_class.to_adapter } let(:user_adapter) { user_class.to_adapter } describe "#get!(id)" do it "should return the instance with id if it exists" do user = create_model(user_class) user_adapter.get!(user.id).should == user end it "should allow to_key like arguments" do user = create_model(user_class) user_adapter.get!(user.to_key).should == user end it "should raise an error if there is no instance with that id" do lambda { user_adapter.get!("nonexistent id") }.should raise_error end end describe "#get(id)" do it "should return the instance with id if it exists" do user = create_model(user_class) user_adapter.get(user.id).should == user end it "should allow to_key like arguments" do user = create_model(user_class) user_adapter.get(user.to_key).should == user end it "should return nil if there is no instance with that id" do user_adapter.get("nonexistent id").should be_nil end end describe "#find_first" do describe "(conditions)" do it "should return first model matching conditions, if it exists" do user = create_model(user_class, :name => "Fred") user_adapter.find_first(:name => "Fred").should == user end it "should return nil if no conditions match" do user_adapter.find_first(:name => "Betty").should == nil end it 'should return the first model if no conditions passed' do user = create_model(user_class) create_model(user_class) user_adapter.find_first.should == user end it "when conditions contain associated object, should return first model if it exists" do user = create_model(user_class) note = create_model(note_class, :owner => user) note_adapter.find_first(:owner => user).should == note end it "understands :id as a primary key condition (allowing scoped finding)" do create_model(user_class, :name => "Fred") user = create_model(user_class, :name => "Fred") user_adapter.find_first(:id => user.id, :name => "Fred").should == user user_adapter.find_first(:id => user.id, :name => "Not Fred").should be_nil end end describe "(:order => )" do it "should return first model in specified order" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user_adapter.find_first(:order => [:name, [:rating, :desc]]).should == user2 end end describe "(:conditions => , :order => )" do it "should return first model matching conditions, in specified order" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user_adapter.find_first(:conditions => {:name => "Fred"}, :order => [:rating, :desc]).should == user2 end end end describe "#find_all" do describe "(conditions)" do it "should return only models matching conditions" do user1 = create_model(user_class, :name => "Fred") user2 = create_model(user_class, :name => "Fred") user3 = create_model(user_class, :name => "Betty") user_adapter.find_all(:name => "Fred").should == [user1, user2] end it "should return all models if no conditions passed" do user1 = create_model(user_class, :name => "Fred") user2 = create_model(user_class, :name => "Fred") user3 = create_model(user_class, :name => "Betty") user_adapter.find_all.should == [user1, user2, user3] end it "should return empty array if no conditions match" do user_adapter.find_all(:name => "Fred").should == [] end it "when conditions contain associated object, should return first model if it exists" do user1, user2 = create_model(user_class), create_model(user_class) note1 = create_model(note_class, :owner => user1) note2 = create_model(note_class, :owner => user2) note_adapter.find_all(:owner => user2).should == [note2] end end describe "(:order => )" do it "should return all models in specified order" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user3 = create_model(user_class, :name => "Betty", :rating => 1) user_adapter.find_all(:order => [:name, [:rating, :desc]]).should == [user3, user2, user1] end end describe "(:conditions => , :order => )" do it "should return only models matching conditions, in specified order" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user3 = create_model(user_class, :name => "Betty", :rating => 1) user_adapter.find_all(:conditions => {:name => "Fred"}, :order => [:rating, :desc]).should == [user2, user1] end end describe "(:limit => )" do it "should return a limited set of matching models" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user3 = create_model(user_class, :name => "Betty", :rating => 1) user_adapter.find_all(:limit => 1).should == [user1] user_adapter.find_all(:limit => 2).should == [user1, user2] end end describe "(:offset => ) with limit (as DataMapper doesn't allow offset on its own)" do it "should return an offset set of matching models" do user1 = create_model(user_class, :name => "Fred", :rating => 1) user2 = create_model(user_class, :name => "Fred", :rating => 2) user3 = create_model(user_class, :name => "Betty", :rating => 1) user_adapter.find_all(:limit => 3, :offset => 0).should == [user1, user2, user3] user_adapter.find_all(:limit => 3, :offset => 1).should == [user2, user3] user_adapter.find_all(:limit => 1, :offset => 1).should == [user2] end end end describe "#create!(attributes)" do it "should create a model with the passed attributes" do user = user_adapter.create!(:name => "Fred") reload_model(user).name.should == "Fred" end it "should raise error when create fails" do lambda { user_adapter.create!(:user => create_model(note_class)) }.should raise_error end it "when attributes contain an associated object, should create a model with the attributes" do user = create_model(user_class) note = note_adapter.create!(:owner => user) reload_model(note).owner.should == user end it "when attributes contain an has_many assoc, should create a model with the attributes" do notes = [create_model(note_class), create_model(note_class)] user = user_adapter.create!(:notes => notes) reload_model(user).notes.should == notes end end describe "#destroy(instance)" do it "should destroy the instance if it exists" do user = create_model(user_class) user_adapter.destroy(user).should be_true user_adapter.get(user.id).should be_nil end it "should return nil if passed with an invalid instance" do user_adapter.destroy("nonexistent instance").should be_nil end it "should not destroy the instance if it doesn't match the model class" do user = create_model(user_class) note_adapter.destroy(user).should be_nil user_adapter.get(user.id).should == user end end end end orm_adapter-0.5.0/spec/orm_adapter/adapters/0000755000004100000410000000000012261216643021076 5ustar www-datawww-dataorm_adapter-0.5.0/spec/orm_adapter/adapters/active_record_spec.rb0000644000004100000410000000372712261216643025257 0ustar www-datawww-datarequire 'spec_helper' require 'orm_adapter/example_app_shared' if !defined?(ActiveRecord::Base) puts "** require 'active_record' to run the specs in #{__FILE__}" else ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:") ActiveRecord::Migration.suppress_messages do ActiveRecord::Schema.define(:version => 0) do create_table(:users, :force => true) {|t| t.string :name; t.integer :rating; } create_table(:notes, :force => true) {|t| t.belongs_to :owner, :polymorphic => true } end end module ArOrmSpec class User < ActiveRecord::Base has_many :notes, :as => :owner end class AbstractNoteClass < ActiveRecord::Base self.abstract_class = true end class Note < AbstractNoteClass belongs_to :owner, :polymorphic => true end # here be the specs! describe '[ActiveRecord orm adapter]' do before do User.delete_all Note.delete_all end it_should_behave_like "example app with orm_adapter" do let(:user_class) { User } let(:note_class) { Note } end describe "#conditions_to_fields" do describe "with non-standard association keys" do class PerverseNote < Note belongs_to :user, :foreign_key => 'owner_id' belongs_to :pwner, :polymorphic => true, :foreign_key => 'owner_id', :foreign_type => 'owner_type' end let(:user) { User.create! } let(:adapter) { PerverseNote.to_adapter } it "should convert polymorphic object in conditions to the appropriate fields" do adapter.send(:conditions_to_fields, :pwner => user).should == {'owner_id' => user.id, 'owner_type' => user.class.name} end it "should convert belongs_to object in conditions to the appropriate fields" do adapter.send(:conditions_to_fields, :user => user).should == {'owner_id' => user.id} end end end end end end orm_adapter-0.5.0/spec/orm_adapter/adapters/data_mapper_spec.rb0000644000004100000410000000201312261216643024706 0ustar www-datawww-datarequire 'spec_helper' require 'orm_adapter/example_app_shared' if !defined?(DataMapper) puts "** require 'dm-core' to run the specs in #{__FILE__}" else DataMapper.setup(:default, 'sqlite::memory:') module DmOrmSpec class User include DataMapper::Resource property :id, Serial property :name, String property :rating, Integer has n, :notes, :child_key => [:owner_id] end class Note include DataMapper::Resource property :id, Serial property :body, String belongs_to :owner, 'User' end require 'dm-migrations' DataMapper.finalize DataMapper.auto_migrate! # here be the specs! describe DataMapper::Resource::OrmAdapter do before do User.destroy Note.destroy end it_should_behave_like "example app with orm_adapter" do let(:user_class) { User } let(:note_class) { Note } def reload_model(model) model.class.get(model.id) end end end end end orm_adapter-0.5.0/spec/orm_adapter/adapters/mongoid_spec.rb0000644000004100000410000000200312261216643024064 0ustar www-datawww-datarequire 'spec_helper' require 'orm_adapter/example_app_shared' if !defined?(Mongoid) || !(Mongo::Connection.new.db('orm_adapter_spec') rescue nil) puts "** require 'mongoid' and start mongod to run the specs in #{__FILE__}" else Mongoid.configure do |config| config.master = Mongo::Connection.new.db('orm_adapter_spec') end module MongoidOrmSpec class User include Mongoid::Document field :name field :rating has_many_related :notes, :foreign_key => :owner_id, :class_name => 'MongoidOrmSpec::Note' end class Note include Mongoid::Document field :body, :default => "made by orm" belongs_to_related :owner, :class_name => 'MongoidOrmSpec::User' end # here be the specs! describe Mongoid::Document::OrmAdapter do before do User.delete_all Note.delete_all end it_should_behave_like "example app with orm_adapter" do let(:user_class) { User } let(:note_class) { Note } end end end end orm_adapter-0.5.0/spec/orm_adapter/adapters/mongo_mapper_spec.rb0000644000004100000410000000211312261216643025115 0ustar www-datawww-datarequire 'spec_helper' require 'orm_adapter/example_app_shared' if !defined?(MongoMapper) || !(Mongo::Connection.new.db('orm_adapter_spec') rescue nil) puts "** require 'mongo_mapper' and start mongod to run the specs in #{__FILE__}" else MongoMapper.connection = Mongo::Connection.new MongoMapper.database = "orm_adapter_spec" module MongoMapperOrmSpec class User include MongoMapper::Document key :name key :rating many :notes, :foreign_key => :owner_id, :class_name => 'MongoMapperOrmSpec::Note' end class Note include MongoMapper::Document key :body, :default => "made by orm" belongs_to :owner, :class_name => 'MongoMapperOrmSpec::User' end # here be the specs! describe MongoMapper::Document::OrmAdapter do before do MongoMapper.database.collections.each do | coll | coll.remove unless coll.name =~ /system/ end end it_should_behave_like "example app with orm_adapter" do let(:user_class) { User } let(:note_class) { Note } end end end end orm_adapter-0.5.0/spec/orm_adapter/base_spec.rb0000644000004100000410000000565012261216643021552 0ustar www-datawww-datarequire 'spec_helper' describe OrmAdapter::Base do subject { OrmAdapter::Base.new(Object) } describe "#extract_conditions!" do let(:conditions) { {:foo => 'bar'} } let(:order) { [[:foo, :asc]] } let(:limit) { 1 } let(:offset) { 2 } it "()" do subject.send(:extract_conditions!, conditions).should == [conditions, [], nil, nil] end it "(:conditions => )" do subject.send(:extract_conditions!, :conditions => conditions).should == [conditions, [], nil, nil] end it "(:order => )" do subject.send(:extract_conditions!, :order => order).should == [{}, order, nil, nil] end it "(:limit => )" do subject.send(:extract_conditions!, :limit => limit).should == [{}, [], limit, nil] end it "(:offset => )" do subject.send(:extract_conditions!, :offset => offset).should == [{}, [], nil, offset] end it "(:conditions => , :order => )" do subject.send(:extract_conditions!, :conditions => conditions, :order => order).should == [conditions, order, nil, nil] end it "(:conditions => , :limit => )" do subject.send(:extract_conditions!, :conditions => conditions, :limit => limit).should == [conditions, [], limit, nil] end it "(:conditions => , :offset => )" do subject.send(:extract_conditions!, :conditions => conditions, :offset => offset).should == [conditions, [], nil, offset] end describe "#valid_object?" do it "determines whether an object is valid for the current model class" do subject.send(:valid_object?, Object.new).should be_true subject.send(:valid_object?, String.new).should be_false end end describe "#normalize_order" do specify "(nil) returns []" do subject.send(:normalize_order, nil).should == [] end specify ":foo returns [[:foo, :asc]]" do subject.send(:normalize_order, :foo).should == [[:foo, :asc]] end specify "[:foo] returns [[:foo, :asc]]" do subject.send(:normalize_order, [:foo]).should == [[:foo, :asc]] end specify "[:foo, :desc] returns [[:foo, :desc]]" do subject.send(:normalize_order, [:foo, :desc]).should == [[:foo, :desc]] end specify "[:foo, [:bar, :asc], [:baz, :desc], :bing] returns [[:foo, :asc], [:bar, :asc], [:baz, :desc], [:bing, :asc]]" do subject.send(:normalize_order, [:foo, [:bar, :asc], [:baz, :desc], :bing]).should == [[:foo, :asc], [:bar, :asc], [:baz, :desc], [:bing, :asc]] end specify "[[:foo, :wtf]] raises ArgumentError" do lambda { subject.send(:normalize_order, [[:foo, :wtf]]) }.should raise_error(ArgumentError) end specify "[[:foo, :asc, :desc]] raises ArgumentError" do lambda { subject.send(:normalize_order, [[:foo, :asc, :desc]]) }.should raise_error(ArgumentError) end end end end orm_adapter-0.5.0/README.rdoc0000644000004100000410000000731112261216643015654 0ustar www-datawww-data= ORM Adapter {Build Status}[http://travis-ci.org/ianwhite/orm_adapter] Provides a single point of entry for popular ruby ORMs. Its target audience is gem authors who want to support more than one ORM. == Example of use require 'orm_adapter' User # is it an ActiveRecord, DM Resource, MongoMapper or MongoId Document? User.to_adapter.find_first :name => 'Fred' # we don't care! user_model = User.to_adapter user_model.get!(1) # find a record by id user_model.find_first(:name => 'fred') # find first fred user_model.find_first(:level => 'awesome', :id => 23) # find user 23, only if it's level is awesome user_model.find_all # find all users user_model.find_all(:name => 'fred') # find all freds user_model.find_all(:order => :name) # find all freds, ordered by name user_model.create!(:name => 'fred') # create a fred user_model.destroy(object) # destroy the user object @see OrmAdapter::Base for more details of the supported API == Supported ORMs Currently supported ORMs are *ActiveRecord*, *DataMapper*, *MongoMapper*, and *MongoId*. We welcome you to write new adapters as gems. ORM Adapter will stay focused in having these major ORMs working. To write an adapter look at lib/orm_adapter/adapters/active_record.rb for an example of implementation. To see how to test it, look at spec/orm_adapter/example_app_shared.rb, spec/orm_adapter/adapters/active_record_spec.rb. You'll need to require the target ORM in spec/spec_helper.rb == Goals ORM Adapter's goal is to support a minimum API used by most of the plugins that needs agnosticism beyond Active Model. ORM Adapter will support only basic methods, as +get+, +find_first+, create! and so forth. It is not ORM Adapter's goal to support different query constructions, handle table joins, etc. ORM adapter provides a consistent API for these basic class or 'factory' methods. It does not attempt to unify the behaviour of model instances returned by these methods. This means that unifying the behaviour of methods such as `model.save`, and `model.valid?` is beyond the scope of orm_adapter. If you need complex queries, we recommend you to subclass ORM Adapters in your plugin and extend it expressing these query conditions as part of your domain logic. == History 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], {Josh Bassett}[http://github.com/nullobject], {Marc Lee}[http://github.com/maleko], and {Sebastian Zuchmanski}[http://github.com/sebcioz]. {José Valim}[http://github.com/josevalim] suggested the extraction, and worked on the first release with Ian. {Luke Cunningham}[http://github.com/icaruswings] contributes the Mongo Mapper adapter. {Fred Wu}[http://github.com/fredwu] contributes the #destroy methods, and :limit, :offset options for #find_all {Tim Galeckas}[http://github.com/timgaleckas] == Development To run the specs, you can start from the last known good set of gem dependencies in Gemfile.lock.development: git clone http://github.com/ianwhite/orm_adapter cd orm_adapter bundle install bundle exec rake spec To run specs for different versions of ORMs, you can specify a gemfile from the `gemfiles` directory, e.g. BUNDLE_GEMFILE=gemiles/activerecord4.gemfile bundle install BUNDLE_GEMFILE=gemiles/activerecord4.gemfile bundle exec rake spec == Copyright Copyright (c) 2010-2013 Ian White and José Valim. See LICENSE for details. orm_adapter-0.5.0/.travis.yml0000644000004100000410000000044612261216643016161 0ustar www-datawww-datalanguage: ruby matrix: include: - rvm: 1.9.3 gemfile: Gemfile services: mongodb - rvm: 2.0.0 gemfile: Gemfile services: mongodb - rvm: 1.9.3 gemfile: gemfiles/activerecord-4.gemfile - rvm: 2.0.0 gemfile: gemfiles/activerecord-4.gemfile orm_adapter-0.5.0/lib/0000755000004100000410000000000012261216643014612 5ustar www-datawww-dataorm_adapter-0.5.0/lib/orm_adapter/0000755000004100000410000000000012261216643017107 5ustar www-datawww-dataorm_adapter-0.5.0/lib/orm_adapter/adapters/0000755000004100000410000000000012261216643020712 5ustar www-datawww-dataorm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb0000644000004100000410000000445012261216643024053 0ustar www-datawww-datarequire 'active_record' module OrmAdapter class ActiveRecord < Base # Return list of column/property names def column_names klass.column_names end # @see OrmAdapter::Base#get! def get!(id) klass.find(wrap_key(id)) end # @see OrmAdapter::Base#get def get(id) klass.where(klass.primary_key => wrap_key(id)).first end # @see OrmAdapter::Base#find_first def find_first(options = {}) construct_relation(klass, options).first end # @see OrmAdapter::Base#find_all def find_all(options = {}) construct_relation(klass, options) end # @see OrmAdapter::Base#create! def create!(attributes = {}) klass.create!(attributes) end # @see OrmAdapter::Base#destroy def destroy(object) object.destroy && true if valid_object?(object) end protected def construct_relation(relation, options) conditions, order, limit, offset = extract_conditions!(options) relation = relation.where(conditions_to_fields(conditions)) relation = relation.order(order_clause(order)) if order.any? relation = relation.limit(limit) if limit relation = relation.offset(offset) if offset relation end # Introspects the klass to convert and objects in conditions into foreign key and type fields def conditions_to_fields(conditions) fields = {} conditions.each do |key, value| if value.is_a?(::ActiveRecord::Base) && (assoc = klass.reflect_on_association(key.to_sym)) && assoc.belongs_to? if ::ActiveRecord::VERSION::STRING < "3.1" fields[assoc.primary_key_name] = value.send(value.class.primary_key) fields[assoc.options[:foreign_type]] = value.class.base_class.name.to_s if assoc.options[:polymorphic] else # >= 3.1 fields[assoc.foreign_key] = value.send(value.class.primary_key) fields[assoc.foreign_type] = value.class.base_class.name.to_s if assoc.options[:polymorphic] end else fields[key] = value end end fields end def order_clause(order) order.map {|pair| "#{pair[0]} #{pair[1]}"}.join(",") end end end ActiveSupport.on_load(:active_record) do extend ::OrmAdapter::ToAdapter self::OrmAdapter = ::OrmAdapter::ActiveRecord end orm_adapter-0.5.0/lib/orm_adapter/adapters/mongo_mapper.rb0000644000004100000410000000346312261216643023730 0ustar www-datawww-datarequire 'mongo_mapper' module MongoMapper module Document module ClassMethods include OrmAdapter::ToAdapter end class OrmAdapter < ::OrmAdapter::Base # get a list of column names for a given class def column_names klass.column_names end # @see OrmAdapter::Base#get! def get!(id) klass.find!(wrap_key(id)) end # @see OrmAdapter::Base#get def get(id) klass.first({ :id => wrap_key(id) }) end # @see OrmAdapter::Base#find_first def find_first(conditions = {}) conditions, order = extract_conditions!(conditions) conditions = conditions.merge(:sort => order) unless order.nil? klass.first(conditions_to_fields(conditions)) end # @see OrmAdapter::Base#find_all def find_all(conditions = {}) conditions, order, limit, offset = extract_conditions!(conditions) conditions = conditions.merge(:sort => order) unless order.nil? conditions = conditions.merge(:limit => limit) unless limit.nil? conditions = conditions.merge(:offset => offset) unless limit.nil? || offset.nil? klass.all(conditions_to_fields(conditions)) end # @see OrmAdapter::Base#create! def create!(attributes = {}) klass.create!(attributes) end # @see OrmAdapter::Base#destroy def destroy(object) object.destroy if valid_object?(object) end protected # converts and documents to ids def conditions_to_fields(conditions) conditions.inject({}) do |fields, (key, value)| if value.is_a?(MongoMapper::Document) && klass.key?("#{key}_id") fields.merge("#{key}_id" => value.id) else fields.merge(key => value) end end end end end end orm_adapter-0.5.0/lib/orm_adapter/adapters/mongoid.rb0000644000004100000410000000321712261216643022676 0ustar www-datawww-datarequire 'mongoid' module Mongoid module Document module ClassMethods include OrmAdapter::ToAdapter end class OrmAdapter < ::OrmAdapter::Base # get a list of column names for a given class def column_names klass.fields.keys end # @see OrmAdapter::Base#get! def get!(id) klass.find(wrap_key(id)) end # @see OrmAdapter::Base#get def get(id) klass.where(:_id => wrap_key(id)).first end # @see OrmAdapter::Base#find_first def find_first(options = {}) conditions, order = extract_conditions!(options) klass.limit(1).where(conditions_to_fields(conditions)).order_by(order).first end # @see OrmAdapter::Base#find_all def find_all(options = {}) conditions, order, limit, offset = extract_conditions!(options) klass.where(conditions_to_fields(conditions)).order_by(order).limit(limit).offset(offset) end # @see OrmAdapter::Base#create! def create!(attributes = {}) klass.create!(attributes) end # @see OrmAdapter::Base#destroy def destroy(object) object.destroy if valid_object?(object) end protected # converts and documents to ids def conditions_to_fields(conditions) conditions.inject({}) do |fields, (key, value)| if value.is_a?(Mongoid::Document) && klass.fields.keys.include?("#{key}_id") fields.merge("#{key}_id" => value.id) elsif key.to_s == 'id' fields.merge('_id' => value) else fields.merge(key => value) end end end end end end orm_adapter-0.5.0/lib/orm_adapter/adapters/data_mapper.rb0000644000004100000410000000262112261216643023515 0ustar www-datawww-datarequire 'dm-core' module DataMapper module Model include OrmAdapter::ToAdapter end module Resource class OrmAdapter < ::OrmAdapter::Base # get a list of column names for a given class def column_names klass.properties.map(&:name) end # @see OrmAdapter::Base#get! def get!(id) klass.get!(id) end # @see OrmAdapter::Base#get def get(id) klass.get(id) end # @see OrmAdapter::Base#find_first def find_first(options = {}) conditions, order = extract_conditions!(options) klass.first :conditions => conditions, :order => order_clause(order) end # @see OrmAdapter::Base#find_all def find_all(options = {}) conditions, order, limit, offset = extract_conditions!(options) opts = { :conditions => conditions, :order => order_clause(order) } opts = opts.merge({ :limit => limit }) unless limit.nil? opts = opts.merge({ :offset => offset }) unless offset.nil? klass.all opts end # @see OrmAdapter::Base#create! def create!(attributes = {}) klass.create(attributes) end # @see OrmAdapter::Base#destroy def destroy(object) object.destroy if valid_object?(object) end protected def order_clause(order) order.map {|pair| pair.first.send(pair.last)} end end end end orm_adapter-0.5.0/lib/orm_adapter/version.rb0000644000004100000410000000005212261216643021116 0ustar www-datawww-datamodule OrmAdapter VERSION = "0.5.0" end orm_adapter-0.5.0/lib/orm_adapter/to_adapter.rb0000644000004100000410000000025212261216643021555 0ustar www-datawww-datamodule OrmAdapter # Extend into a class that has an OrmAdapter module ToAdapter def to_adapter @_to_adapter ||= self::OrmAdapter.new(self) end end endorm_adapter-0.5.0/lib/orm_adapter/base.rb0000644000004100000410000000756212261216643020360 0ustar www-datawww-datamodule OrmAdapter class Base attr_reader :klass # Your ORM adapter needs to inherit from this Base class and its adapter # will be registered. To create an adapter you should create an inner # constant "OrmAdapter" e.g. ActiveRecord::Base::OrmAdapter # # @see orm_adapters/active_record # @see orm_adapters/datamapper # @see orm_adapters/mongoid def self.inherited(adapter) OrmAdapter.adapters << adapter super end def initialize(klass) @klass = klass end # Get a list of column/property/field names def column_names raise NotSupportedError end # Get an instance by id of the model. Raises an error if a model is not found. # This should comply with ActiveModel#to_key API, i.e.: # # User.to_adapter.get!(@user.to_key) == @user # def get!(id) raise NotSupportedError end # Get an instance by id of the model. Returns nil if a model is not found. # This should comply with ActiveModel#to_key API, i.e.: # # User.to_adapter.get(@user.to_key) == @user # def get(id) raise NotSupportedError end # Find the first instance, optionally matching conditions, and specifying order # # You can call with just conditions, providing a hash # # User.to_adapter.find_first :name => "Fred", :age => 23 # # Or you can specify :order, and :conditions as keys # # User.to_adapter.find_first :conditions => {:name => "Fred", :age => 23} # User.to_adapter.find_first :order => [:age, :desc] # User.to_adapter.find_first :order => :name, :conditions => {:age => 18} # # When specifying :order, it may be # * a single arg e.g. :order => :name # * a single pair with :asc, or :desc as last, e.g. :order => [:name, :desc] # * an array of single args or pairs (with :asc or :desc as last), e.g. :order => [[:name, :asc], [:age, :desc]] # def find_first(options = {}) raise NotSupportedError end # Find all models, optionally matching conditions, and specifying order # @see OrmAdapter::Base#find_first for how to specify order and conditions def find_all(options = {}) raise NotSupportedError end # Create a model using attributes def create!(attributes = {}) raise NotSupportedError end # Destroy an instance by passing in the instance itself. def destroy(object) raise NotSupportedError end protected def valid_object?(object) object.class == klass end def wrap_key(key) key.is_a?(Array) ? key.first : key end # given an options hash, # with optional :conditions, :order, :limit and :offset keys, # returns conditions, normalized order, limit and offset def extract_conditions!(options = {}) order = normalize_order(options.delete(:order)) limit = options.delete(:limit) offset = options.delete(:offset) conditions = options.delete(:conditions) || options [conditions, order, limit, offset] end # given an order argument, returns an array of pairs, with each pair containing the attribute, and :asc or :desc def normalize_order(order) order = Array(order) if order.length == 2 && !order[0].is_a?(Array) && [:asc, :desc].include?(order[1]) order = [order] else order = order.map {|pair| pair.is_a?(Array) ? pair : [pair, :asc] } end order.each do |pair| pair.length == 2 or raise ArgumentError, "each order clause must be a pair (unknown clause #{pair.inspect})" [:asc, :desc].include?(pair[1]) or raise ArgumentError, "order must be specified with :asc or :desc (unknown key #{pair[1].inspect})" end order end end class NotSupportedError < NotImplementedError def to_s "method not supported by this orm adapter" end end end orm_adapter-0.5.0/lib/orm_adapter.rb0000644000004100000410000000100112261216643017424 0ustar www-datawww-datarequire 'orm_adapter/base' require 'orm_adapter/to_adapter' require 'orm_adapter/version' module OrmAdapter # A collection of registered adapters def self.adapters @@adapters ||= [] end end require 'orm_adapter/adapters/active_record' if defined?(ActiveRecord::Base) require 'orm_adapter/adapters/data_mapper' if defined?(DataMapper::Resource) require 'orm_adapter/adapters/mongoid' if defined?(Mongoid::Document) require 'orm_adapter/adapters/mongo_mapper' if defined?(MongoMapper::Document)orm_adapter-0.5.0/gemfiles/0000755000004100000410000000000012261216643015637 5ustar www-datawww-dataorm_adapter-0.5.0/gemfiles/activerecord-4.gemfile0000644000004100000410000000020412261216643022000 0ustar www-datawww-datasource "https://rubygems.org" gem "rake", ">= 10" gem "activerecord", "~> 4.0.1" gem "rspec", ">= 2.4.0" gem "sqlite3", ">= 1.3.2" orm_adapter-0.5.0/metadata.yml0000644000004100000410000001541512261216643016355 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: orm_adapter version: !ruby/object:Gem::Version version: 0.5.0 platform: ruby authors: - Ian White - Jose Valim autorequire: bindir: bin cert_chain: [] date: 2013-11-12 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.0.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.0.0 - !ruby/object:Gem::Dependency name: git requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.2.5 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.2.5 - !ruby/object:Gem::Dependency name: yard requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 0.6.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 0.6.0 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 0.8.7 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 0.8.7 - !ruby/object:Gem::Dependency name: activerecord requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.2.15 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 3.2.15 - !ruby/object:Gem::Dependency name: mongoid requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 2.8.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 2.8.0 - !ruby/object:Gem::Dependency name: mongo_mapper requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.11.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.11.0 - !ruby/object:Gem::Dependency name: bson_ext requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.0 - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 2.4.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 2.4.0 - !ruby/object:Gem::Dependency name: sqlite3 requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.2 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.2 - !ruby/object:Gem::Dependency name: datamapper requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: dm-sqlite-adapter requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: dm-active_model requirement: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '1.0' description: Provides a single point of entry for using basic features of ruby ORMs email: ian.w.white@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - .gitignore - .rspec - .travis.yml - Gemfile - History.txt - LICENSE - README.rdoc - Rakefile - gemfiles/activerecord-4.gemfile - lib/orm_adapter.rb - lib/orm_adapter/adapters/active_record.rb - lib/orm_adapter/adapters/data_mapper.rb - lib/orm_adapter/adapters/mongo_mapper.rb - lib/orm_adapter/adapters/mongoid.rb - lib/orm_adapter/base.rb - lib/orm_adapter/to_adapter.rb - lib/orm_adapter/version.rb - orm_adapter.gemspec - spec/orm_adapter/adapters/active_record_spec.rb - spec/orm_adapter/adapters/data_mapper_spec.rb - spec/orm_adapter/adapters/mongo_mapper_spec.rb - spec/orm_adapter/adapters/mongoid_spec.rb - spec/orm_adapter/base_spec.rb - spec/orm_adapter/example_app_shared.rb - spec/orm_adapter_spec.rb - spec/spec_helper.rb homepage: http://github.com/ianwhite/orm_adapter licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.3.6 requirements: [] rubyforge_project: orm_adapter rubygems_version: 2.0.6 signing_key: specification_version: 4 summary: orm_adapter provides a single point of entry for using basic features of popular ruby ORMs. Its target audience is gem authors who want to support many ruby ORMs. test_files: - spec/orm_adapter/adapters/active_record_spec.rb - spec/orm_adapter/adapters/data_mapper_spec.rb - spec/orm_adapter/adapters/mongo_mapper_spec.rb - spec/orm_adapter/adapters/mongoid_spec.rb - spec/orm_adapter/base_spec.rb - spec/orm_adapter/example_app_shared.rb - spec/orm_adapter_spec.rb - spec/spec_helper.rb has_rdoc: orm_adapter-0.5.0/orm_adapter.gemspec0000644000004100000410000000304312261216643017706 0ustar www-datawww-data$:.push File.expand_path("../lib", __FILE__) require "orm_adapter/version" Gem::Specification.new do |s| s.name = "orm_adapter" s.version = OrmAdapter::VERSION.dup s.platform = Gem::Platform::RUBY s.authors = ["Ian White", "Jose Valim"] s.description = "Provides a single point of entry for using basic features of ruby ORMs" s.summary = "orm_adapter provides a single point of entry for using basic features of popular ruby ORMs. Its target audience is gem authors who want to support many ruby ORMs." s.email = "ian.w.white@gmail.com" s.homepage = "http://github.com/ianwhite/orm_adapter" s.license = "MIT" s.rubyforge_project = "orm_adapter" s.required_rubygems_version = ">= 1.3.6" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.require_paths = ["lib"] s.add_development_dependency "bundler", ">= 1.0.0" s.add_development_dependency "git", ">= 1.2.5" s.add_development_dependency "yard", ">= 0.6.0" s.add_development_dependency "rake", ">= 0.8.7" s.add_development_dependency "activerecord", ">= 3.2.15" s.add_development_dependency "mongoid", "~> 2.8.0" s.add_development_dependency "mongo_mapper", "~> 0.11.0" s.add_development_dependency "bson_ext", ">= 1.3.0" s.add_development_dependency "rspec", ">= 2.4.0" s.add_development_dependency "sqlite3", ">= 1.3.2" s.add_development_dependency "datamapper", ">= 1.0" s.add_development_dependency "dm-sqlite-adapter", ">= 1.0" s.add_development_dependency "dm-active_model", ">= 1.0" end orm_adapter-0.5.0/.gitignore0000644000004100000410000000022312261216643016031 0ustar www-datawww-data# system crap .DS_Store # local ruby/gems dev stuff .rvmrc .bundle Gemfile.lock gemfiles/*.lock # built docs .yardoc doc # built gems pkg *.gem orm_adapter-0.5.0/LICENSE0000644000004100000410000000206212261216643015051 0ustar www-datawww-dataCopyright (c) 2010-2013 Ian White and José Valim Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. orm_adapter-0.5.0/checksums.yaml.gz0000444000004100000410000000041512261216643017332 0ustar www-datawww-dataURe;rA=^`ULsF>əSMx