Module: StrokeDB::Meta

Defined in:
lib/document/meta.rb,
lib/document/util.rb

Overview

Meta is basically a type. Imagine the following document:

some_apple:

weight: 3oz
color: green
price: $3

Each apple is a fruit and a product in this case (because it has price).

we can express it by assigning metas to document like this:

some_apple:

meta: [Fruit, Product]
weight: 3oz
color: green
price: $3

In document slots metas store references to metadocument.

Document class will be extended by modules Fruit and Product.

Defined Under Namespace

Modules: Util

Constant Summary collapse

CALLBACKS =
%w(on_initialization on_load before_save after_save when_slot_not_found on_new_document on_validation 
after_validation on_set_slot)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.document(store = nil) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/document/meta.rb', line 53

def document(store=nil)
  raise NoDefaultStoreError.new unless store ||= StrokeDB.default_store
  unless meta_doc = store.find(NIL_UUID)
    meta_doc = Document.create!(store, :name => Meta.name, :uuid => NIL_UUID)
  end
  meta_doc
end

.new(*args, &block) ⇒ Object



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
# File 'lib/document/meta.rb', line 25

def new(*args, &block)
  mod = Module.new
  args = args.unshift(nil) if args.empty? || args.first.is_a?(Hash)
  args << {} unless args.last.is_a?(Hash)
  mod.module_eval do
    @args = args
    @meta_initialization_procs = []
    @metas = [self]
    extend Meta
    extend Associations
    extend Validations
    extend Coercions
    extend Virtualizations
    extend Util
  end
  mod.module_eval(&block) if block_given?
  mod.module_eval do
    initialize_associations
    initialize_validations
    initialize_coercions
    initialize_virtualizations
  end
  if meta_name = extract_meta_name(*args)
    Object.const_set(meta_name, mod)
  end
  mod
end

Instance Method Details

#+(meta) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/document/meta.rb', line 73

def +(meta)
  if is_a?(Module) && meta.is_a?(Module)
    new_meta = Module.new
    instance_variables.each do |iv|
      new_meta.instance_variable_set(iv, instance_variable_get(iv) ? instance_variable_get(iv).clone : nil)
    end
    new_meta.instance_variable_set(:@metas, @metas.clone)
    new_meta.instance_variable_get(:@metas) << meta
    new_meta.module_eval do
      extend Meta
    end
    new_meta_name = new_meta.instance_variable_get(:@metas).map{|m| m.name}.join('__')
    Object.send(:remove_const, new_meta_name) rescue nil
    Object.const_set(new_meta_name, new_meta)
    new_meta
  elsif is_a?(Document) && meta.is_a?(Document)
    (Document.new(store, self.to_raw.except('uuid','version','previous_version'), true) +
    Document.new(store, meta.to_raw.except('uuid','version','previous_version'), true)).extend(Meta).make_immutable!
  else
    raise "Can't + #{self.class} and #{meta.class}"
  end
end

#create!(*args, &block) ⇒ Object



115
116
117
# File 'lib/document/meta.rb', line 115

def create!(*args, &block)
  new(*args, &block).save!
end

#document(store = nil) ⇒ Object



195
196
197
198
199
200
201
# File 'lib/document/meta.rb', line 195

def document(store=nil)
  metadocs = @metas.map do |m|
    @args = m.instance_variable_get(:@args)
    make_document(store)
  end
  metadocs.size > 1 ? metadocs.inject { |a, b| a + b }.make_immutable! : metadocs.first
end

#find(*args) ⇒ Object

Finds all documents matching given parameters. The simplest form of find call is without any parameters. This returns all documents belonging to the meta as an array.

User = Meta.new
all_users = User.find

Another form is to find a document by its UUID:

specific_user = User.find("1e3d02cc-0769-4bd8-9113-e033b246b013")

If the UUID is not found, nil is returned.

Most prominent search uses slot values as criteria:

short_fat_joes = User.find(:name => "joe", :weight => 110, :height => 167)

All matching documents are returned as an array.

In all described cases the default store is used. You may also specify another store as the first argument:

all_my_users = User.find(my_store)
all_my_joes  = User.find(my_store, :name => "joe")
oh_my        = User.find(my_store, "1e3d02cc-0769-4bd8-9113-e033b246b013")


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/document/meta.rb', line 146

def find(*args)
  if args.empty? || !args.first.respond_to?(:search)
    raise NoDefaultStoreError unless StrokeDB.default_store
    
    args = args.unshift(StrokeDB.default_store) 
  end

  unless args.size == 1 || args.size == 2
    raise ArgumentError, "Invalid arguments for find"
  end

  store = args[0]
  opt = { :meta => @metas.map {|m| m.document(store)} }

  case args[1]
  when String
    raise ArgumentError, "Invalid UUID" unless args[1].match(UUID_RE)

    store.search(opt.merge({ :uuid => args[1] })).first
  when Hash
    store.search opt.merge(args[1])
  when nil
    store.search opt
  else
    raise ArgumentError, "Invalid search criteria for find"
  end
end

#find_or_create(*args) ⇒ Object

Similar to find, but a creates document with appropriate slot values if not found.

If found, returned is only the first result.



180
181
182
183
# File 'lib/document/meta.rb', line 180

def find_or_create(*args)
  result = find(*args)
  result.empty? ? create!(*args) : result.first
end

#inspectObject Also known as: to_s



185
186
187
188
189
190
191
# File 'lib/document/meta.rb', line 185

def inspect
  if is_a?(Module)
    name
  else
    pretty_print
  end
end

#new(*args, &block) ⇒ Object



107
108
109
110
111
112
113
# File 'lib/document/meta.rb', line 107

def new(*args, &block)
  args = args.clone
  args << {} unless args.last.is_a?(Hash)
  args.last[:meta] = @metas
  doc = Document.new(*args, &block)
  doc
end