lib/orm_adapter/base.rb
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 # Gets a list of the available models for this adapter def self.model_classes raise NotImplementedError, "return a list of available models for this adapter" 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 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. <tt>:order => :name</tt> # * a single pair with :asc, or :desc as last, e.g. <tt>:order => [:name, :desc]</tt> # * an array of single args or pairs (with :asc or :desc as last), e.g. <tt>:order => [[:name, :asc], [:age, :desc]]</tt> # 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 protected def wrap_key(key) key.is_a?(Array) ? key.first : key end # given an options hash, with optional :conditions and :order keys, returns conditions and normalized order def extract_conditions_and_order!(options = {}) order = normalize_order(options.delete(:order)) conditions = options.delete(:conditions) || options [conditions, order] 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