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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a5f86620e77e947cb68b49795d40a7d696bd7b6e7f50812f5ec7028728f447d
4
- data.tar.gz: 02bb60ee8785e484be3dc1d73191d2a61012f2d6d7bc13cafdb7542c6ba8a330
3
+ metadata.gz: 69be34181734a815ae1468128e569eee76b41d4022217f21042e0b96a63acbd2
4
+ data.tar.gz: 351403a3931b8a69c44612d52a5f322813ad0e57f9b14383ec4e255b6d3742a9
5
5
  SHA512:
6
- metadata.gz: 28cd6b56d6134ac8d68215221e9423a745c2e8971d310bdc5e3a2660bebc55b0c05f6c064529b2863cc0e303620300d48370fc18437587af492ddfba692d19c6
7
- data.tar.gz: 624fbc993b3f2c8e185f754c1f2dfd737fd2820603d0bac6510305834d9f0b15d4d6e178f06c88d9c04f4e0adc1c8917fb10dc7e004bbc03851047d0ca2ed6c0
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
- - [LucidDocument](docs/data_document.md) - for textual data with fields
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 documents
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 field declared: '#{field_name}'!") unless field_conditions.key?(field_name)
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 field #{field_name} not given!")
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
- field_options[name] = {}
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
- define_method(name) do
66
- _get_field(name)
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
- if @_selected_fields && !@_selected_fields.empty?
122
- sel_fields.each_key do |fld|
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
- field_options[name] = {}
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
- if @_selected_fields && !@_selected_fields.empty?
164
- sel_fields.each_key do |fld|
165
- unless @_selected_fields.include?(fld.to_sym) || @_selected_fields.include?(fld)
166
- sel_fields.delete(fld)
167
- end
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 = instance_exec(key: key, &@_load_block)
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
- instance = instance_exec(&self.class.instance_variable_get(:@_create_block))
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
- instance = instance_exec(&self.class.instance_variable_get(:@_save_block))
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
@@ -6,7 +6,6 @@ module Isomorfeus
6
6
  class Generic < LucidHandler::Base
7
7
  # responsible for loading:
8
8
  # LucidObject
9
- # LucidDocument
10
9
  # LucidFile
11
10
  # LucidQuery
12
11
 
@@ -1,75 +1,140 @@
1
1
  module Isomorfeus
2
2
  module Data
3
3
  class ObjectAccelerator
4
- def self.finalize(ham_acc)
5
- proc { ham_acc.close_index }
4
+ def self.finalize(acc)
5
+ proc { acc.close_store }
6
6
  end
7
7
 
8
- attr_accessor :index
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 destroy_index
22
- close_index
23
- FileUtils.rm_rf(@index_path)
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 close_index
27
- @index.close
30
+ def serialize(obj)
31
+ Oj.dump(obj, mode: :object, circular: true, class_cache: @class_cache)
28
32
  end
29
33
 
30
- def create_doc(document)
31
- @index.add_document(document)
34
+ def unserialize(v)
35
+ Oj.load(v, mode: :object, circular: true, class_cache: @class_cache)
32
36
  end
33
37
 
34
- def destroy_doc(key)
35
- id = get_doc_id(key)
36
- @index.delete(id) if id
37
- true
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 load_doc(key)
41
- id = get_doc_id(key)
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 save_doc(key, document)
46
- id = get_doc_id(key)
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
- @index.update(id, document)
49
- true
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 search_each(query, options, &block)
54
- @index.search_each(query, options, &block)
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 get_doc_id(key)
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 = @index.search("sid_s_attr:\"#{escaped_key}\"", limit: 1)
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 open_index
67
- FileUtils.mkdir_p(@index_path) unless Dir.exist?(@index_path)
68
- @index = Isomorfeus::Ferret::Index::Index.new(path: @index_path, key: :sid_s_attr, auto_flush: true, lock_retry_time: 5)
69
- @index.field_infos.add_field(:attribute, store: :no, term_vector: :no) unless @index.field_infos[:attribute]
70
- @index.field_infos.add_field(:class_name, store: :no, term_vector: :no) unless @index.field_infos[:class_name]
71
- @index.field_infos.add_field(:value, store: :no) unless @index.field_infos[:value]
72
- @index.field_infos.add_field(:sid_s_attr, store: :yes, term_vector: :no) unless @index.field_infos[:sid_s_attr]
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
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Data
3
- VERSION = '2.4.2'
3
+ VERSION = '2.5.0'
4
4
  end
5
5
  end
@@ -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'