isomorfeus-data 2.0.5 → 2.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 455e8b083641020d3d3dfa97b34d4144087fb19c11f551c240cdf4e946f60df0
4
- data.tar.gz: 20f440fa635643a147bbcfb2571b9bcb0afcef57e57977de08725ac7cf732870
3
+ metadata.gz: 03adcad549502d3b374fa200b4c1a90b4a1963288a40e619a170ffb5190ec870
4
+ data.tar.gz: 000c496d28015877c52c84934d100827dea59740cda0f78b1b6f8b6c9eea5979
5
5
  SHA512:
6
- metadata.gz: 46f6c764a5d12fe8b46730ee1cc1b18d8a99a52c56fff668143abcd30a4961b55813f9bbc8840c7ca80a8bf365b8faa3f3a06a6a0d0fc802dc2f4037f2a6a406
7
- data.tar.gz: e34bd37b4b16359a2cf14a863fefd327cac00568f9048c1466c6061cc922072046bca750fcd36be150fac6e7876c96671d7d5f71c4b3715610e773b37f910cc6
6
+ metadata.gz: bdd85f149ef46ba89524c23045fa68cc5662786dcb16f07c9a8405e567edac87e4c87f679d1286164f0e1fee62e5b76b6299506c26f9a0ad25620a43d8632c24
7
+ data.tar.gz: 5bcac6b623211981f5d4e5adc83ef63257d022301cad48582bd7cecd43ecbd46054622ed133c3f7f158868823a36b8e5bbfcf488a6eab7fbbf7bf1553225f268
data/lib/data_uri/uri.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module URI
2
2
  class Data < Generic
3
- COMPONENT = [:scheme, :opaque].freeze
4
- MIME_TYPE_RE = %r{^([-\w.+]+/[-\w.+]*)}.freeze
5
- MIME_PARAM_RE = /^;([-\w.+]+)=([^;,]+)/.freeze
3
+ COMPONENT = [:scheme, :opaque]
4
+ MIME_TYPE_RE = %r{^([-\w.+]+/[-\w.+]*)}
5
+ MIME_PARAM_RE = /^;([-\w.+]+)=([^;,]+)/
6
6
 
7
7
  attr_reader :content_type, :data
8
8
 
data/lib/data_uri.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'uri'
2
2
  require 'base64'
3
3
  require 'stringio'
4
-
5
4
  require 'data_uri/uri'
@@ -11,8 +11,8 @@ module Isomorfeus
11
11
  @indexed_attributes ||= {}
12
12
  end
13
13
 
14
- def valid_attribute?(attr_name, attr_value)
15
- Isomorfeus::Props::Validator.new(self.name, attr_name, attr_value, attribute_conditions[attr_name]).validate!
14
+ def valid_attribute?(attr_name, val)
15
+ Isomorfeus::Props::Validator.new(self.name, attr_name, val, attribute_conditions[attr_name]).validate!
16
16
  rescue
17
17
  false
18
18
  end
@@ -21,23 +21,23 @@ module Isomorfeus
21
21
  Isomorfeus::Props::ValidateHashProxy.new
22
22
  end
23
23
 
24
- def _validate_attribute(attr_name, attr_val)
24
+ def _validate_attribute(attr_name, val)
25
25
  Isomorfeus.raise_error(message: "#{self.name}: No such attribute declared: '#{attr_name}'!") unless attribute_conditions.key?(attr_name)
26
- Isomorfeus::Props::Validator.new(self.name, attr_name, attr_val, attribute_conditions[attr_name]).validate!
26
+ Isomorfeus::Props::Validator.new(self.name, attr_name, val, attribute_conditions[attr_name]).validated_value
27
27
  end
28
28
 
29
29
  def _validate_attributes(attrs)
30
- attribute_conditions.each_key do |attr|
31
- if attribute_conditions[attr].key?(:required) && attribute_conditions[attr][:required] && !attrs.key?(attr)
32
- Isomorfeus.raise_error(message: "Required attribute #{attr} not given!")
30
+ attribute_conditions.each_key do |attr_name|
31
+ if attribute_conditions[attr_name].key?(:required) && attribute_conditions[attr_name][:required] && !attrs.key?(attr_name)
32
+ Isomorfeus.raise_error(message: "Required attribute #{attr_name} not given!")
33
33
  end
34
+ attrs[attr_name] = _validate_attribute(attr_name, attrs[attr_name])
34
35
  end
35
- attrs.each { |attr, val| _validate_attribute(attr, val) }
36
36
  end
37
37
  end
