isomorfeus-data 1.0.0.zeta10 → 1.0.0.zeta11

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: f806c11706bdf321a3522be0c3fbf727695d65b6c8b8f8897158c4d136e593b2
4
- data.tar.gz: 462e6635a0c19080fba47e06bd076b15955e109c11b090175197e227e7c2d2db
3
+ metadata.gz: dd049fd338445d10e197978101c5a05f02a30640666e4096bebbe75fc18d28df
4
+ data.tar.gz: d34b607a5f86824905a11b9283102db0698091eb8ecf028e57d9e0fcee78dac0
5
5
  SHA512:
6
- metadata.gz: 10645fb7608b96f4f2b2e6a5a3d8f89de7d28ef1aef47920a4566b486a73ee4992a09c61b1290008d60b4129e0fa8d9b2acd7447bec4e4d0daba54d95da92686
7
- data.tar.gz: 55e236b32fb9c8b1432ae7c18f5e16b1f50432e70d7e5691f8367ad1578aa8af84f570562d8484e7fb8a6b1e1c17ce4a9e93bbe0e8adee607e9ed30dbc8f00cb
6
+ metadata.gz: 45ca03236e53607fb90bc7ddef14f614a01db6bc43afae81a25da3f5283cdbfa182d7400608ca7a80267cb648ec461776a2104b882af86b8c14a21f77711bcd5
7
+ data.tar.gz: 9120881d8116d9ded40da8228fd3da9d8f28c552282f509ef9a8fd934ea9c6cf3addb4acffc046823f323e7cb8a071be14d045fbf5a27ccd8f3d97821d851075
@@ -1,25 +1,9 @@
1
1
  require 'isomorfeus-transport'
2
2
  require 'isomorfeus/data/config'
3
- require 'isomorfeus/data/props'
4
3
  require 'isomorfeus/data/attribute_support'
5
4
  require 'isomorfeus/data/generic_class_api'
6
5
  require 'isomorfeus/data/generic_instance_api'
7
6
  require 'isomorfeus/data/element_validator'
8
- #require 'lucid_arango/node/mixin'
9
- #require 'lucid_arango/node/base'
10
- #require 'lucid_arango/document/mixin'
11
- #require 'lucid_arango/document/base'
12
- #require 'lucid_arango/vertex/mixin'
13
- #require 'lucid_arango/vertex/base'
14
- #require 'lucid_arango/edge/mixin'
15
- #require 'lucid_arango/edge/base'
16
- #require 'lucid_arango/collection/mixin'
17
- #require 'lucid_arango/collection/base'
18
- #require 'lucid_arango/edge_collection/mixin'
19
- #require 'lucid_arango/edge_collection/base'
20
- #require 'lucid_arango/graph/mixin'
21
- #require 'lucid_arango/graph/base'
22
-
23
7
 
24
8
  if RUBY_ENGINE == 'opal'
25
9
  require 'isomorfeus/data/reducer'
@@ -31,9 +15,8 @@ else
31
15
  require 'oj'
32
16
  require 'active_support'
33
17
  require 'active_support/core_ext/hash'
34
- #require 'arango-driver'
35
- #require 'isomorfeus/data/handler/arango'
36
18
 
19
+ require 'isomorfeus_data/lucid_data/query_result'
37
20
  require 'isomorfeus_data/lucid_data/array/mixin'
38
21
  require 'isomorfeus_data/lucid_data/array/base'
39
22
  require 'isomorfeus_data/lucid_data/hash/mixin'
@@ -59,16 +42,10 @@ else
59
42
  require 'isomorfeus_data/lucid_data/graph/finders'
60
43
  require 'isomorfeus_data/lucid_data/graph/mixin'
61
44
  require 'isomorfeus_data/lucid_data/graph/base'
62
- require 'isomorfeus_data/lucid_data/object/mixin'
63
- require 'isomorfeus_data/lucid_data/object/base'
64
- require 'isomorfeus_data/lucid_data/remote_object/mixin'
65
- require 'isomorfeus_data/lucid_data/remote_object/base'
66
45
  require 'isomorfeus_data/lucid_data/composition/mixin'
