isomorfeus-data 2.4.2 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -4
- data/lib/isomorfeus/data/config.rb +0 -8
- data/lib/isomorfeus/data/field_support.rb +108 -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 +10 -29
- 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: 69be34181734a815ae1468128e569eee76b41d4022217f21042e0b96a63acbd2
|
4
|
+
data.tar.gz: 351403a3931b8a69c44612d52a5f322813ad0e57f9b14383ec4e255b6d3742a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb1f8eed6401abdbc008c6616b21d77e77d91dff6fe53ac19cecea03a313c260fc3aa6fe042aa3d98c46c030adc426eacd76a042730fe562dde5a775e870ee3e
|
7
|
+
data.tar.gz: 1b7fefa06146fd81b733fd4ecf8c04ab4385bab3669875fc9cd0fad2fe1fe170b75db70202d305d344b8bfee02f9741ba9aa68aae96cb5e6629833e6032ed350
|
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,77 @@ 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
|
+
|
44
|
+
def object(name, options = {})
|
45
|
+
default_options = { is_a: LucidObject::Mixin, allow_nil: true }
|
46
|
+
field(name, :object, default_options.merge(options))
|
47
|
+
end
|
48
|
+
|
49
|
+
def field?(field_name)
|
50
|
+
field_options.key?(field_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_field?(field_name)
|
54
|
+
field_types[field_name] == :text_field
|
55
|
+
end
|
56
|
+
|
57
|
+
def attribute?(attr_name)
|
58
|
+
field_types[attr_name] == :attribute
|
59
|
+
end
|
60
|
+
|
61
|
+
def object?(obj_name)
|
62
|
+
field_types[obj_name] == :object
|
63
|
+
end
|
64
|
+
|
14
65
|
def valid_field?(field_name, val)
|
15
|
-
Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validate!
|
66
|
+
return Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validate! if field?(field_name)
|
67
|
+
false
|
68
|
+
rescue
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
def valid_text_field?(field_name, val)
|
73
|
+
return valid_field?(field_name, val) if text_field?(field_name)
|
74
|
+
false
|
75
|
+
rescue
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
def valid_attribute?(attr_name, val)
|
80
|
+
return valid_field?(attr_name, val) if attribute?(attr_name)
|
81
|
+
false
|
82
|
+
rescue
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
def valid_object?(obj_name, val)
|
87
|
+
return valid_field?(obj_name, val) if object?(obj_name)
|
88
|
+
false
|
89
|
+
rescue
|
90
|
+
false
|
16
91
|
end
|
17
92
|
|
18
93
|
def validate
|
@@ -20,14 +95,14 @@ module Isomorfeus
|
|
20
95
|
end
|
21
96
|
|
22
97
|
def _validate_field(field_name, val)
|
23
|
-
Isomorfeus.raise_error(message: "#{self.name}: No such
|
98
|
+
Isomorfeus.raise_error(message: "#{self.name}: No such text_field, attribute or object declared: '#{field_name}'!") unless field_conditions.key?(field_name)
|
24
99
|
Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validated_value
|
25
100
|
end
|
26
101
|
|
27
102
|
def _validate_fields(fields)
|
28
103
|
field_conditions.each_key do |field_name|
|
29
104
|
if field_conditions[field_name].key?(:required) && field_conditions[field_name][:required] && !fields.key?(field_name)
|
30
|
-
Isomorfeus.raise_error(message: "Required
|
105
|
+
Isomorfeus.raise_error(message: "Required #{field_types[field_name]} #{field_name} not given!")
|
31
106
|
end
|
32
107
|
fields[field_name] = _validate_field(field_name, fields[field_name])
|
33
108
|
end
|
@@ -42,28 +117,19 @@ module Isomorfeus
|
|
42
117
|
self.class._validate_fields(fields)
|
43
118
|
end
|
44
119
|
|
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
120
|
if RUBY_ENGINE == 'opal'
|
54
121
|
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
|
122
|
+
def field(name, type, options)
|
123
|
+
_register_field(name, type, options)
|
64
124
|
|
65
|
-
|
66
|
-
|
125
|
+
if type == :object
|
126
|
+
define_method(name) do
|
127
|
+
_get_object(name)
|
128
|
+
end
|
129
|
+
else
|
130
|
+
define_method(name) do
|
131
|
+
_get_field(name)
|
132
|
+
end
|
67
133
|
end
|
68
134
|
|
69
135
|
define_method("#{name}=") do |val|
|
@@ -109,6 +175,15 @@ module Isomorfeus
|
|
109
175
|
}
|
110
176
|
end
|
111
177
|
|
178
|
+
def _get_object(name)
|
179
|
+
return @_changed_fields[name] if @_changed_fields.key?(name)
|
180
|
+
return @_objects[name] if @_objects.key?(name)
|
181
|
+
path = @_store_path + [name]
|
182
|
+
sid_or_array = Redux.fetch_by_path(*path)
|
183
|
+
return nil if `(sid_or_array === null)`
|
184
|
+
@_objects[name] = Isomorfeus.instance_from_sid(sid_or_array) if sid_or_array
|
185
|
+
end
|
186
|
+
|
112
187
|
def fields
|
113
188
|
raw_fields = Redux.fetch_by_path(*@_store_path)
|
114
189
|
hash = Hash.new(raw_fields)
|
@@ -118,29 +193,15 @@ module Isomorfeus
|
|
118
193
|
|
119
194
|
def _get_selected_fields
|
120
195
|
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) }
|
196
|
+
self.class.field_types.each do |field, type|
|
197
|
+
sel_fields[field] = sel_fields[field]&.sid if type == :object
|
130
198
|
end
|
131
199
|
sel_fields
|
132
200
|
end
|
133
201
|
else
|
134
202
|
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
|
203
|
+
def field(name, type, options)
|
204
|
+
_register_field(name, type, options)
|
144
205
|
|
145
206
|
define_method(name) do
|
146
207
|
@_raw_fields[name]
|
@@ -160,16 +221,15 @@ module Isomorfeus
|
|
160
221
|
|
161
222
|
def _get_selected_fields
|
162
223
|
sel_fields = fields.transform_keys(&:to_s)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
224
|
+
ft = self.class.field_types
|
225
|
+
self.class.field_conditions.each do |field, options|
|
226
|
+
field_s = field.to_s
|
227
|
+
if options[:server_only]
|
228
|
+
sel_fields.delete(field_s)
|
229
|
+
elsif ft[field] == :object
|
230
|
+
sel_fields[field_s] = sel_fields[field_s]&.sid
|
168
231
|
end
|
169
232
|
end
|
170
|
-
if @_excluded_fields && !@_excluded_fields.empty?
|
171
|
-
@_excluded_fields.each { |fld| sel_fields.delete(fld.to_s) }
|
172
|
-
end
|
173
233
|
sel_fields
|
174
234
|
end
|
175
235
|
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
|
+
raise "object not created yet" 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'
|