38
38
 
39
- def _validate_attribute(attr_name, value)
40
- self.class._validate_attribute(attr_name, value)
39
+ def _validate_attribute(attr_name, val)
40
+ self.class._validate_attribute(attr_name, val)
41
41
  end
42
42
 
43
43
  def _validate_attributes(attrs)
@@ -55,8 +55,7 @@ module Isomorfeus
55
55
  if RUBY_ENGINE == 'opal'
56
56
  base.instance_exec do
57
57
  def attribute(name, options = {})
58
- indexed = options.delete(:index)
59
- indexed_attributes[name] = indexed if indexed
58
+ indexed_attributes[name] = options.delete(:index) if options.key?(:index)
60
59
  attribute_conditions[name] = options
61
60
 
62
61
  define_method(name) do
@@ -64,7 +63,7 @@ module Isomorfeus
64
63
  end
65
64
 
66
65
  define_method("#{name}=") do |val|
67
- _validate_attribute(name, val)
66
+ val = _validate_attribute(name, val)
68
67
  changed!
69
68
  @_changed_attributes[name] = val
70
69
  end
@@ -132,8 +131,7 @@ module Isomorfeus
132
131
  else
133
132
  base.instance_exec do
134
133
  def attribute(name, options = {})
135
- indexed = options.delete(:index)
136
- indexed_attributes[name] = indexed if indexed
134
+ indexed_attributes[name] = options.delete(:index) if options.key?(:index)
137
135
  attribute_conditions[name] = options
138
136
 
139
137
  define_method(name) do
@@ -141,7 +139,7 @@ module Isomorfeus
141
139
  end
142
140
 
143
141
  define_method("#{name}=") do |val|
144
- _validate_attribute(name, val)
142
+ val = _validate_attribute(name, val)
145
143
  changed!
146
144
  @_raw_attributes[name] = val
147
145
  end
@@ -34,17 +34,23 @@ module Isomorfeus
34
34
  @index.add_document(document)
35
35
  end
36
36
 
37
- def destroy_doc(id)
38
- @index.delete(id)
37
+ def destroy_doc(key)
38
+ id = get_doc_id(key)
39
+ @index.delete(id) if id
39
40
  true
40
41
  end
41
42
 
42
- def load_doc(id)
43
- @index.doc(id)&.load
43
+ def load_doc(key)
44
+ id = get_doc_id(key)
45
+ @index.doc(id)&.load&.to_h if id
44
46
  end
45
47
 
46
- def save_doc(id, document)
47
- @index.update(id, document)
48
+ def save_doc(key, document)
49
+ id = get_doc_id(key)
50
+ if id
51
+ @index.update(id, document)
52
+ true
53
+ end
48
54
  end
49
55
 
50
56
  def search_each(query, options, &block)
@@ -53,13 +59,25 @@ module Isomorfeus
53
59
 
54
60
  private
55
61
 
