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 +4 -4
- data/lib/data_uri/uri.rb +3 -3
- data/lib/data_uri.rb +0 -1
- data/lib/isomorfeus/data/attribute_support.rb +14 -16
- data/lib/isomorfeus/data/ferret_accelerator.rb +25 -7
- data/lib/isomorfeus/data/field_support.rb +74 -7
- data/lib/isomorfeus/data/generic_class_api.rb +14 -18
- data/lib/isomorfeus/data/generic_instance_api.rb +22 -3
- data/lib/isomorfeus/data/version.rb +1 -1
- data/lib/isomorfeus-data.rb +0 -1
- data/lib/isomorfeus_data/lucid_document/mixin.rb +46 -15
- data/lib/isomorfeus_data/lucid_file/mixin.rb +1 -1
- data/lib/isomorfeus_data/lucid_object/mixin.rb +26 -14
- data/lib/isomorfeus_data/lucid_query/mixin.rb +11 -9
- data/lib/isomorfeus_data/lucid_query_result.rb +7 -15
- data/opal/uri/generic.rb +1 -1
- metadata +10 -11
- data/lib/isomorfeus/data/element_validator.rb +0 -147
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03adcad549502d3b374fa200b4c1a90b4a1963288a40e619a170ffb5190ec870
|
4
|
+
data.tar.gz: 000c496d28015877c52c84934d100827dea59740cda0f78b1b6f8b6c9eea5979
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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]
|
4
|
-
MIME_TYPE_RE = %r{^([-\w.+]+/[-\w.+]*)}
|
5
|
-
MIME_PARAM_RE = /^;([-\w.+]+)=([^;,]+)
|
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
@@ -11,8 +11,8 @@ module Isomorfeus
|
|
11
11
|
@indexed_attributes ||= {}
|
12
12
|
end
|
13
13
|
|
14
|
-
def valid_attribute?(attr_name,
|
15
|
-
Isomorfeus::Props::Validator.new(self.name, attr_name,
|
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,
|
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,
|
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 |
|
31
|
-
if attribute_conditions[
|
32
|
-
Isomorfeus.raise_error(message: "Required attribute #{
|
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,
|
40
|
-
self.class._validate_attribute(attr_name,
|
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
|
-
|
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
|
-
|
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(
|
38
|
-
|
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(
|
43
|
-
|
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(
|
47
|
-
|
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
|
-
|
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
|
11
|
-
|
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 =
|
26
|
-
field_options[name] =
|
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 =
|
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] =
|
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 =
|
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
|
74
|
-
|
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))
|
data/lib/isomorfeus-data.rb
CHANGED
@@ -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
|
38
|
-
|
39
|
-
|
40
|
-
if
|
41
|
-
|
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
|
-
|
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
|
-
|
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.
|
93
|
-
|
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
|
-
|
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
|
-
|
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
|
38
|
-
|
39
|
-
if
|
40
|
-
|
41
|
-
|
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
|
-
|
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
|
-
|
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[:
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|