67
46
  require 'isomorfeus_data/lucid_data/composition/base'
68
47
 
69
48
  require 'isomorfeus/data/handler/generic'
70
- require 'isomorfeus/data/handler/object_call'
71
- require 'isomorfeus/data/handler/object_store'
72
49
 
73
50
  Opal.append_path(__dir__.untaint) unless Opal.paths.include?(__dir__.untaint)
74
51
 
@@ -16,11 +16,28 @@ module Isomorfeus
16
16
  def validate
17
17
  Isomorfeus::Props::ValidateHashProxy.new
18
18
  end
19
+
20
+ def _validate_attribute(attr_name, attr_val)
21
+ raise "#{self.name}: No such attribute declared: '#{attr_name}'!" unless attribute_conditions.key?(attr_name)
22
+ Isomorfeus::Props::Validator.new(self.name, attr_name, attr_val, attribute_conditions[attr_name]).validate!
23
+ end
24
+
25
+ def _validate_attributes(attrs)
26
+ attribute_conditions.each_key do |attr|
27
+ if attribute_conditions[attr].key?(:required) && attribute_conditions[attr][:required] && !attrs.key?(attr)
28
+ raise "Required attribute #{attr} not given!"
29
+ end
30
+ end
31
+ attrs.each { |attr, val| _validate_attribute(attr, val) }
32
+ end
33
+ end
34
+
35
+ def _validate_attribute(attr_name, value)
36
+ self.class._validate_attribute(attr_name, value)
19
37
  end
20
38
 
21
- def _validate_attribute(attr_name, attr_val)
22
- raise "#{@class_name} No such attribute declared: '#{attr_name}'!" unless self.class.attribute_conditions.key?(attr_name)
23
- Isomorfeus::Props::Validator.new(@class_name, attr_name, attr_val, self.class.attribute_conditions[attr_name]).validate!
39
+ def _validate_attributes(attrs)
40
+ self.class._validate_attributes(attrs)
24
41
  end
25
42
 
26
43
  def exclude_attributes(*attrs)
@@ -37,12 +54,7 @@ module Isomorfeus
37
54
  attribute_conditions[name] = options
38
55
 
39
56
  define_method(name) do
40
- v = _get_attribute(name)
41
- %x{
42
- if (v instanceof Object && !(v instanceof Array)) {
43
- return Opal.Hash.$new(v);
44
- } else { return v; }
45
- }
57
+ _get_attribute(name)
46
58
  end
47
59
 
48
60
  define_method("#{name}=") do |val|
@@ -57,8 +69,12 @@ module Isomorfeus
57
69
  return @_changed_attributes[name] if @_changed_attributes.key?(name)
58
70
  path = @_store_path + [name]
59
71
  result = Redux.fetch_by_path(*path)
60
- return nil if `result === null`
61
- result
72
+ %x{
73
+ if (result === null) { return nil; }
74
+ else if (result instanceof Object && !(result instanceof Array)) {
75
+ return Opal.Hash.$new(result);
76
+ } else { return result; }
77
+ }
62
78
  end
63
79
 
64
80
  def _get_attributes
@@ -57,20 +57,21 @@ module Isomorfeus
57
57
  end
58
58
  end
59
59
 
60
- def promise_load_once(key:, instance: nil)
61
- instance = self.new(key: key) unless instance
62
- if instance.loaded?
63
- Promise.new.resolve(instance)
64
- else
65
- promise_load(key: key, instance: instance)
66
- end
60
+ def query(props:)
61
+ query_result_instance = LucidData::QueryResult.new
62
+ promise_query(props: props, query_result_instance: query_result_instance) unless query_result_instance.loaded?
63
+ query_result_instance
67
64
  end
68
65
 
69
- def promise_query(props = {})
66
+ def promise_query(props:, query_result_instance: nil)
67
+ query_result_instance = LucidData::QueryResult.new unless query_result_instance
68
+ props.each_key do |prop_name|
69
+ raise "#{self.to_s} No such query prop declared: '#{prop_name}'!" unless declared_props.key?(prop_name)
70
+ end
70
71
  validate_props(props)