62
+ def get_doc_id(key)
63
+ # special characters must be escaped, characters taken from the ferret query parser documentation
64
+ escaped_key = key.gsub(/([\\\&\:\(\)\[\]\{\}\!\"\~\^\|\<\>\=\*\?\+\-\s])/, '\\\\\1')
65
+ top_docs = @index.search("key:\"#{escaped_key}\"", limit: 1)
66
+ id = top_docs.hits[0].doc if top_docs.total_hits == 1
67
+ end
68
+
56
69
  def index_path
57
70
  File.expand_path(File.join(Isomorfeus.data_documents_path, @doc_class_name_u))
58
71
  end
59
72
 
60
73
  def open_index
61
74
  FileUtils.mkdir_p(Isomorfeus.data_documents_path) unless Dir.exist?(Isomorfeus.data_documents_path)
62
- @index = Isomorfeus::Ferret::Index::Index.new(path: index_path, id_field: :key)
75
+ field_infos = Isomorfeus::Ferret::Index::FieldInfos.new(store: :yes, index: :yes, term_vector: :with_positions_offsets)
76
+ @index = Isomorfeus::Ferret::Index::Index.new(path: index_path, key: :key, auto_flush: true, lock_retry_time: 5)
77
+ @index.field_infos.add_field(:key, store: :yes, index: :yes, term_vector: :no) unless @index.field_infos[:key]
78
+ @doc_class.field_options.each do |field, options|
79
+ @index.field_infos.add_field(field, options) unless @index.field_infos[field]
80
+ end
63
81
  end
64
82
  end
65
83
  end
@@ -7,9 +7,39 @@ module Isomorfeus
7
7
  @field_options ||= {}
8
8
  end
9
9
 
10
- def valid_field?(field_name, field_value)
11
- field_options.key?(field_name)
10
+ def field_conditions
11
+ @field_conditions ||= {}
12
12
  end
13
+
14
+ def valid_field?(field_name, val)
15
+ Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validate!
16
+ end
17
+
18
+ def validate
19
+ Isomorfeus::Props::ValidateHashProxy.new
20
+ end
21
+
22
+ 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)
24
+ Isomorfeus::Props::Validator.new(self.name, field_name, val, field_conditions[field_name]).validated_value
25
+ end
26
+
27
+ def _validate_fields(fields)
28
+ field_conditions.each_key do |field_name|
29
+ 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!")
31
+ end
32
+ fields[field_name] = _validate_field(field_name, fields[field_name])
33
+ end
34
+ end
35
+ end
36
+
37
+ def _validate_field(field_name, val)
38
+ self.class._validate_field(field_name, val)
39
+ end
40
+
41
+ def _validate_fields(fields)
42
+ self.class._validate_fields(fields)
13
43
  end
14
44
 
15
45
  def exclude_fields(*flds)
@@ -22,21 +52,52 @@ module Isomorfeus
22
52
 
23
53
  if RUBY_ENGINE == 'opal'
24
54
  base.instance_exec do
25
- def field(name, options = nil)
26
- field_options[name] = options
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][:term_vector] = options.delete(:term_vector) if options.key?(:term_vector)
62
+ field_conditions[name] = options
27
63
 
28
64
  define_method(name) do
29
65
  _get_field(name)
30
66
  end
31
67
 
32
68
  define_method("#{name}=") do |val|
33
- val = val.to_s unless val.class == String
69
+ val = _validate_field(name, val)
34
70
  changed!
35
71
  @_changed_fields[name] = val
36
72
  end
37
73
  end
38
74
  end
39
75
 
76
+ def validate_fields_function
77
+ %x{
78
+ if (typeof self.validate_fields_function === 'undefined') {
79
+ self.validate_fields_function = function(fields_object) {
80
+ try { self.$_validate_fields(Opal.Hash.$new(fields_object)) }
81
+ catch (e) { return e.message; }
82
+ }
83
+ }
84
+ return self.validate_fields_function;
85
+ }
86
+ end
87
+
88
+ def validate_field_function(field_name)
89
+ function_name = "validate_field_#{field_name}_function"
90
+ %x{
91
+ if (typeof self[function_name] === 'undefined') {
92
+ self[function_name] = function(value) {
93
+ try { self.$_validate_field(field_name, value); }
94
+ catch (e) { return e.message; }
95
+ }
96
+ }
97
+ return self[function_name];
98
+ }
99
+ end
100
+
40
101
  def _get_field(name)
41
102
  return @_changed_fields[name] if @_changed_fields.key?(name)
42
103
  path = @_store_path + [name]
@@ -71,14 +132,20 @@ module Isomorfeus
71
132
  else
72
133
  base.instance_exec do
73
134
  def field(name, options = {})
74
- field_options[name] = options
135
+ field_options[name] = {}
136
+ field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:default_boost)
137
+ field_options[name][:default_boost] = options.delete(:default_boost) if options.key?(:boost)
138
+ field_options[name][:index] = options.delete(:index) if options.key?(:index)
139
+ field_options[name][:store] = options.delete(:store) if options.key?(:store)
140
+ field_options[name][:term_vector] = options.delete(:term_vector) if options.key?(:term_vector)
141
+ field_conditions[name] = options
75
142
 
76
143
  define_method(name) do
77
144
  @_raw_fields[name]
78
145
  end
79
146
 
80
147
  define_method("#{name}=") do |val|
81
- val = val.to_s unless val.class == String
148
+ val = _validate_field(name, val)
82
149
  changed!
83
150
  @_raw_fields[name] = val
84
151
  end
@@ -23,13 +23,13 @@ module Isomorfeus
23
23
  end
24
24
 
25
25
  def load(key:)
26
- instance = self.new(key: key)
26
+ instance = self.new(key: key, _loading: true)
27
27
  promise_load(key: key, instance: instance) unless instance.loaded?
28
28
  instance
29
29
  end
30
30
 
31
31
  def promise_load(key:, instance: nil)
32
- instance = self.new(key: key) unless instance
32
+ instance = self.new(key: key, _loading: true) unless instance
33
33
  if instance.loaded?
34
34
  Promise.new.resolve(instance)
35
35
  else
