orm-adapter-0.4.0/ 0000755 0000764 0000764 00000000000 12042474557 012774 5 ustar pravi pravi orm-adapter-0.4.0/.travis.yml 0000644 0000764 0000764 00000000130 12042474556 015076 0 ustar pravi pravi language: ruby
rvm:
- 1.9.3
before_install: "cp Gemfile.lock.development Gemfile.lock" orm-adapter-0.4.0/Rakefile 0000644 0000764 0000764 00000001557 12042474556 014450 0 ustar pravi pravi #!/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
end orm-adapter-0.4.0/lib/ 0000755 0000764 0000764 00000000000 12042474556 013541 5 ustar pravi pravi orm-adapter-0.4.0/lib/orm_adapter/ 0000755 0000764 0000764 00000000000 12042474556 016036 5 ustar pravi pravi orm-adapter-0.4.0/lib/orm_adapter/version.rb 0000644 0000764 0000764 00000000051 12042474556 020044 0 ustar pravi pravi module OrmAdapter
VERSION = "0.4.0"
end orm-adapter-0.4.0/lib/orm_adapter/adapters/ 0000755 0000764 0000764 00000000000 12042474556 017641 5 ustar pravi pravi orm-adapter-0.4.0/lib/orm_adapter/adapters/mongoid.rb 0000644 0000764 0000764 00000003217 12042474556 021625 0 ustar pravi pravi require '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.rb 0000644 0000764 0000764 00000004236 12042474556 023004 0 ustar pravi pravi require '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.rb 0000644 0000764 0000764 00000003463 12042474556 022657 0 ustar pravi pravi require '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.rb 0000644 0000764 0000764 00000002621 12042474556 022444 0 ustar pravi pravi require '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.rb 0000644 0000764 0000764 00000000252 12042474556 020504 0 ustar pravi pravi module OrmAdapter
# Extend into a class that has an OrmAdapter
module ToAdapter
def to_adapter
@_to_adapter ||= self::OrmAdapter.new(self)
end
end
end orm-adapter-0.4.0/lib/orm_adapter/base.rb 0000644 0000764 0000764 00000007562 12042474556 017307 0 ustar pravi pravi module 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.rb 0000644 0000764 0000764 00000001001 12042474556 016353 0 ustar pravi pravi require '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.gemspec 0000644 0000764 0000764 00000003025 12042474556 016635 0 ustar pravi pravi $:.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.development 0000644 0000764 0000764 00000005653 12042474556 017547 0 ustar pravi pravi PATH
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.yml 0000644 0000764 0000764 00000013770 12042474557 015307 0 ustar pravi pravi --- !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/LICENSE 0000644 0000764 0000764 00000002062 12042474556 014000 0 ustar pravi pravi Copyright (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/.gitignore 0000644 0000764 0000764 00000000202 12042474556 014755 0 ustar pravi pravi # system crap
.DS_Store
# local ruby/gems dev stuff
.rvmrc
.bundle
Gemfile.lock
# built docs
.yardoc
doc
# built gems
pkg
*.gem orm-adapter-0.4.0/README.rdoc 0000644 0000764 0000764 00000007010 12042474556 014577 0 ustar pravi pravi = ORM Adapter {
}[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/ 0000755 0000764 0000764 00000000000 12042474556 013725 5 ustar pravi pravi orm-adapter-0.4.0/spec/spec_helper.rb 0000644 0000764 0000764 00000000467 12042474556 016552 0 ustar pravi pravi require '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/ 0000755 0000764 0000764 00000000000 12042474556 016222 5 ustar pravi pravi orm-adapter-0.4.0/spec/orm_adapter/adapters/ 0000755 0000764 0000764 00000000000 12042474556 020025 5 ustar pravi pravi orm-adapter-0.4.0/spec/orm_adapter/adapters/mongoid_spec.rb 0000644 0000764 0000764 00000002020 12042474556 023012 0 ustar pravi pravi require '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.4.0/spec/orm_adapter/adapters/data_mapper_spec.rb 0000644 0000764 0000764 00000002036 12042474556 023642 0 ustar pravi pravi require '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.4.0/spec/orm_adapter/adapters/active_record_spec.rb 0000644 0000764 0000764 00000004004 12042474556 024173 0 ustar pravi pravi require '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.4.0/spec/orm_adapter/adapters/mongo_mapper_spec.rb 0000644 0000764 0000764 00000002103 12042474556 024043 0 ustar pravi pravi require '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
end orm-adapter-0.4.0/spec/orm_adapter/base_spec.rb 0000644 0000764 0000764 00000005650 12042474556 020501 0 ustar pravi pravi require '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.rb 0000644 0000764 0000764 00000022413 12042474556 022372 0 ustar pravi pravi # 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.rb 0000644 0000764 0000764 00000000506 12042474556 017562 0 ustar pravi pravi require '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/Gemfile 0000644 0000764 0000764 00000000045 12042474556 014265 0 ustar pravi pravi source "http://rubygems.org"
gemspec orm-adapter-0.4.0/History.txt 0000644 0000764 0000764 00000002764 12042474556 015206 0 ustar pravi pravi == 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/.rspec 0000644 0000764 0000764 00000000011 12042474556 014100 0 ustar pravi pravi --colour