71
- props_json = props.to_json
72
- instance = self.new(key) unless instance
73
- Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, 'query', props_json).then do |agent|
72
+ data_props = { props: props, query_result_instance_key: query_result_instance.key }
73
+ props_json = data_props.to_json
74
+ Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :query, props_json).then do |agent|
74
75
  if agent.processed
75
76
  agent.result
76
77
  else
@@ -79,8 +80,9 @@ module Isomorfeus
79
80
  `console.error(#{agent.response[:error].to_n})`
80
81
  raise agent.response[:error]
81
82
  end
83
+ query_result_instance._load_from_store!
82
84
  Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.full_response[:data])
83
- agent.result = instance
85
+ agent.result = query_result_instance
84
86
  end
85
87
  end
86
88
  end
@@ -90,12 +92,6 @@ module Isomorfeus
90
92
  def execute_load(_); end
91
93
  def execute_query(_); end
92
94
  def execute_save(_); end
93
-
94
- # callbacks
95
- def on_destroy(_); end
96
- def on_load(_); end
97
- def on_query(_); end
98
- def on_save(_); end
99
95
  else
100
96
  def promise_create(key:, **things)
101
97
  instance = self.create(key: key, **things)
@@ -105,12 +101,16 @@ module Isomorfeus
105
101
  end
106
102
 
107
103
  def promise_destroy(key:)
108
- self.destroy(key: key)
104
+ sid = self.destroy(key: key)
109
105
  result_promise = Promise.new
110
- result_promise.resolve(true)
106
+ result_promise.resolve(sid)
111
107
  result_promise
112
108
  end
113
109
 
110
+ def destroy(key:, pub_sub_client: nil, current_user: nil)
111
+ instance_exec(key: key, pub_sub_client: pub_sub_client, current_user: current_user, &@_destroy_block)
112
+ end
113
+
114
114
  def promise_load(key:)
115
115
  instance = self.load(key: key)
116
116
  result_promise = Promise.new
@@ -118,13 +118,24 @@ module Isomorfeus
118
118
  result_promise
119
119
  end
120
120
 
121
- def promise_query(props)
122
- instance = self.query(props)
121
+ def promise_query(props:)
122
+ instance = self.query(props: props)
123
123
  result_promise = Promise.new
124
124
  result_promise.resolve(instance)
125
125
  result_promise
126
126
  end
127
127
 
128
+ def query(props:, query_result_instance_key: nil, pub_sub_client: nil, current_user: nil)
129
+ props.each_key do |prop_name|
130
+ raise "#{self.to_s} No such query prop declared: '#{prop_name}'!" unless declared_props.key?(prop_name)
131
+ end
132
+ validate_props(props)
133
+ query_result = LucidData::QueryResult.new(key: query_result_instance_key)
134
+ query_result.result_set = instance_exec(props: Isomorfeus::Transport::PropsProxy.new(props),
135
+ pub_sub_client: pub_sub_client, current_user: current_user, &@_query_block)
136
+ query_result
137
+ end
138
+
128
139
  # execute
129
140
  def execute_destroy(&block)
130
141
  @_destroy_block = block
@@ -141,23 +152,6 @@ module Isomorfeus
141
152
  def execute_save(&block)
142
153
  @_save_block = block
143
154
  end
144
-
145
- # callbacks
146
- def on_destroy(&block)
147
- @_on_destroy_block = block
148
- end
149
-
150
- def on_load(&block)
151
- @_on_load_block = block
152
- end
153
-
154
- def on_query(&block)
155
- @_on_query_block = block
156
- end
157
-
158
- def on_save(&block)
159
- @_on_save_block = block
160
- end
161
155
  end
162
156
  end
163
157
  end
@@ -36,10 +36,6 @@ module Isomorfeus
36
36
  self
37
37
  end
38
38
 
39
- def promise_load_once
40
- self.class.promise_load_once(key: key, instance: self)
41
- end
42
-
43
39
  def promise_reload
44
40
  self.class.promise_load(@key, self)
45
41
  end