@@ -38,13 +38,13 @@ module Isomorfeus
38
38
  end
39
39
 
40
40
  def load!(key:)
41
- instance = self.new(key: key)
41
+ instance = self.new(key: key, _loading: true)
42
42
  promise_load!(key: key, instance: instance) unless instance.loaded?
43
43
  instance
44
44
  end
45
45
 
46
46
  def promise_load!(key:, instance: nil)
47
- instance = self.new(key: key) unless instance
47
+ instance = self.new(key: key, _loading: true) unless instance
48
48
  Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :load, key: key).then do |agent|
49
49
  if agent.processed
50
50
  agent.result
@@ -70,13 +70,9 @@ module Isomorfeus
70
70
  !!instance_exec(key: key, &@_destroy_block)
71
71
  end
72
72
 
73
- def promise_load(key:)
74
- instance = self.load(key: key)
75
- result_promise = Promise.new
76
- result_promise.resolve(instance)
77
- result_promise
73
+ def promise_destroy(key:)
74
+ Promise.new.resolve(destroy(key: key))
78
75
  end
79
- alias promise_load! promise_load
80
76
 
81
77
  def load(key:)
82
78
  data = instance_exec(key: key, &@_load_block)
@@ -86,6 +82,14 @@ module Isomorfeus
86
82
  end
87
83
  alias load! load
88
84
 
85
+ def promise_load(key:)
86
+ instance = self.load(key: key)
87
+ result_promise = Promise.new
88
+ result_promise.resolve(instance)
89
+ result_promise
90
+ end
91
+ alias promise_load! promise_load
92
+
89
93
  def execute_create(&block)
90
94
  @_create_block = block
91
95
  end
@@ -115,14 +119,6 @@ module Isomorfeus
115
119
  new(key: key, **things).promise_create
116
120
  end
117
121
 
118
- def save(instance:)
119
- instance.save
120
- end
121
-
122
- def promise_save(instance:)
123
- instance.promise_save
124
- end
125
-
126
122
  def current_user
127
123
  Isomorfeus.current_user
128
124
  end
@@ -66,16 +66,21 @@ module Isomorfeus
66
66
  end
67
67
 
68
68
  def promise_destroy
69
- self.class.promise_destroy(@key)
69
+ self.class.promise_destroy(key: @key)
70
70
  end
71
71
 
72
72
  def reload
73
- self.class.promise_load!(@key, self)
73
+ self.class.promise_load!(key: @key, instance: self)
74
74
  self
75
75
  end
76
76
 
77
77
  def promise_reload
78
- self.class.promise_load!(@key, self)
78
+ self.class.promise_load!(key: @key, instance: self)
79
+ end
80
+
81
+ def save
82
+ promise_save
83
+ self
79
84
  end
80
85
 
81
86
  def promise_save
@@ -122,6 +127,20 @@ module Isomorfeus
122
127
  promise.resolve(create)
123
128
  end
124
129
 
130
+ def destroy
131
+ self.class.destroy(key: @key)
132
+ end
133
+
134
+ def promise_destroy
135
+ self.class.promise_destroy(key: @key)
136
+ end
137
+
138
+ # reload must be implemented by mixin
139
+
140
+ def promise_reload
141
+ Promise.new.resolve(reload)
142
+ end
143
+
125
144
  def save
126
145
  previous_key = self.key
127
146
  instance = instance_exec(&self.class.instance_variable_get(:@_save_block))
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Data
3
- VERSION = '2.0.5'
3
+ VERSION = '2.0.9'
4
4
  end
5
5
  end
@@ -8,7 +8,6 @@ require 'isomorfeus/data/attribute_support'
8
8
  require 'isomorfeus/data/field_support'
9
9
  require 'isomorfeus/data/generic_class_api'
10
10
  require 'isomorfeus/data/generic_instance_api'
11
- require 'isomorfeus/data/element_validator'
12
11
 
13
12
  if RUBY_ENGINE == 'opal'
14
13
  require 'isomorfeus/data/reducer'
@@ -5,6 +5,12 @@ module LucidDocument
5
5
  base.extend(Isomorfeus::Data::GenericClassApi)
6
6
  base.include(Isomorfeus::Data::GenericInstanceApi)
7
7
 
