isomorfeus-data 2.4.2 → 2.5.0
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 +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'
|