@@ -51,7 +47,11 @@ module Isomorfeus
51
47
  alias create save
52
48
 
53
49
  def promise_save
54
- Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, 'save', to_transport).then do |agent|
50
+ data_hash = to_transport
51
+ if self.respond_to?(:included_changed_items)
52
+ data_hash.deep_merge!(self.included_changed_items)
53
+ end
54
+ Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, 'save', data_hash).then do |agent|
55
55
  if agent.processed
56
56
  agent.result
57
57
  else
@@ -5,11 +5,14 @@ module Isomorfeus
5
5
  module Handler
6
6
  class Generic < LucidHandler::Base
7
7
  # responsible for loading:
8
- # LucidArray
9
- # LucidHash
8
+ # LucidData::Array
9
+ # LucidData::Hash
10
10
  # LucidData::Edge
11
11
  # LucidData::Document
12
12
  # LucidData::Collection
13
+ # LucidData::EdgeCollection
14
+ # LucidData::Graph
15
+ # LucidData::Composition
13
16
 
14
17
  def process_request(pub_sub_client, current_user, response_agent)
15
18
  # promise_send_path('Isomorfeus::Data::Handler::Generic', self.to_s, action, props_hash)
@@ -19,8 +22,10 @@ module Isomorfeus
19
22
  if type_class
20
23
  response_agent.request[type_class_name].each_key do |action|
21
24
  case action
22
- when 'load' then process_load(pub_sub_client, current_user, response_agent, type_class, type_class_name, action)
23
- when 'store' then process_store(pub_sub_client, current_user, response_agent, type_class, type_class_name, action)
25
+ when 'load' then process_load(pub_sub_client, current_user, response_agent, type_class, type_class_name)
26
+ when 'query' then process_query(pub_sub_client, current_user, response_agent, type_class, type_class_name)
27
+ when 'save' then process_save(pub_sub_client, current_user, response_agent, type_class, type_class_name)
28
+ when 'destroy' then process_destroy(pub_sub_client, current_user, response_agent, type_class, type_class_name)
24
29
  else response_agent.error = { error: { action => 'No such thing!' }}
25
30
  end
26
31
  end
@@ -35,17 +40,13 @@ module Isomorfeus
35
40
  end
36
41
  end
37
42
 
38
- def process_load(pub_sub_client, current_user, response_agent, type_class, type_class_name, action)
39
- props = response_agent.request[type_class_name][action]
40
- # STDERR.puts "PROPS_JSON #{props_json}"
41
- # props = Oj.load(props_json, mode: :strict)
43
+ def process_load(pub_sub_client, current_user, response_agent, type_class, type_class_name)
44
+ props = response_agent.request[type_class_name]['load']
42
45
  props.transform_keys!(&:to_sym)
43
46
  props.merge!(pub_sub_client: pub_sub_client, current_user: current_user)
44
47
  if current_user.authorized?(type_class, :load, props)
45
48
  loaded_type = type_class.load(**props)
46
49
  if loaded_type
47
- on_load_block = type_class.instance_variable_get(:@_on_load_block)
48
- loaded_type.instance_exec(pub_sub_client, current_user, &on_load_block) if on_load_block
49
50
  response_agent.outer_result = { data: loaded_type.to_transport }
50
51
  if loaded_type.respond_to?(:included_items_to_transport)
51
52
  response_agent.outer_result.deep_merge!(data: loaded_type.included_items_to_transport)
@@ -57,35 +58,73 @@ module Isomorfeus
57
58
  end
58
59
  end
59
60
 
60
- def process_store(pub_sub_client, current_user, response_agent, type_class, type_class_name, action)
61
- props_json = response_agent.request[type_class_name][action]
61
+ def process_query(pub_sub_client, current_user, response_agent, type_class, type_class_name)
62
+ props_json = response_agent.request[type_class_name]['query']
62
63
  props = Oj.load(props_json, mode: :strict)
