orm-adapter-0.4.0/0000755000076400007640000000000012042474557012774 5ustar pravipraviorm-adapter-0.4.0/.travis.yml0000644000076400007640000000013012042474556015076 0ustar pravipravilanguage: ruby rvm: - 1.9.3 before_install: "cp Gemfile.lock.development Gemfile.lock"orm-adapter-0.4.0/Rakefile0000644000076400007640000000155712042474556014450 0ustar pravipravi#!/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 task :release => :check_gemfile task :check_gemfile do if File.exists?("Gemfile.lock") && File.read("Gemfile.lock") != File.read("Gemfile.lock.development") cp "Gemfile.lock", "Gemfile.lock.development" raise "** Gemfile.lock.development has been updated, please commit these changes." end endorm-adapter-0.4.0/lib/0000755000076400007640000000000012042474556013541 5ustar pravipraviorm-adapter-0.4.0/lib/orm_adapter/0000755000076400007640000000000012042474556016036 5ustar pravipraviorm-adapter-0.4.0/lib/orm_adapter/version.rb0000644000076400007640000000005112042474556020044 0ustar pravipravimodule OrmAdapter VERSION = "0.4.0" endorm-adapter-0.4.0/lib/orm_adapter/adapters/0000755000076400007640000000000012042474556017641 5ustar pravipraviorm-adapter-0.4.0/lib/orm_adapter/adapters/mongoid.rb0000644000076400007640000000321712042474556021625 0ustar pravipravirequire '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.4.0/lib/orm_adapter/adapters/active_record.rb0000644000076400007640000000423612042474556023004 0ustar pravipravirequire '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 = {}) conditions, order = extract_conditions!(options) klass.where(conditions_to_fields(conditions)).order(*order_clause(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(*order_clause(order)).limit(limit).offset(offset).all 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 # 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.4.0/lib/orm_adapter/adapters/mongo_mapper.rb0000644000076400007640000000346312042474556022657 0ustar pravipravirequire '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.4.0/lib/orm_adapter/adapters/data_mapper.rb0000644000076400007640000000262112042474556022444 0ustar pravipravirequire '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.4.0/lib/orm_adapter/to_adapter.rb0000644000076400007640000000025212042474556020504 0ustar pravipravimodule 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.4.0/lib/orm_adapter/base.rb0000644000076400007640000000756212042474556017307 0ustar pravipravimodule 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.4.0/lib/orm_adapter.rb0000644000076400007640000000100112042474556016353 0ustar pravipravirequire '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.4.0/orm_adapter.gemspec0000644000076400007640000000302512042474556016635 0ustar pravipravi$:.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.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.0.0" s.add_development_dependency "mongoid", ">= 2.0.0.beta.20" s.add_development_dependency "mongo_mapper", ">= 0.9.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.4.0/Gemfile.lock.development0000644000076400007640000000565312042474556017547 0ustar pravipraviPATH remote: . specs: orm_adapter (0.4.0) GEM remote: http://rubygems.org/ specs: activemodel (3.1.3) activesupport (= 3.1.3) builder (~> 3.0.0) i18n (~> 0.6) activerecord (3.1.3) activemodel (= 3.1.3) activesupport (= 3.1.3) arel (~> 2.2.1) tzinfo (~> 0.3.29) activesupport (3.1.3) multi_json (~> 1.0) addressable (2.2.6) arel (2.2.1) bcrypt-ruby (3.0.1) bson (1.5.2) bson_ext (1.5.2) bson (= 1.5.2) builder (3.0.0) data_objects (0.10.7) addressable (~> 2.1) datamapper (1.2.0) dm-aggregates (~> 1.2.0) dm-constraints (~> 1.2.0) dm-core (~> 1.2.0) dm-migrations (~> 1.2.0) dm-serializer (~> 1.2.0) dm-timestamps (~> 1.2.0) dm-transactions (~> 1.2.0) dm-types (~> 1.2.0) dm-validations (~> 1.2.0) diff-lcs (1.1.3) dm-active_model (1.2.0) activemodel (~> 3.1.0) dm-core (~> 1.2.0) dm-aggregates (1.2.0) dm-core (~> 1.2.0) dm-constraints (1.2.0) dm-core (~> 1.2.0) dm-core (1.2.0) addressable (~> 2.2.6) dm-do-adapter (1.2.0) data_objects (~> 0.10.6) dm-core (~> 1.2.0) dm-migrations (1.2.0) dm-core (~> 1.2.0) dm-serializer (1.2.1) dm-core (~> 1.2.0) fastercsv (~> 1.5.4) json (~> 1.6.1) json_pure (~> 1.6.1) multi_json (~> 1.0.3) dm-sqlite-adapter (1.2.0) dm-do-adapter (~> 1.2.0) do_sqlite3 (~> 0.10.6) dm-timestamps (1.2.0) dm-core (~> 1.2.0) dm-transactions (1.2.0) dm-core (~> 1.2.0) dm-types (1.2.1) bcrypt-ruby (~> 3.0.0) dm-core (~> 1.2.0) fastercsv (~> 1.5.4) json (~> 1.6.1) multi_json (~> 1.0.3) stringex (~> 1.3.0) uuidtools (~> 2.1.2) dm-validations (1.2.0) dm-core (~> 1.2.0) do_sqlite3 (0.10.7) data_objects (= 0.10.7) fastercsv (1.5.4) git (1.2.5) i18n (0.6.0) json (1.6.4) json_pure (1.6.4) mongo (1.5.2) bson (= 1.5.2) mongo_mapper (0.10.1) activemodel (~> 3.0) activesupport (~> 3.0) plucky (~> 0.4.0) mongoid (2.4.0) activemodel (~> 3.1) mongo (~> 1.3) tzinfo (~> 0.3.22) multi_json (1.0.4) plucky (0.4.3) mongo (~> 1.3) rake (0.9.2.2) rspec (2.8.0) rspec-core (~> 2.8.0) rspec-expectations (~> 2.8.0) rspec-mocks (~> 2.8.0) rspec-core (2.8.0) rspec-expectations (2.8.0) diff-lcs (~> 1.1.2) rspec-mocks (2.8.0) sqlite3 (1.3.5) stringex (1.3.0) tzinfo (0.3.31) uuidtools (2.1.2) yard (0.7.4) PLATFORMS ruby DEPENDENCIES activerecord (>= 3.0.0) bson_ext (>= 1.3.0) bundler (>= 1.0.0) datamapper (>= 1.0) dm-active_model (>= 1.0) dm-sqlite-adapter (>= 1.0) git (>= 1.2.5) mongo_mapper (>= 0.9.0) mongoid (>= 2.0.0.beta.20) orm_adapter! rake (>= 0.8.7) rspec (>= 2.4.0) sqlite3 (>= 1.3.2) yard (>= 0.6.0) orm-adapter-0.4.0/metadata.yml0000644000076400007640000001377012042474557015307 0ustar pravipravi--- !ruby/object:Gem::Specification name: orm_adapter version: !ruby/object:Gem::Version version: 0.4.0 prerelease: platform: ruby authors: - Ian White - Jose Valim autorequire: bindir: bin cert_chain: [] date: 2012-07-09 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: bundler requirement: &70358654083860 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.0.0 type: :development prerelease: false version_requirements: *70358654083860 - !ruby/object:Gem::Dependency name: git requirement: &70358654083320 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.2.5 type: :development prerelease: false version_requirements: *70358654083320 - !ruby/object:Gem::Dependency name: yard requirement: &70358654082820 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.6.0 type: :development prerelease: false version_requirements: *70358654082820 - !ruby/object:Gem::Dependency name: rake requirement: &70358654082040 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.8.7 type: :development prerelease: false version_requirements: *70358654082040 - !ruby/object:Gem::Dependency name: activerecord requirement: &70358654080600 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 3.0.0 type: :development prerelease: false version_requirements: *70358654080600 - !ruby/object:Gem::Dependency name: mongoid requirement: &70358654079240 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 2.0.0.beta.20 type: :development prerelease: false version_requirements: *70358654079240 - !ruby/object:Gem::Dependency name: mongo_mapper requirement: &70358654078040 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.9.0 type: :development prerelease: false version_requirements: *70358654078040 - !ruby/object:Gem::Dependency name: bson_ext requirement: &70358654077240 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.3.0 type: :development prerelease: false version_requirements: *70358654077240 - !ruby/object:Gem::Dependency name: rspec requirement: &70358654076340 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 2.4.0 type: :development prerelease: false version_requirements: *70358654076340 - !ruby/object:Gem::Dependency name: sqlite3 requirement: &70358654056980 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.3.2 type: :development prerelease: false version_requirements: *70358654056980 - !ruby/object:Gem::Dependency name: datamapper requirement: &70358654056260 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: *70358654056260 - !ruby/object:Gem::Dependency name: dm-sqlite-adapter requirement: &70358654055740 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: *70358654055740 - !ruby/object:Gem::Dependency name: dm-active_model requirement: &70358654055220 !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: *70358654055220 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 - Gemfile.lock.development - History.txt - LICENSE - README.rdoc - Rakefile - 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: [] post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' segments: - 0 hash: 3652466131119741366 required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.3.6 requirements: [] rubyforge_project: orm_adapter rubygems_version: 1.8.15 signing_key: specification_version: 3 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.4.0/LICENSE0000644000076400007640000000206212042474556014000 0ustar pravipraviCopyright (c) 2010-2012 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.4.0/.gitignore0000644000076400007640000000020212042474556014755 0ustar pravipravi# system crap .DS_Store # local ruby/gems dev stuff .rvmrc .bundle Gemfile.lock # built docs .yardoc doc # built gems pkg *.gemorm-adapter-0.4.0/README.rdoc0000644000076400007640000000701012042474556014577 0ustar pravipravi= 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 cp Gemfile.lock.development Gemfile.lock bundle bundle exec rake spec == Copyright Copyright (c) 2010-2012 Ian White and José Valim. See LICENSE for details. orm-adapter-0.4.0/spec/0000755000076400007640000000000012042474556013725 5ustar pravipraviorm-adapter-0.4.0/spec/spec_helper.rb0000644000076400007640000000046712042474556016552 0ustar pravipravirequire 'rubygems' require 'rspec' $:.unshift(File.dirname(__FILE__) + '/../lib') ['dm-core', 'mongoid', 'active_record', 'mongo_mapper'].each do |orm| begin require orm rescue LoadError puts "#{orm} not available" end end require 'dm-active_model' if defined?(DataMapper) require 'orm_adapter'orm-adapter-0.4.0/spec/orm_adapter/0000755000076400007640000000000012042474556016222 5ustar pravipraviorm-adapter-0.4.0/spec/orm_adapter/adapters/0000755000076400007640000000000012042474556020025 5ustar pravipraviorm-adapter-0.4.0/spec/orm_adapter/adapters/mongoid_spec.rb0000644000076400007640000000202012042474556023012 0ustar pravipravirequire '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 endorm-adapter-0.4.0/spec/orm_adapter/adapters/data_mapper_spec.rb0000644000076400007640000000203612042474556023642 0ustar pravipravirequire '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 endorm-adapter-0.4.0/spec/orm_adapter/adapters/active_record_spec.rb0000644000076400007640000000400412042474556024173 0ustar pravipravirequire '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 endorm-adapter-0.4.0/spec/orm_adapter/adapters/mongo_mapper_spec.rb0000644000076400007640000000210312042474556024043 0ustar pravipravirequire '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 end end it_should_behave_like "example app with orm_adapter" do let(:user_class) { User } let(:note_class) { Note } end end end endorm-adapter-0.4.0/spec/orm_adapter/base_spec.rb0000644000076400007640000000565012042474556020501 0ustar pravipravirequire '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.4.0/spec/orm_adapter/example_app_shared.rb0000644000076400007640000002241312042474556022372 0ustar pravipravi# 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 == 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.4.0/spec/orm_adapter_spec.rb0000644000076400007640000000050612042474556017562 0ustar pravipravirequire '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.4.0/Gemfile0000644000076400007640000000004512042474556014265 0ustar pravipravisource "http://rubygems.org" gemspecorm-adapter-0.4.0/History.txt0000644000076400007640000000276412042474556015206 0ustar pravipravi== 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.4.0/.rspec0000644000076400007640000000001112042474556014100 0ustar pravipravi--colour