8
+ base.instance_exec do
9
+ def escape_string(s)
10
+ s.gsub(/([\\\&\:\(\)\[\]\{\}\!\"\~\^\|\<\>\=\*\?\+\-\s])/, '\\\\\1')
11
+ end
12
+ end
13
+
8
14
  def [](name)
9
15
  send(name)
10
16
  end
@@ -26,7 +32,7 @@ module LucidDocument
26
32
  end
27
33
 
28
34
  if RUBY_ENGINE == 'opal'
29
- def initialize(key: nil, revision: nil, fields: nil)
35
+ def initialize(key: nil, revision: nil, fields: nil, _loading: false)
30
36
  @key = key.nil? ? SecureRandom.uuid : key.to_s
31
37
  @class_name = self.class.name
32
38
  @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
@@ -34,19 +40,25 @@ module LucidDocument
34
40
  @_revision = revision ? revision : Redux.fetch_by_path(:data_state, :revision, @class_name, @key)
35
41
  @_changed = false
36
42
  loaded = loaded?
37
- if fields
38
- if loaded
39
- raw_fields = Redux.fetch_by_path(*@_store_path)
40
- if `raw_fields === null`
41
- @_changed_fields = !fields ? {} : fields
42
- elsif raw_fields && !fields.nil? && ::Hash.new(raw_fields) != fields
43
+ if loaded
44
+ raw_fields = Redux.fetch_by_path(*@_store_path)
45
+ if `raw_fields === null`
46
+ if fields
47
+ _validate_fields(fields)
43
48
  @_changed_fields = fields
49
+ else
50
+ @_changed_fields = {}
44
51
  end
45
- else
52
+ elsif raw_fields && fields && ::Hash.new(raw_fields) != fields
53
+ _validate_fields(fields)
46
54
  @_changed_fields = fields
55
+ else
56
+ @_changed_fields = {}
47
57
  end
48
58
  else
49
- @_changed_fields = {}
59
+ fields = {} unless fields
60
+ _validate_fields(fields) unless _loading
61
+ @_changed_fields = fields
50
62
  end
51
63
  end
52
64
 
@@ -89,15 +101,24 @@ module LucidDocument
89
101
  def search(query, options = {})
90
102
  top_docs = []
91
103
  self.ferret_accelerator.search_each(query, options) do |id|
92
- doc = self.ferret_accelerator.load_doc(id)
93
- top_docs << self.new(key: doc[:key], fields: doc) if doc
104
+ doc = self.ferret_accelerator.index.doc(id)&.load
105
+ if doc
106
+ key = doc.delete(:key)
107
+ top_docs << self.new(key: key, fields: doc)
108
+ end
94
109
  end
95
110
  top_docs
96
111
  end
97
112
 
98
113
  execute_create do
99
- doc = self.fields
100
- doc[:key] = self.key.nil? ? SecureRandom.uuid : self.key
114
+ doc = self.fields.dup
115
+ if self.key.nil?
116
+ u = SecureRandom.uuid
117
+ doc[:key] = u
118
+ self.key = u
119
+ else
120
+ doc[:key] = self.key
121
+ end
101
122
  self.class.ferret_accelerator.create_doc(doc)
102
123
  self
103
124
  end
@@ -115,9 +136,11 @@ module LucidDocument
115
136
  end
116
137
 
117
138
  execute_save do
118
- doc = self.fields
139
+ doc = self.fields.dup
119
140
  if self.key.nil?
120
- doc[:key] = SecureRandom.uuid
141
+ u = SecureRandom.uuid
142
+ doc[:key] = u
143
+ self.key = u
121
144
  self.class.ferret_accelerator.create_doc(doc)
122
145
  else
123
146
  doc[:key] = self.key
@@ -134,6 +157,7 @@ module LucidDocument
134
157
  @_revision = revision
135
158
  @_changed = false
136
159
  fields = {} unless fields
160
+ _validate_fields(fields)
137
161
  @_raw_fields = fields
138
162
  end
139
163
 
@@ -144,6 +168,13 @@ module LucidDocument
144
168
  def each(&block)
145
169
  @_raw_fields.each(&block)
146
170
  end
171
+
172
+ def reload
173
+ new_instance = self.class.load(key: @key)
174
+ @_raw_fields = new_instance.fields
175
+ _unchange!
176
+ self
177
+ end
147
178
  end # RUBY_ENGINE
148
179
  end
149
180
  end
@@ -92,7 +92,7 @@ module LucidFile
92
92
  end
93
93
  end
94
94
 
95
- def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, revision: nil)
95
+ def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, revision: nil, _loading: false)
96
96
  @key = key.nil? ? SecureRandom.uuid : key.to_s
97
97
  @class_name = self.class.name
98
98
  @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
@@ -5,10 +5,6 @@ module LucidObject
5
5
  base.extend(Isomorfeus::Data::GenericClassApi)
6
6
  base.include(Isomorfeus::Data::GenericInstanceApi)
7
7
 
8
- def changed!
9
- @_changed = true
10
- end
11
-
12
8
  def [](name)
13
9
  send(name)
14
10
  end
@@ -17,6 +13,10 @@ module LucidObject
17
13
  send("#{name}=".to_sym, val)
18
14
  end
19
15
 
16
+ def changed!
17
+ @_changed = true
18
+ end
19
+
20
20
  def to_transport
21
21
  hash = { 'attributes' => _get_selected_attributes }
22
22
  hash['revision'] = revision if revision
@@ -26,7 +26,7 @@ module LucidObject
26
26
  end
27
27
 
28
28
  if RUBY_ENGINE == 'opal'
29
- def initialize(key: nil, revision: nil, attributes: nil)
29
+ def initialize(key: nil, revision: nil, attributes: nil, _loading: false)
30
30
  @key = key.nil? ? SecureRandom.uuid : key.to_s
31
31
  @class_name = self.class.name
32
32
  @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
@@ -34,20 +34,25 @@ module LucidObject
34
34
  @_revision = revision ? revision : Redux.fetch_by_path(:data_state, :revision, @class_name, @key)
35
35
  @_changed = false
36
36
  loaded = loaded?
37
- if attributes
38
- _validate_attributes(attributes)
39
- if loaded
40
- raw_attributes = Redux.fetch_by_path(*@_store_path)
41
- if `raw_attributes === null`
42
- @_changed_attributes = !attributes ? {} : attributes
43
- elsif raw_attributes && !attributes.nil? && ::Hash.new(raw_attributes) != attributes
37
+ if loaded
38
+ raw_attributes = Redux.fetch_by_path(*@_store_path)
39
+ if `raw_attributes === null`
40
+ if attributes
41
+ _validate_attributes(attributes)
44
42
  @_changed_attributes = attributes
43
+ else
44
+ @_changed_attributes = {}
45
45
  end
46
- else
46
+ elsif raw_attributes && attributes && ::Hash.new(raw_attributes) != attributes
47
+ _validate_attributes(attributes)
47
48
  @_changed_attributes = attributes
49
+ else
50
+ @_changed_attributes = {}
48
51
  end
49
52
  else
50
- @_changed_attributes = {}
53
+ attributes = {} unless attributes
54
+ _validate_attributes(attributes) unless _loading
55
+ @_changed_attributes = attributes
51
56
  end
52
57
  end
53
58
 
@@ -210,6 +215,13 @@ module LucidObject
210
215
  def each(&block)
211
216
  @_raw_attributes.each(&block)
212
217
  end
218
+
219
+ def reload
220
+ new_instance = self.class.load(key: @key)
221
+ @_raw_attributes = new_instance.attributes
222
+ _unchange!
223
+ self
224
+ end
213
225
  end # RUBY_ENGINE
214
226
  end
215
227
  end
@@ -5,20 +5,23 @@ module LucidQuery
5
5
 
6
6
  if RUBY_ENGINE == 'opal'
7
7
  base.instance_exec do
8
- def execute(**props)
9
- props[:query_result_instance] = LucidQueryResult.new
8
+ def execute(key: nil, **props)
9
+ props[:query_result_instance] = LucidQueryResult.new(key: key)
10
10
  promise_execute(props) unless props[:query_result_instance].loaded?
11
11
  props[:query_result_instance]
12
12
  end
13
13
 
14
- def promise_execute(**props)
14
+ def promise_execute(key: nil, **props)
15
15
  query_result_instance = props.delete(:query_result_instance)
16
- query_result_instance = LucidQueryResult.new unless query_result_instance
16
+ query_result_instance = LucidQueryResult.new(key: key) unless query_result_instance
17
+
18
+ return Promise.new.resolve(query_result_instance) if query_result_instance.loaded?
19
+
17
20
  props.each_key do |prop_name|
18
21
  Isomorfeus.raise_error(message: "#{self.to_s} No such query prop declared: '#{prop_name}'!") unless declared_props.key?(prop_name)
19
22
  end
20
23
  props = validated_props(props)
21
- props[:query_result_instance_key] = query_result_instance.key
24
+ props[:key] = query_result_instance.key
22
25
  Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :query, props).then do |agent|