63
- props.merge!(pub_sub_client: pub_sub_client, current_user: current_user)
64
- if current_user.authorized?(type_class, :store, props)
65
- stored_type = type_class.new(**props).store
66
- on_store_block = type_class.instance_variable_get(:@_on_store_block)
67
- stored_type.instance_exec(pub_sub_client, current_user, &on_store_block) if on_store_block
68
- response_agent.outer_result = { data: stored_type.to_transport }
64
+ props.transform_keys!(&:to_sym)
65
+ props[:props].transform_keys!(&:to_sym)
66
+ props.deep_merge!({ pub_sub_client: pub_sub_client, current_user: current_user })
67
+ if current_user.authorized?(type_class, :query, props[:props])
68
+ queried_type = type_class.query(**props)
69
+ if queried_type
70
+ response_agent.outer_result = { data: queried_type.to_transport }
71
+ if queried_type.respond_to?(:included_items_to_transport)
72
+ response_agent.outer_result.deep_merge!(data: queried_type.included_items_to_transport)
73
+ end
74
+ response_agent.agent_result = { success: 'ok' }
75
+ else response_agent.error = { error: { type_class_name => 'No such thing!' }}
76
+ end
77
+ else response_agent.error = { error: 'Access denied!' }
78
+ end
79
+ end
80
+
81
+ def process_save(pub_sub_client, current_user, response_agent, type_class, type_class_name)
82
+ data_hash_json = response_agent.request[type_class_name]['save']
83
+ data_hash = Oj.load(data_hash_json, mode: :strict)
84
+ response_agent.outer_result = {}
85
+ if current_user.authorized?(type_class, :save, { pub_sub_client: pub_sub_client, current_user: current_user })
86
+ data_hash.each_key do |data_class_name|
87
+ data_hash[data_class_name].each_key do |key|
88
+ if Isomorfeus.valid_data_class_name?(type_class_name)
89
+ data_class = Isomorfeus.cached_data_class(data_class_name)
90
+ if data_class
91
+ item_data_hash = data_hash[data_class_name][key]
92
+ item_data_hash = item_data_hash.merge({ pub_sub_client: pub_sub_client, current_user: current_user })
93
+ if current_user.authorized?(data_class, :save, item_data_hash)
94
+ saved_type = data_class.save(**item_data_hash)
95
+ if saved_type
96
+ response_agent.outer_result.deep_merge!({ data: saved_type.to_transport })
97
+ end
98
+ else
99
+ response_agent.error = { error: 'Access denied!' }
100
+ break
101
+ end
102
+ else
103
+ response_agent.error = { error: 'Access denied!' }
104
+ break
105
+ end
106
+ end
107
+ end
108
+ end
69
109
  response_agent.agent_result = { success: 'ok' }
70
110
  else response_agent.error = { error: 'Access denied!' }
71
111
  end
72
112
  end
73
113
 
74
- #def process_destroy(pub_sub_client, current_user, response_agent, type_class, type_class_name, action)
75
- # props_json = response_agent.request[type_class_name][action]
76
- # props = Oj.load(props_json, mode: :strict)
77
- # props.merge!(pub_sub_client: pub_sub_client, current_user: current_user)
78
- # if current_user.authorized?(type_class, :store, *props)
79
- # # TODO
80
- # stored_type.instance_exec do
81
- # type_class.on_store_block.call(pub_sub_client, current_user) if type_class.on_store_block
82
- # end
83
- # destroyed = type_class.destroy(**props)
84
- # response_agent.outer_result = { data: stored_type.to_transport }
85
- # response_agent.agent_result = { success: 'ok' }
86
- # else response_agent.error = { error: 'Access denied!' }
87
- # end
88
- #end
114
+ def process_destroy(pub_sub_client, current_user, response_agent, type_class, type_class_name)
115
+ props_json = response_agent.request[type_class_name]['destroy']
116
+ props = Oj.load(props_json, mode: :strict)
117
+ props.merge!(pub_sub_client: pub_sub_client, current_user: current_user)
118
+ if current_user.authorized?(type_class, :destroy, props)
119
+ destroyed_type = type_class.destroy(**props)
120
+ if destroyed_type
121
+ response_agent.outer_result = { data: destroyed_type }
122
+ response_agent.agent_result = { success: 'ok' }
123
+ else response_agent.error = { error: { type_class_name => 'No such thing!' }}
124
+ end
125
+ else response_agent.error = { error: 'Access denied!' }
126
+ end
127
+ end
89
128
  end
