Class: Mongocore::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/mongocore/schema.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Schema

Init



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
# File 'lib/mongocore/schema.rb', line 12

def initialize(klass)
  # Store the document
  @klass = klass

  # Schema path
  @path = File.join(Mongocore.schema, "#{@klass.to_s.downcase}.yml")

  # Load schema
  @schema = YAML.load(File.read(@path)).deep_symbolize_keys

  # Meta
  @meta = @schema[:meta] || {}

  # Keys
  @keys = @schema[:keys] || {}

  # Accessors
  (@accessors = @schema[:accessor] || []).each{|a| @klass.send(:attr_accessor, a)}

  # Many
  (@many = @schema[:many] || []).each{|k| many(k)}

  # Scopes
  (@scopes = @schema[:scopes] || {}).each{|k, v| scope(k, v)}

  # Defaults and foreign keys
  @defaults = {}; @keys.each{|k, v| foreign(k, v); @defaults[k] = v[:default]}
end

Instance Attribute Details

#accessorsObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def accessors
  @accessors
end

#defaultsObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def defaults
  @defaults
end

#keysObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def keys
  @keys
end

#klassObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def klass
  @klass
end

#many(key) ⇒ Object

Many



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def many
  @many
end

#metaObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def meta
  @meta
end

#pathObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def path
  @path
end

#schemaObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def schema
  @schema
end

#scopesObject

Accessors



9
10
11
# File 'lib/mongocore/schema.rb', line 9

def scopes
  @scopes
end

Instance Method Details

#attributes(tags) ⇒ Object

Get attributes that has these tags



42
43
44
# File 'lib/mongocore/schema.rb', line 42

def attributes(tags)
  (tags[0] ? @keys.select{|k, v| v[:tags] & tags} : @keys).keys
end

#bin(val) ⇒ Object

Convert to binary



57
58
59
# File 'lib/mongocore/schema.rb', line 57

def bin(val)
  val.is_a?(BSON::Binary) ? val : BSON::Binary.new(val)
end

#foreign(key, data) ⇒ Object

Foreign keys



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/mongocore/schema.rb', line 116

def foreign(key, data)
  return if key !~ /(.+)_id/
  t = %Q{
    def #{$1}
      @#{$1} ||= mq(#{$1.capitalize}, :_id => @#{key}).first
    end

    def #{$1}=(m)
      @#{key} = m._id rescue (BSON::ObjectId.from_string(m) rescue m)
      @#{$1} = m
    end
  }
  @klass.class_eval t
end

#ids(h) ⇒ Object

Setup query, replace :id with :_id, set up object ids



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mongocore/schema.rb', line 78

def ids(h)
  transform(h).each do |k, v|
    case v
    when Hash
      # Call hashes recursively
      ids(v)
    when Array
      # Return mapped array or recurse hashes
      v.map!{|r| r.is_a?(Hash) ? ids(r) : oid(r)}
    else
      # Convert to object ID if applicable
      h[k] = oid(v) if v.is_a?(String)
    end
  end
end

#oid(id = nil) ⇒ Object

Convert to BSON::ObjectId



105
106
107
108
109
# File 'lib/mongocore/schema.rb', line 105

def oid(id = nil)
  return id if id.is_a?(BSON::ObjectId)
  return BSON::ObjectId.new if !id
  BSON::ObjectId.from_string(id) rescue id
end

#scope(key, data) ⇒ Object

Set up scope and insert it



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/mongocore/schema.rb', line 142

def scope(key, data)
  # Extract the parameters
  pm = data.delete(:params) || []

  # Replace data if we are using parameters
  d = %{#{data}}
  pm.each do |a|
    d.scan(%r{(=>"(#{a})(\.[a-z0-9]+)?")}).each do |n|
      d.gsub!(n[0], %{=>#{n[1]}#{n[2]}})
    end
  end

  # Define the scope method so we can call it
  j = pm.any? ? %{#{pm.join(', ')},} : ''
  t = %Q{
    def #{key}(#{j} q = {}, o = {})
      mq(self, q.merge(#{d}), {:scope => [:#{key}]}.merge(o))
    end
  }
  @klass.instance_eval t
end

#set(key, val) ⇒ Object

Set value based on type



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mongocore/schema.rb', line 62

def set(key, val)
  return nil if val.nil?
  case type(key)
  when :string       then val.to_s
  when :integer      then val.to_i
  when :time         then time(val)
  when :float        then val.to_f
  when :boolean      then val.to_s.to_bool
  when :object_id    then oid(val)
  when :array, :hash then ids(val)
  when :binary       then bin(val)
  else val
  end
end

#time(val) ⇒ Object

Get time



47
48
49
50
51
52
53
54
# File 'lib/mongocore/schema.rb', line 47

def time(val)
  case val
  when Time then val.utc
  when String then Time.parse(val).utc
  when Date, DateTime then val.to_time.utc
  else nil
  end
end

#transform(e) ⇒ Object

Transform :id to _id or id to object id



95
96
97
# File 'lib/mongocore/schema.rb', line 95

def transform(e)
  e.is_a?(Hash) ? e.transform_keys!{|k| k == :id ? :_id : k} : e.map!{|r| oid(r)}
end

#type(key) ⇒ Object

Find type as defined in schema



100
101
102
# File 'lib/mongocore/schema.rb', line 100

def type(key)
  @keys[key][:type].to_sym rescue :string
end