23
26
  if agent.processed
24
27
  agent.result
@@ -50,10 +53,9 @@ module LucidQuery
50
53
  end
51
54
 
52
55
  def execute(**props)
53
- query_result_instance_key = props.delete(:query_result_instance_key)
54
- query_result = LucidQueryResult.new(key: query_result_instance_key)
55
- query_result.result_set = self.new(**props).instance_exec(&@_query_block)
56
- query_result
56
+ key = props.delete(:key)
57
+ result_set = self.new(**props).instance_exec(&@_query_block)
58
+ LucidQueryResult.new(key: key, result_set: result_set)
57
59
  end
58
60
 
59
61
  def execute_query(&block)
@@ -14,7 +14,7 @@ class LucidQueryResult
14
14
  end
15
15
 
16
16
  if RUBY_ENGINE == 'opal'
17
- def initialize(key: nil, result_set: {})
17
+ def initialize(key: nil, result_set: nil)
18
18
  @class_name = 'LucidQueryResult'
19
19
  @key = key ? key.to_s : self.object_id.to_s
20
20
  @result_set = result_set
@@ -39,17 +39,13 @@ class LucidQueryResult
39
39
  end
40
40
  alias has_key? key?
41
41
 
42
- def result_set=(r)
43
- @result_set = r
44
- end
45
-
46
42
  def method_missing(accessor_name, *args, &block)