90
129
  end
91
130
  end
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Data
3
- VERSION = '1.0.0.zeta10'
3
+ VERSION = '1.0.0.zeta11'
4
4
  end
5
5
  end
@@ -14,15 +14,23 @@ module LucidData
14
14
  alias element elements
15
15
 
16
16
  def element_conditions
17
- @element_conditions
17
+ @element_conditions ||= {}
18
18
  end
19
19
 
20
20
  def valid_element?(element)
21
- return true unless @element_conditions
22
- Isomorfeus::Data::ElementValidator.new(self.name, element, @element_conditions).validate!
21
+ return true unless element_conditions.any?
22
+ _validate_element(element)
23
23
  rescue
24
24
  false
25
25
  end
26
+
27
+ def _validate_element(element)
28
+ Isomorfeus::Data::ElementValidator.new(self.to_s, element, element_conditions).validate!
29
+ end
30
+
31
+ def _validate_elements(many_els)
32
+ many_els.each { |e| _validate_element(e) } if element_conditions.any?
33
+ end
26
34
  end
27
35
 
28
36
  def composition
@@ -38,8 +46,12 @@ module LucidData
38
46
  @_changed = true
39
47
  end
40
48
 
41
- def _validate_element(el)
42
- Isomorfeus::Data::ElementValidator.new(@class_name, el, @_el_con).validate!
49
+ def _validate_element(element)
50
+ self.class._validate_element(element)
51
+ end
52
+
53
+ def _validate_elements(many_elements)
54
+ self.class._validate_elements(many_elements)
43
55
  end
44
56
 
45
57
  if RUBY_ENGINE == 'opal'
@@ -52,11 +64,8 @@ module LucidData
52
64
  @_changed_array = nil
53
65
  @_composition = composition
54
66
  @_changed = false
55
- @_el_con = self.class.element_conditions
56
- @_validate_elements = @_el_con ? true : false
57
- if @_validate_elements && elements
58
- elements.each { |e| _validate_element(e) }
59
- end
67
+ @_validate_elements = self.class.element_conditions.any?
68
+ _validate_elements(elements)
60
69
  raw_array = Redux.fetch_by_path(*@_store_path)
61
70
  if `raw_array === null`
62
71
  @_changed_array = elements ? elements : []
@@ -343,9 +352,17 @@ module LucidData
343
352
 
344
353
  base.instance_exec do
345
354
  def load(key:, pub_sub_client: nil, current_user: nil)
346
- data = instance_exec(key: key, &@_load_block)
347
- revision = nil
348
- revision = data.delete(:revision) if data.key?(:revision)
355
+ data = instance_exec(key: key, pub_sub_client: pub_sub_client, current_user: current_user, &@_load_block)
356
+ revision = data.delete(:revision)
357
+ elements = data.delete(:elements)
358
+ self.new(key: key, revision: revision, elements: elements)
359
+ end
360
+
361
+ def save(key:, revision: nil, elements: nil, pub_sub_client: nil, current_user: nil)
362
+ _validate_elements(elements)
363
+ data = instance_exec(key: key, revision: revision, elements: elements,
364
+ pub_sub_client: pub_sub_client, current_user: current_user, &@_save_block)
365
+ revision = data.delete(:revision)
349
366
  elements = data.delete(:elements)
350
367
  self.new(key: key, revision: revision, elements: elements)
351
368
  end
@@ -358,12 +375,9 @@ module LucidData
358
375
  @_revision = revision
359
376
  @_changed = false
360
377
  @_composition = composition
361
- @_el_con = self.class.element_conditions
362
- @_validate_elements = @_el_con ? true : false
363
378
  elements = [] unless elements
364
- if @_validate_elements
365
- elements.each { |e| _validate_element(e) }
366
- end
379
+ @_validate_elements = self.class.element_conditions.any?
380
+ _validate_elements(elements)
367
381
  @_raw_array = elements
368
382
  end
369
383