isomorfeus-data 2.4.2 → 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -4
- data/lib/isomorfeus/data/config.rb +0 -8
- data/lib/isomorfeus/data/field_support.rb +110 -48
- data/lib/isomorfeus/data/generic_class_api.rb +10 -2
- data/lib/isomorfeus/data/generic_instance_api.rb +18 -4
- data/lib/isomorfeus/data/handler/generic.rb +0 -1
- data/lib/isomorfeus/data/object_accelerator.rb +105 -40
- data/lib/isomorfeus/data/version.rb +1 -1
- data/lib/isomorfeus-data.rb +0 -7
- data/lib/isomorfeus_data/lucid_object/mixin.rb +108 -146
- metadata +12 -31
- data/lib/isomorfeus/data/attribute_support.rb +0 -174
- data/lib/isomorfeus/data/document_accelerator.rb +0 -84
- data/lib/isomorfeus/data/object_expander.rb +0 -79
- data/lib/isomorfeus_data/lucid_document/base.rb +0 -10
- data/lib/isomorfeus_data/lucid_document/mixin.rb +0 -197
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 683f95014508aca48f80ba7230ca3b7904886e8482852714ce6eed75bb418170
|
4
|
+
data.tar.gz: 6d3106fd68c818818022b8bff174a51fcaf7d1b9ce7606f208e0325b555823ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30764ed57ee8a5b255ee02b596f9e3617c1e53d75300973c3494fe62e880977ed3c04eaf49b42cccf50b47ba4a4b8b4f0b9877f74761d121fddb03291bdb3442
|
7
|
+
data.tar.gz: 2dd0444993981ba0e9eafba0933496fd95b68f01d4e420443ec5591c87e1e08d764635614e0ba87a6a3c671687eacd94d9bb0ffa522b80f18ea6e8056eb51253
|
data/README.md
CHANGED
@@ -23,8 +23,7 @@ Graphs can easily be implemented with objects.
|
|
23
23
|
|
24
24
|
All classes follow the common principles and the common API above.
|
25
25
|
|
26
|
-
- [
|
27
|
-
- [LucidObject](docs/data_object.md) - for objects with attributes
|
26
|
+
- [LucidObject](docs/data_object.md) - for objects with text_fields or attributes
|
28
27
|
- [LucidFile](docs/data_file.md) - for files like images, pdfs, etc.
|
29
28
|
- [LucidQuery](docs/data_query.md) - for isomorphic queries.
|
30
29
|
|
@@ -32,7 +31,6 @@ All classes follow the common principles and the common API above.
|
|
32
31
|
|
33
32
|
isomorfeus-data relies on:
|
34
33
|
|
35
|
-
- [isomorfeus-ferret](https://github.com/isomorfeus/isomorfeus-ferret) as storage and index for
|
36
|
-
- [isomorfeus-hamster](https://github.com/isomorfeus/isomorfeus-hamster) as storage and index for objects
|
34
|
+
- [isomorfeus-ferret](https://github.com/isomorfeus/isomorfeus-ferret) as storage and index for objects
|
37
35
|
- the Filesystem for files
|
38
36
|
- [Oj](https://github.com/ohler55/oj) for serialization
|
@@ -62,8 +62,6 @@ module Isomorfeus
|
|
62
62
|
attr_accessor :ferret_path
|
63
63
|
attr_accessor :data_documents_path
|
64
64
|
|
65
|
-
attr_accessor :hamster_path
|
66
|
-
attr_accessor :hamster_mapsize
|
67
65
|
attr_accessor :data_object_envs_path
|
68
66
|
attr_accessor :data_object_idxs_path
|
69
67
|
end
|
@@ -76,11 +74,5 @@ module Isomorfeus
|
|
76
74
|
# documents and indices
|
77
75
|
self.ferret_path = File.expand_path(File.join(self.storage_path, 'ferret'))
|
78
76
|
self.data_documents_path = File.expand_path(File.join(self.ferret_path, 'documents'))
|
79
|
-
|
80
|
-
# objects, nodes and edges
|
81
|
-
self.hamster_path = File.expand_path(File.join(self.storage_path, 'hamster'))
|
82
|
-
self.hamster_mapsize = 4_294_967_296
|
83
|
-
self.data_object_envs_path = File.expand_path(File.join(self.hamster_path, 'object_envs'))
|
84
|
-
self.data_object_idxs_path = File.expand_path(File.join(self.hamster_path, 'object_idxs'))
|
85
77
|
end
|
86
78
|
end
|
@@ -3,7 +3,13 @@ module Isomorfeus
|
|
3
3
|
module FieldSupport
|
4
4
|
def self.included(base)
|
5
5
|
base.instance_exec do
|
6
|
+
def field_types
|
7
|
+
# determines how the item is stored in the index
|
8
|
+
@field_types ||= {}
|
9
|
+
end
|
10
|
+
|
6
11
|
def field_options
|
12
|
+
# options for the index
|
7
13
|
@field_options ||= {}
|
8
14
|
end
|
9
15
|
|
@@ -11,8 +17,79 @@ module Isomorfeus
|
|
11
17
|
@field_conditions ||= {}
|
12
18
|
end
|
13
19
|
|
20
|
+
def _register_field(name, type, options)
|
21
|
+
field_options[name] = {}
|
22
|
+
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:default_boost)
|
23
|
+
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:boost)
|
24
|
+
field_options[name][:index] = options.delete(:index) { :no }
|
25
|
+
field_options[name][:store] = options.delete(:store) if options.key?(:store)
|
26
|
+
field_options[name][:compress] = options.delete(:compress) if options.key?(:compress)
|
27
|
+
if field_options[name][:index] == :yes
|
28
|
+
field_options[name][:term_vector] = options.delete(:term_vector) { type == :text_field ? :with_positions_offsets : :no }
|
29
|
+
elsif field_options[name][:index] == :no
|
30
|
+
field_options[name][:term_vector] = :no
|
31
|
+
end
|
32
|
+
field_conditions[name] = options
|
33
|
+
field_types[name] = type
|
34
|
+
end
|
35
|
+
|
36
|
+
def text_field(name, options = {})
|
37
|
+
field(name, :text_field, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def attribute(name, options = {})
|
41
|
+
field(name, :attribute, options)
|
42
|
+
end
|
43
|
+
alias embed attribute
|
44
|
+
|
45
|
+
def object(name, options = {})
|
46
|
+
default_options = { is_a: LucidObject::Mixin, allow_nil: true }
|
47
|
+
field(name, :object, default_options.merge(options))
|
48
|
+
end
|
49
|
+
alias reference object
|
50
|
+
|
51
|
+
def field?(field_name)
|
52
|
+
field_options.key?(field_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def text_field?(field_name)
|
56
|
+
field_types[field_name] == :text_field
|
57
|
+
end
|
58
|
+
|
59
|
+
def attribute?(attr_name)
|
60
|
+
field_types[attr_name] == :attribute
|
61
|
+
end
|
62
|
+
|
63
|
+
def object?(obj_name)
|
64
|
+
field_types[obj_name] == :object
|
65
|
+
end
|
66
|
+
|
14
67
|
def valid_field?(field_name, val)
|
15
|
-
Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validate!
|
68
|
+
return Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validate! if field?(field_name)
|
69
|
+
false
|
70
|
+
rescue
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def valid_text_field?(field_name, val)
|
75
|
+
return valid_field?(field_name, val) if text_field?(field_name)
|
76
|
+
false
|
77
|
+
rescue
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
def valid_attribute?(attr_name, val)
|
82
|
+
return valid_field?(attr_name, val) if attribute?(attr_name)
|
83
|
+
false
|
84
|
+
rescue
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
88
|
+
def valid_object?(obj_name, val)
|
89
|
+
return valid_field?(obj_name, val) if object?(obj_name)
|
90
|
+
false
|
91
|
+
rescue
|
92
|
+
false
|
16
93
|
end
|
17
94
|
|
18
95
|
def validate
|
@@ -20,14 +97,14 @@ module Isomorfeus
|
|
20
97
|
end
|
21
98
|
|
22
99
|
def _validate_field(field_name, val)
|
23
|
-
Isomorfeus.raise_error(message: "#{self.name}: No such
|
100
|
+
Isomorfeus.raise_error(message: "#{self.name}: No such text_field, attribute or object declared: '#{field_name}'!") unless field_conditions.key?(field_name)
|
24
101
|
Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validated_value
|
25
102
|
end
|
26
103
|
|
27
104
|
def _validate_fields(fields)
|
28
105
|
field_conditions.each_key do |field_name|
|
29
106
|
if field_conditions[field_name].key?(:required) && field_conditions[field_name][:required] && !fields.key?(field_name)
|
30
|
-
Isomorfeus.raise_error(message: "Required
|
107
|
+
Isomorfeus.raise_error(message: "Required #{field_types[field_name]} #{field_name} not given!")
|
31
108
|
end
|
32
109
|
fields[field_name] = _validate_field(field_name, fields[field_name])
|
33
110
|
end
|
@@ -42,28 +119,19 @@ module Isomorfeus
|
|
42
119
|
self.class._validate_fields(fields)
|
43
120
|
end
|
44
121
|
|
45
|
-
def exclude_fields(*flds)
|
46
|
-
@_excluded_fields = flds
|
47
|
-
end
|
48
|
-
|
49
|
-
def select_fields(*flds)
|
50
|
-
@_selected_fields = flds
|
51
|
-
end
|
52
|
-
|
53
122
|
if RUBY_ENGINE == 'opal'
|
54
123
|
base.instance_exec do
|
55
|
-
def field(name, options
|
56
|
-
|
57
|
-
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:default_boost)
|
58
|
-
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:boost)
|
59
|
-
field_options[name][:index] = options.delete(:index) if options.key?(:index)
|
60
|
-
field_options[name][:store] = options.delete(:store) if options.key?(:store)
|
61
|
-
field_options[name][:compress] = options.delete(:compress) if options.key?(:compress)
|
62
|
-
field_options[name][:term_vector] = options.delete(:term_vector) if options.key?(:term_vector)
|
63
|
-
field_conditions[name] = options
|
124
|
+
def field(name, type, options)
|
125
|
+
_register_field(name, type, options)
|
64
126
|
|
65
|
-
|
66
|
-
|
127
|
+
if type == :object
|
128
|
+
define_method(name) do
|
129
|
+
_get_object(name)
|
130
|
+
end
|
131
|
+
else
|
132
|
+
define_method(name) do
|
133
|
+
_get_field(name)
|
134
|
+
end
|
67
135
|
end
|
68
136
|
|
69
137
|
define_method("#{name}=") do |val|
|
@@ -109,6 +177,15 @@ module Isomorfeus
|
|
109
177
|
}
|
110
178
|
end
|
111
179
|
|
180
|
+
def _get_object(name)
|
181
|
+
return @_changed_fields[name] if @_changed_fields.key?(name)
|
182
|
+
return @_objects[name] if @_objects.key?(name)
|
183
|
+
path = @_store_path + [name]
|
184
|
+
sid_or_array = Redux.fetch_by_path(*path)
|
185
|
+
return nil if `(sid_or_array === null)`
|
186
|
+
@_objects[name] = Isomorfeus.instance_from_sid(sid_or_array) if sid_or_array
|
187
|
+
end
|
188
|
+
|
112
189
|
def fields
|
113
190
|
raw_fields = Redux.fetch_by_path(*@_store_path)
|
114
191
|
hash = Hash.new(raw_fields)
|
@@ -118,29 +195,15 @@ module Isomorfeus
|
|
118
195
|
|
119
196
|
def _get_selected_fields
|
120
197
|
sel_fields = fields.dup
|
121
|
-
|
122
|
-
sel_fields
|
123
|
-
unless @_selected_fields.include?(fld) || @_selected_fields.include?(fld)
|
124
|
-
sel_fields.delete(fld)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
if @_excluded_fields && !@_excluded_fields.empty?
|
129
|
-
@_excluded_fields.each { |fld| sel_fields.delete(fld) }
|
198
|
+
self.class.field_types.each do |field, type|
|
199
|
+
sel_fields[field] = sel_fields[field]&.sid if type == :object
|
130
200
|
end
|
131
201
|
sel_fields
|
132
202
|
end
|
133
203
|
else
|
134
204
|
base.instance_exec do
|
135
|
-
def field(name, options
|
136
|
-
|
137
|
-
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:default_boost)
|
138
|
-
field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:boost)
|
139
|
-
field_options[name][:index] = options.delete(:index) if options.key?(:index)
|
140
|
-
field_options[name][:store] = options.delete(:store) if options.key?(:store)
|
141
|
-
field_options[name][:compress] = options.delete(:compress) if options.key?(:compress)
|
142
|
-
field_options[name][:term_vector] = options.delete(:term_vector) if options.key?(:term_vector)
|
143
|
-
field_conditions[name] = options
|
205
|
+
def field(name, type, options)
|
206
|
+
_register_field(name, type, options)
|
144
207
|
|
145
208
|
define_method(name) do
|
146
209
|
@_raw_fields[name]
|
@@ -160,16 +223,15 @@ module Isomorfeus
|
|
160
223
|
|
161
224
|
def _get_selected_fields
|
162
225
|
sel_fields = fields.transform_keys(&:to_s)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
226
|
+
ft = self.class.field_types
|
227
|
+
self.class.field_conditions.each do |field, options|
|
228
|
+
field_s = field.to_s
|
229
|
+
if options[:server_only]
|
230
|
+
sel_fields.delete(field_s)
|
231
|
+
elsif ft[field] == :object
|
232
|
+
sel_fields[field_s] = sel_fields[field_s]&.sid
|
168
233
|
end
|
169
234
|
end
|
170
|
-
if @_excluded_fields && !@_excluded_fields.empty?
|
171
|
-
@_excluded_fields.each { |fld| sel_fields.delete(fld.to_s) }
|
172
|
-
end
|
173
235
|
sel_fields
|
174
236
|
end
|
175
237
|
end
|
@@ -62,8 +62,12 @@ module Isomorfeus
|
|
62
62
|
Promise.new.resolve(destroy(key: key))
|
63
63
|
end
|
64
64
|
|
65
|
-
def load(key:)
|
66
|
-
data =
|
65
|
+
def load(key:, _already_loaded: {})
|
66
|
+
data = if @_load_block.arity == 1
|
67
|
+
instance_exec(key: key, &@_load_block)
|
68
|
+
else
|
69
|
+
instance_exec(key: key, _already_loaded: _already_loaded, &@_load_block)
|
70
|
+
end
|
67
71
|
return nil if data.nil?
|
68
72
|
return data if data.class.to_s == self.to_s
|
69
73
|
Isomorfeus.raise_error(message: "#{self}: execute_load must return a instance of #{self} or nil. Returned was: #{data.class}.")
|
@@ -95,6 +99,10 @@ module Isomorfeus
|
|
95
99
|
end
|
96
100
|
end # RUBY_ENGINE
|
97
101
|
|
102
|
+
def gen_ref_s(key)
|
103
|
+
"---iso-object-reference---#{self.name}---#{key}---"
|
104
|
+
end
|
105
|
+
|
98
106
|
def gen_sid_s(key)
|
99
107
|
"[#{self.name}|#{key}]"
|
100
108
|
end
|
@@ -25,6 +25,10 @@ module Isomorfeus
|
|
25
25
|
"[#{@class_name}|#{@key}]"
|
26
26
|
end
|
27
27
|
|
28
|
+
def ref_s
|
29
|
+
self.class.gen_ref_s(@key)
|
30
|
+
end
|
31
|
+
|
28
32
|
if RUBY_ENGINE == 'opal'
|
29
33
|
def loaded?
|
30
34
|
Redux.fetch_by_path(*@_store_path) ? true : false
|
@@ -100,9 +104,14 @@ module Isomorfeus
|
|
100
104
|
true
|
101
105
|
end
|
102
106
|
|
103
|
-
def create
|
107
|
+
def create(_already_saved: {})
|
104
108
|
previous_key = self.key
|
105
|
-
|
109
|
+
create_block = self.class.instance_variable_get(:@_create_block)
|
110
|
+
instance = if create_block.arity == 0
|
111
|
+
instance_exec(&create_block)
|
112
|
+
else
|
113
|
+
instance_exec(_already_saved: _already_saved, &create_block)
|
114
|
+
end
|
106
115
|
return nil unless instance
|
107
116
|
Isomorfeus.raise_error(message: "#{self.to_s}: execute_create must return self or nil. Returned was: #{instance.class}.") if instance != self
|
108
117
|
instance_variable_set(:@previous_key, previous_key) if key != previous_key
|
@@ -129,9 +138,14 @@ module Isomorfeus
|
|
129
138
|
Promise.new.resolve(reload)
|
130
139
|
end
|
131
140
|
|
132
|
-
def save
|
141
|
+
def save(_already_saved: {})
|
133
142
|
previous_key = self.key
|
134
|
-
|
143
|
+
save_block = self.class.instance_variable_get(:@_save_block)
|
144
|
+
instance = if save_block.arity == 0
|
145
|
+
instance_exec(&save_block)
|
146
|
+
else
|
147
|
+
instance_exec(_already_saved: _already_saved, &save_block)
|
148
|
+
end
|
135
149
|
return nil unless instance
|
136
150
|
Isomorfeus.raise_error(message: "#{self.to_s}: execute_save must return self or nil. Returned was: #{instance.class}.") if instance != self
|
137
151
|
instance_variable_set(:@previous_key, previous_key) if key != previous_key
|
@@ -1,75 +1,140 @@
|
|
1
1
|
module Isomorfeus
|
2
2
|
module Data
|
3
3
|
class ObjectAccelerator
|
4
|
-
def self.finalize(
|
5
|
-
proc {
|
4
|
+
def self.finalize(acc)
|
5
|
+
proc { acc.close_store }
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
attr_reader :object_class, :object_class_name
|
9
|
+
attr_accessor :store
|
10
|
+
|
11
|
+
def initialize(ruby_class)
|
12
|
+
@object_class = ruby_class
|
13
|
+
@object_class_name = ruby_class.name
|
14
|
+
@class_cache = Isomorfeus.production?
|
15
|
+
|
16
|
+
@store_path = File.expand_path(File.join(Isomorfeus.data_documents_path, "#{@object_class_name.underscore}"))
|
17
|
+
open_store
|
9
18
|
|
10
|
-
def initialize(object_class_name, &block)
|
11
|
-
if block_given?
|
12
|
-
res = block.call(self)
|
13
|
-
@index = res unless @index
|
14
|
-
else
|
15
|
-
@index_path = File.expand_path(File.join(Isomorfeus.data_object_idxs_path, object_class_name.underscore))
|
16
|
-
open_index
|
17
|
-
end
|
18
19
|
ObjectSpace.define_finalizer(self, self.class.finalize(self))
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
22
|
+
def object_from_ref(ref, already_loaded)
|
23
|
+
_, iso, type_class_name, key = ref.split('---')
|
24
|
+
raise "not a valid object reference '#{ref}'" unless iso == "iso-object-reference"
|
25
|
+
raise "invalid data class #{type_class_name}" unless Isomorfeus.valid_data_class_name?(type_class_name)
|
26
|
+
type_class = Isomorfeus.cached_data_class(type_class_name)
|
27
|
+
type_class.load(key: key, _already_loaded: already_loaded)
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
27
|
-
@
|
30
|
+
def serialize(obj)
|
31
|
+
Oj.dump(obj, mode: :object, circular: true, class_cache: @class_cache)
|
28
32
|
end
|
29
33
|
|
30
|
-
def
|
31
|
-
|
34
|
+
def unserialize(v)
|
35
|
+
Oj.load(v, mode: :object, circular: true, class_cache: @class_cache)
|
32
36
|
end
|
33
37
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
def destroy_store
|
39
|
+
close_store
|
40
|
+
FileUtils.rm_rf(@store_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def close_store
|
44
|
+
@store.close
|
38
45
|
end
|
39
46
|
|
40
|
-
def
|
41
|
-
|
42
|
-
@index.doc(id)&.load&.to_h if id
|
47
|
+
def search_each(query, options, &block)
|
48
|
+
@store.search_each(query, options, &block)
|
43
49
|
end
|
44
50
|
|
45
|
-
def
|
46
|
-
|
51
|
+
def each(&block)
|
52
|
+
ft = @object_class.field_types
|
53
|
+
@store.each do |doc|
|
54
|
+
hash = doc.to_h do |k, v|
|
55
|
+
[k, unserialize_or_load(v, ft[k], {})]
|
56
|
+
end
|
57
|
+
block.call hash
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_object(key, fields, already_saved)
|
62
|
+
ft = @object_class.field_types
|
63
|
+
hash = fields.to_h do |k, v|
|
64
|
+
[k, serialize_or_save(v, ft[k], already_saved)]
|
65
|
+
end
|
66
|
+
@store.add_document(hash.merge!({key: key}))
|
67
|
+
end
|
68
|
+
|
69
|
+
def destroy_object(key)
|
70
|
+
id = get_object_id(key)
|
71
|
+
@store.delete(id) if id
|
72
|
+
end
|
73
|
+
|
74
|
+
def load_object(key: nil, id: nil, already_loaded: {})
|
75
|
+
hash = nil
|
76
|
+
id = get_object_id(key) if key
|
47
77
|
if id
|
48
|
-
@
|
49
|
-
|
78
|
+
ft = @object_class.field_types
|
79
|
+
hash = @store.doc(id)&.to_h do |k, v|
|
80
|
+
[k, unserialize_or_load(v, ft[k], already_loaded)]
|
81
|
+
end
|
50
82
|
end
|
83
|
+
hash
|
51
84
|
end
|
52
85
|
|
53
|
-
def
|
54
|
-
|
86
|
+
def save_object(key, fields, already_saved)
|
87
|
+
id = get_object_id(key)
|
88
|
+
return create_object(key, fields, already_saved) unless id
|
89
|
+
ft = @object_class.field_types
|
90
|
+
hash = fields.to_h do |k, v|
|
91
|
+
[k, serialize_or_save(v, ft[k], already_saved)]
|
92
|
+
end
|
93
|
+
@store.update(id, hash.merge!({key: key}))
|
94
|
+
true
|
55
95
|
end
|
56
96
|
|
57
97
|
private
|
58
98
|
|
59
|
-
def
|
99
|
+
def unserialize_or_load(v, t, already_loaded)
|
100
|
+
return unserialize(v) if t == :attribute
|
101
|
+
if t == :object && v
|
102
|
+
return nil if v.empty?
|
103
|
+
return object_from_ref(v, already_loaded)
|
104
|
+
end
|
105
|
+
v
|
106
|
+
end
|
107
|
+
|
108
|
+
def serialize_or_save(v, t, already_saved)
|
109
|
+
return serialize(v) if t == :attribute
|
110
|
+
return create_or_save(v, already_saved) if t == :object && v
|
111
|
+
v
|
112
|
+
end
|
113
|
+
|
114
|
+
def create_or_save(v, already_saved)
|
115
|
+
if get_object_id(v.key)
|
116
|
+
v.save(_already_saved: already_saved)
|
117
|
+
else
|
118
|
+
v.create
|
119
|
+
end
|
120
|
+
v.ref_s
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_object_id(key)
|
60
124
|
# special characters must be escaped, characters taken from the ferret query parser documentation
|
61
125
|
escaped_key = key.gsub(/([\\\&\:\(\)\[\]\{\}\!\"\~\^\|\<\>\=\*\?\+\-\s])/, '\\\\\1')
|
62
|
-
top_docs = @
|
126
|
+
top_docs = @store.search("key:\"#{escaped_key}\"", limit: 1)
|
63
127
|
id = top_docs.hits[0].doc if top_docs.total_hits == 1
|
64
128
|
end
|
65
129
|
|
66
|
-
def
|
67
|
-
FileUtils.mkdir_p(
|
68
|
-
|
69
|
-
@
|
70
|
-
@
|
71
|
-
@
|
72
|
-
|
130
|
+
def open_store
|
131
|
+
FileUtils.mkdir_p(Isomorfeus.data_documents_path) unless Dir.exist?(Isomorfeus.data_documents_path)
|
132
|
+
field_infos = Isomorfeus::Ferret::Index::FieldInfos.new(store: :yes, index: :yes, term_vector: :no)
|
133
|
+
@store = Isomorfeus::Ferret::Index::Index.new(path: @store_path, key: :key, auto_flush: true, lock_retry_time: 5, field_infos: field_infos)
|
134
|
+
@store.field_infos.add_field(:key, store: :yes, index: :yes, term_vector: :yes) unless @store.field_infos[:key]
|
135
|
+
@object_class.field_options.each do |field, options|
|
136
|
+
@store.field_infos.add_field(field, options) unless @store.field_infos[field]
|
137
|
+
end
|
73
138
|
end
|
74
139
|
end
|
75
140
|
end
|
data/lib/isomorfeus-data.rb
CHANGED
@@ -9,7 +9,6 @@ require 'isomorfeus-policy'
|
|
9
9
|
require 'isomorfeus-transport'
|
10
10
|
require 'isomorfeus-i18n'
|
11
11
|
require 'isomorfeus/data/config'
|
12
|
-
require 'isomorfeus/data/attribute_support'
|
13
12
|
require 'isomorfeus/data/field_support'
|
14
13
|
require 'isomorfeus/data/generic_class_api'
|
15
14
|
require 'isomorfeus/data/generic_instance_api'
|
@@ -28,17 +27,11 @@ else
|
|
28
27
|
require 'active_support/core_ext/hash'
|
29
28
|
|
30
29
|
require 'isomorfeus-ferret'
|
31
|
-
require 'isomorfeus/data/document_accelerator'
|
32
|
-
|
33
|
-
require 'isomorfeus-hamster'
|
34
|
-
require 'isomorfeus/data/object_expander'
|
35
30
|
require 'isomorfeus/data/object_accelerator'
|
36
31
|
|
37
32
|
require 'isomorfeus_data/lucid_query_result'
|
38
33
|
require 'isomorfeus_data/lucid_object/mixin'
|
39
34
|
require 'isomorfeus_data/lucid_object/base'
|
40
|
-
require 'isomorfeus_data/lucid_document/mixin'
|
41
|
-
require 'isomorfeus_data/lucid_document/base'
|
42
35
|
require 'isomorfeus_data/lucid_query/mixin'
|
43
36
|
require 'isomorfeus_data/lucid_query/base'
|
44
37
|
require 'isomorfeus_data/lucid_file/mixin'
|