47
43
  sid_or_array = if @result_set
48
- @result_set[accessor_name]
49
- else
50
- stored_results = Redux.fetch_by_path(:data_state, @class_name, @key)
51
- stored_results.JS[accessor_name] if stored_results
52
- end
44
+ @result_set[accessor_name]
45
+ else
46
+ stored_results = Redux.fetch_by_path(:data_state, @class_name, @key)
47
+ stored_results.JS[accessor_name] if stored_results
48
+ end
53
49
  Isomorfeus.raise_error(message: "#{@class_name}: no such thing '#{accessor_name}' in the results!") unless sid_or_array
54
50
  if stored_results.JS['_is_array_']
55
51
  sid_or_array.map { |sid| Isomorfeus.instance_from_sid(sid) }
@@ -58,7 +54,7 @@ class LucidQueryResult
58
54
  end
59
55
  end
60
56
  else
61
- def initialize(key: nil, result_set: {})
57
+ def initialize(key: nil, result_set: nil)
62
58
  @class_name = 'LucidQueryResult'
63
59
  @key = key ? key.to_s : self.object_id.to_s
64
60
  @result_set = result_set.nil? ? {} : result_set
@@ -74,10 +70,6 @@ class LucidQueryResult
74
70
  end
75
71
  alias has_key? key?
76
72
 
77
- def result_set=(r)
78
- @result_set = r
79
- end
80
-
81
73
  def method_missing(accessor_name, *args, &block)
82
74
  Isomorfeus.raise_error(message: "#{@class_name}: no such thing '#{accessor_name}' in the results!") unless @result_set.key?(accessor_name)
83
75
  @result_set[accessor_name]
data/opal/uri/generic.rb CHANGED
@@ -12,7 +12,7 @@ module URI
12
12
  :path, :opaque,
13
13
  :query,
14
14
  :fragment
15
- ].freeze
15
+ ]
16
16
 
