isomorfeus-data 1.0.0.zeta10 → 1.0.0.zeta11

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: 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