File: base.rb

package info (click to toggle)
ruby-orm-adapter 0.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 180 kB
  • ctags: 88
  • sloc: ruby: 698; makefile: 4
file content (127 lines) | stat: -rw-r--r-- 3,954 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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. <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

    # 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