17
17
  def initialize(scheme,
18
18
  userinfo, host, port, registry,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-22 00:00:00.000000000 Z
11
+ date: 2022-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.14.5
75
+ version: 0.14.6
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.14.5
82
+ version: 0.14.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: isomorfeus-ferret
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 10.6.11
117
+ version: 10.6.14
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 10.6.11
124
+ version: 10.6.14
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: isomorfeus-redux
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -142,28 +142,28 @@ dependencies:
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 2.0.5
145
+ version: 2.0.9
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 2.0.5
152
+ version: 2.0.9
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: isomorfeus
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - '='
158
158
  - !ruby/object:Gem::Version
159
- version: 2.0.5
159
+ version: 2.0.9
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - '='
165
165
  - !ruby/object:Gem::Version
166
- version: 2.0.5
166
+ version: 2.0.9
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rake
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -207,7 +207,6 @@ files:
207
207
  - lib/isomorfeus-data.rb
208
208
  - lib/isomorfeus/data/attribute_support.rb
209
209
  - lib/isomorfeus/data/config.rb
210
- - lib/isomorfeus/data/element_validator.rb
211
210
  - lib/isomorfeus/data/ferret_accelerator.rb
212
211
  - lib/isomorfeus/data/field_support.rb
213
212
  - lib/isomorfeus/data/generic_class_api.rb
@@ -1,147 +0,0 @@
1
- module Isomorfeus
2
- module Data
3
- class ElementValidator
4
- def initialize(source_class, element, options)
5
- @c = source_class
6
- @e = element
7
- @o = options
8
- end
9
-
10
- def validate!
11
- ensured = ensure!
12
- unless ensured
13
- cast!
14
- type!
15
- end
16
- run_checks!
17
- true
18
- end
19
-
20
- private
21
-
22
- # basic tests
23
-
24
- def cast!
25
- if @o.key?(:cast)
26
- begin
27
- @e = case @o[:class]
28
- when Integer then @e.to_i
29
- when String then @e.to_s
30
- when Float then @e.to_f
31
- when Array then @e.to_a
32
- when Hash then @e.to_h
33
- end
34
- @e = !!@e if @o[:type] == :boolean
35
- rescue
36
- Isomorfeus.raise_error(message: "#{@c}: #{@p} cast failed") unless @e.class == @o[:class]
37
- end
38
- end
39
- end
40
-
41
- def ensure!
42
- if @o.key?(:ensure)
43
- @e = @o[:ensure] unless @e
44
- true
45
- elsif @o.key?(:ensure_block)
46
- @e = @o[:ensure_block].call(@e)
47
- true
48
- else
49
- false
50
- end
51
- end
52
-
53
- def type!
54
- return if @o[:allow_nil] && @e.nil?
55
- if @o.key?(:class)
56
- Isomorfeus.raise_error(message: "#{@c}: #{@p} class not #{@o[:class]}") unless @e.class == @o[:class]
57
- elsif @o.key?(:is_a)
58
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is not a #{@o[:is_a]}") unless @e.is_a?(@o[:is_a])
59
- elsif @o.key?(:type)
60
- case @o[:type]
61
- when :boolean
62
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is not a boolean") unless @e.class == TrueClass || @e.class == FalseClass
63
- else
64
- c_string_sub_types
65
- end
66
- end
67
- end
68
-
69
- # all other checks
70
-
71
- def run_checks!
72
- if @o.key?(:validate)
73
- @o[:validate].each do |m, l|
74
- send('c_' + m, l)
75
- end
76
- end
77
- @o[:validate_block].call(@e) if @o.key?(:validate_block)
78
- end
79
-
80
- # specific validations
81
- def c_gt(v)
82
- Isomorfeus.raise_error(message: "#{@c}: #{@p} not greater than #{v}!") unless @e > v
83
- end
84
-
85
- def c_lt(v)
86
- Isomorfeus.raise_error(message: "#{@c}: #{@p} not less than #{v}!") unless @e < v
87
- end
88
-
89
- def c_keys(v)
90
- Isomorfeus.raise_error(message: "#{@c}: #{@p} keys dont fit!") unless @e.keys.sort == v.sort
91
- end
92
-
93
- def c_size(v)
94
- Isomorfeus.raise_error(message: "#{@c}: #{@p} length/size is not #{v}") unless @e.size == v
95
- end
96
-
97
- def c_matches(v)
98
- Isomorfeus.raise_error(message: "#{@c}: #{@p} does not match #{v}") unless v.match?(@e)
99
- end
100
-
101
- def c_max(v)
102
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is larger than #{v}") unless @e <= v
103
- end
104
-
105
- def c_min(v)
106
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is smaller than #{v}") unless @e >= v
107
- end
108
-
109
- def c_max_size(v)
110
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is larger than #{v}") unless @e.size <= v
111
- end
112
-
113
- def c_min_size(v)
114
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is smaller than #{v}") unless @e.size >= v
115
- end
116
-
117
- def c_direction(v)
118
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is positive") if v == :negative && @e >= 0
119
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is negative") if v == :positive && @e < 0
120
- end
121
-
122
- def c_test
123
- Isomorfeus.raise_error(message: "#{@c}: #{@p} test condition check failed") unless @o[:test].call(@e)
124
- end
125
-
126
- def c_string_sub_types
127
- Isomorfeus.raise_error(message: "#{@c}: #{@p} must be a String") unless @e.class == String
128
- case @o[:type]
129
- when :email
130
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is not a valid email address") unless @e.match?(/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/)
131
- when :uri
132
- if RUBY_ENGINE == 'opal'
133
- %x{
134
- try {
135
- new URL(#@e);
136
- } catch {
137
- #{Isomorfeus.raise_error(message: "#{@c}: #{@p} is not a valid uri")}
138
- }
139
- }
140
- else
141
- Isomorfeus.raise_error(message: "#{@c}: #{@p} is not a valid uri") unless @e.match?(/\A#{URI.regexp}\z/)
142
- end
143
- end
144
- end
145
- end
146
- end
147
- end