-
Notifications
You must be signed in to change notification settings - Fork 1
/
document.rb
147 lines (121 loc) · 3.4 KB
/
document.rb
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# frozen_string_literal: true
module Esse
class Document
MUTATIONS_FALLBACK = {}.freeze
attr_reader :object, :options
def initialize(object, **options)
@object = object
@options = options.freeze
end
# @return [String, Number] the document ID
# @abstract Override this method to return the document ID
def id
raise NotImplementedError, 'Override this method to return the document ID'
end
# @return [String, nil] the document type
# @abstract Override this method to return the document type
def type
nil
end
# @return [Boolean] whether the document has type
def type?
!type.nil?
end
# @return [String, nil] the document routing
# @abstract Override this method to return the document routing
def routing
nil
end
# @return [Boolean] whether the document has routing
def routing?
!routing.nil?
end
# @TODO allow import, index, bulk to accept a suffix to tell which index to use
# def index_suffix
# nil
# end
# @return [Hash] the document meta
# @abstract Override this method to return the document meta
def meta
{}
end
# @return [Hash] the document source
# @abstract Override this method to return the document source
def source
{}
end
# @return [Hash] the document data
def to_h
mutated_source.merge(
_id: id,
).tap do |hash|
hash[:_type] = type if type
hash[:_routing] = routing if routing
hash.merge!(meta)
end
end
def to_bulk(data: true, operation: nil)
doc_header.tap do |h|
if data && operation == :update
h[:data] = { doc: mutated_source }
elsif data
h[:data] = mutated_source
end
h.merge!(meta)
end
end
def ignore_on_index?
id.nil?
end
def ignore_on_delete?
id.nil?
end
def eql?(other, match_lazy_doc_header: false)
if match_lazy_doc_header
other.eql?(self)
else
other.is_a?(Esse::Document) && (
id.to_s == other.id.to_s && type == other.type && routing == other.routing && meta == other.meta
)
end
end
alias_method :==, :eql?
def doc_header
{ _id: id }.tap do |h|
h[:_type] = type if type
h[:routing] = routing if routing?
end
end
def document_for_partial_update(source)
DocumentForPartialUpdate.new(self, source: source)
end
def inspect
attributes = {id: :id, routing: :routing, source: :memoized_source}.map do |attr_name, attr_src|
value = send(attr_src)
next unless value
"#{attr_name}: #{value.inspect}"
rescue
nil
end.compact.join(', ')
attributes << " mutations: #{@__mutations__.inspect}" if @__mutations__
"#<#{self.class.name || 'Esse::Document'} #{attributes}>"
end
def mutate(key)
@__mutations__ ||= {}
@__mutations__[key] = yield
instance_variable_set(:@__mutated_source__, nil)
end
def mutations
@__mutations__ || MUTATIONS_FALLBACK
end
def mutated_source
return memoized_source unless @__mutations__
@__mutated_source__ ||= memoized_source.merge(@__mutations__)
end
protected
def memoized_source
return @__memoized_source__ if defined?(@__memoized_source__)
@__memoized_source__ = source || {}
end
end
end