isomorfeus-data 1.0.0.zeta5 → 1.0.0.zeta6

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -1
  3. data/lib/isomorfeus/data/attribute_support.rb +122 -0
  4. data/lib/isomorfeus/data/config.rb +79 -89
  5. data/lib/isomorfeus/data/element_validator.rb +133 -0
  6. data/lib/isomorfeus/data/generic_class_api.rb +155 -0
  7. data/lib/isomorfeus/data/generic_instance_api.rb +72 -0
  8. data/lib/isomorfeus/data/handler/arango.rb +61 -0
  9. data/lib/isomorfeus/data/handler/generic.rb +92 -0
  10. data/lib/isomorfeus/data/handler/object_call.rb +45 -0
  11. data/lib/isomorfeus/data/handler/object_store.rb +45 -0
  12. data/lib/isomorfeus/data/version.rb +1 -1
  13. data/lib/isomorfeus-data.rb +61 -30
  14. data/lib/isomorfeus_data/lucid_data/array/base.rb +15 -0
  15. data/lib/isomorfeus_data/lucid_data/array/mixin.rb +570 -0
  16. data/lib/isomorfeus_data/lucid_data/collection/base.rb +15 -0
  17. data/lib/isomorfeus_data/lucid_data/collection/finders.rb +83 -0
  18. data/lib/isomorfeus_data/lucid_data/collection/mixin.rb +710 -0
  19. data/lib/isomorfeus_data/lucid_data/composition/base.rb +15 -0
  20. data/lib/isomorfeus_data/lucid_data/composition/mixin.rb +185 -0
  21. data/lib/isomorfeus_data/lucid_data/document/base.rb +15 -0
  22. data/lib/isomorfeus_data/lucid_data/document/mixin.rb +9 -0
  23. data/lib/isomorfeus_data/lucid_data/edge/base.rb +15 -0
  24. data/lib/isomorfeus_data/lucid_data/edge/mixin.rb +281 -0
  25. data/lib/isomorfeus_data/lucid_data/edge_collection/base.rb +15 -0
  26. data/lib/isomorfeus_data/lucid_data/edge_collection/finders.rb +134 -0
  27. data/lib/isomorfeus_data/lucid_data/edge_collection/mixin.rb +705 -0
  28. data/lib/isomorfeus_data/lucid_data/graph/base.rb +15 -0
  29. data/lib/isomorfeus_data/lucid_data/graph/finders.rb +141 -0
  30. data/lib/isomorfeus_data/lucid_data/graph/mixin.rb +401 -0
  31. data/lib/isomorfeus_data/lucid_data/hash/base.rb +15 -0
  32. data/lib/isomorfeus_data/lucid_data/hash/mixin.rb +413 -0
  33. data/lib/isomorfeus_data/lucid_data/link/base.rb +15 -0
  34. data/lib/isomorfeus_data/lucid_data/link/mixin.rb +9 -0
  35. data/lib/isomorfeus_data/lucid_data/link_collection/base.rb +15 -0
  36. data/lib/isomorfeus_data/lucid_data/link_collection/mixin.rb +9 -0
  37. data/lib/isomorfeus_data/lucid_data/node/base.rb +15 -0
  38. data/lib/isomorfeus_data/lucid_data/node/mixin.rb +192 -0
  39. data/lib/isomorfeus_data/lucid_data/object/base.rb +13 -0
  40. data/lib/{lucid_array → isomorfeus_data/lucid_data/object}/mixin.rb +15 -16
  41. data/lib/isomorfeus_data/lucid_data/remote_object/base.rb +13 -0
  42. data/lib/isomorfeus_data/lucid_data/remote_object/mixin.rb +19 -0
  43. data/lib/isomorfeus_data/lucid_data/vertex/base.rb +15 -0
  44. data/lib/isomorfeus_data/lucid_data/vertex/mixin.rb +9 -0
  45. data/lib/lucid_arango/collection/base.rb +15 -0
  46. data/lib/lucid_arango/collection/mixin.rb +20 -0
  47. data/lib/lucid_arango/document/base.rb +15 -0
  48. data/lib/lucid_arango/document/mixin.rb +9 -0
  49. data/lib/lucid_arango/edge/base.rb +16 -0
  50. data/lib/lucid_arango/edge/mixin.rb +20 -0
  51. data/lib/lucid_arango/edge_collection/base.rb +15 -0
  52. data/lib/lucid_arango/edge_collection/mixin.rb +20 -0
  53. data/lib/lucid_arango/graph/base.rb +15 -0
  54. data/lib/lucid_arango/graph/mixin.rb +20 -0
  55. data/lib/lucid_arango/node/base.rb +16 -0
  56. data/lib/lucid_arango/node/mixin.rb +81 -0
  57. data/lib/lucid_arango/vertex/base.rb +15 -0
  58. data/lib/lucid_arango/vertex/mixin.rb +9 -0
  59. metadata +84 -47
  60. data/lib/isomorfeus/data/handler/array_load_handler.rb +0 -47
  61. data/lib/isomorfeus/data/handler/collection_load_handler.rb +0 -48
  62. data/lib/isomorfeus/data/handler/graph_load_handler.rb +0 -48
  63. data/lib/isomorfeus/data/handler/hash_load_handler.rb +0 -47
  64. data/lib/lucid_array/base.rb +0 -14
  65. data/lib/lucid_collection/base.rb +0 -14
  66. data/lib/lucid_collection/mixin.rb +0 -241
  67. data/lib/lucid_edge/base.rb +0 -5
  68. data/lib/lucid_edge/mixin.rb +0 -238
  69. data/lib/lucid_graph/base.rb +0 -14
  70. data/lib/lucid_graph/mixin.rb +0 -670
  71. data/lib/lucid_hash/base.rb +0 -14
  72. data/lib/lucid_hash/mixin.rb +0 -168
  73. data/lib/lucid_node/base.rb +0 -5
  74. data/lib/lucid_node/mixin.rb +0 -198
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5625abbd413fd5cf21639fa6d0f582a2f041d23416192efe7b02cff14a887ce
4
- data.tar.gz: 2cdec72d114889ea6e470b1e6dc7dc6d169b158221c5e5cbf242b6f9f431f215
3
+ metadata.gz: 8e3b35be6d60e990ded7a328e4024ed43dd3a23e14d3c5f6827f6d25fb6ffcd9
4
+ data.tar.gz: 8317a70faf17071ebb31bc2f9b6cff9047ae676a56e10ec9cdf5b768078f0abd
5
5
  SHA512:
6
- metadata.gz: 4fd527598a4840d83d5f0d7fa85f00eb03663b6378595d498121a28f395b9dd5f03178127da1379655a4e50f094c019e5e3795c17e4e603b163b3f08c271be1f
7
- data.tar.gz: 82eff7fb7ab7e6fc0572215cbc373f1e824e47711c18772c5135b7b5084da2444c5ffc6b4f32568554b109bd964d05f6caaf82edb4ca87d9d30e542eb580b73f
6
+ metadata.gz: 1480236015fee03d640bde3b30fe3f281e01809ec363c6f4ab8eceef79aa05017da92d6102d8f1d4ee6206576ace07859983d598b5043ee9a6fc77ba479e464f
7
+ data.tar.gz: ff340cfec0e01b915949e95ba10918aca57a8e299c18e822db84f536ceabd8be768a1fe1d4a2e2c631783e9b7657809838f12279a627525c1592ffe4bddc047e
data/README.md CHANGED
@@ -1,3 +1,39 @@
1
1
  # isomorfeus-data
2
2
 
3
- see docs for now
3
+ Data access for Isomorfeus.
4
+
5
+ *Use Ruby for Graphs! ... and more!*
6
+
7
+ ### Community and Support
8
+ At the [Isomorfeus Framework Project](http://isomorfeus.com)
9
+
10
+ ### Overview
11
+
12
+ Isomorfeus Data provides convenient access to all sorts of data for the distributes, isomorphic system.
13
+ Data is available in the same way on clients and server.
14
+
15
+ Isomorfeus Data supports arrays, hashes, collections, graphs, nodes, edges and compositions of any of those which can be loaded with one requests.
16
+
17
+ All LucidData classes are database agnostic. Any ORM or data source supported by ruby can be used.
18
+ Data must then be shaped (usually in to a Hash or Array) to fit the Isomorfeus Data classes.
19
+
20
+
21
+ ### Core Concepts and Common API
22
+
23
+ - [Core Concepts](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/concepts.md)
24
+ - [Common API](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/common_api.md)
25
+
26
+ ### Available Classes
27
+
28
+ All classes follow the common principles and the common API above.
29
+
30
+ - [LucidData::Array](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_array.md) - A array, easily accessible on client and server
31
+ - [LucidData::Collections](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_collection.md) - A collection of LucidData::Node or LucidData::Vertex or LucidData::Document objects
32
+ - [LucidData::Composition](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_composition.md) - A composition of any of those other classes, even graphs, for easy, one request access to arbitrary data
33
+ - [LucidData::Document, LucidData::Node, LucidData::Vertex](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_node.md) - A node/document/vertex, can be used stand alone, in a collection or in a graph
34
+ - [LucidData::Edge, LucidData::Link](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_edge.md) - A edge/link, can be used standalone, in a collection or in a graph
35
+ - [LucidData::EdgeCollection, LucidData::LinkCollection](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_edge_collection.md) - A collection of LucidData::Edge or LucidData::Link objects
36
+ - [LucidData::Graph](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_graph.md) - A graph, which can be build from several LucidData::Collection objects and LucidData::EdgeCollection objects
37
+ - [LucidData::Hash](https://github.com/isomorfeus/isomorfeus-framework/blob/master/ruby/isomorfeus-data/docs/data_hash.md) - A hash, easily accessible on client and server
38
+
39
+ (more to come soon)
@@ -0,0 +1,122 @@
1
+ module Isomorfeus
2
+ module Data
3
+ module AttributeSupport
4
+ def self.included(base)
5
+ base.instance_exec do
6
+ def attribute_conditions
7
+ @attribute_conditions ||= {}
8
+ end
9
+
10
+ def valid_attribute?(attr_name, attr_value)
11
+ Isomorfeus::Props::Validator.new(self.name, attr_name, attr_value, attribute_conditions[attr_name]).validate!
12
+ rescue
13
+ false
14
+ end
15
+
16
+ def validate
17
+ Isomorfeus::Props::ValidateHashProxy.new
18
+ end
19
+ end
20
+
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!
24
+ end
25
+
26
+ def exclude_attributes(*attrs)
27
+ @_excluded_attributes = attrs
28
+ end
29
+
30
+ def select_attributes(*attrs)
31
+ @_selected_attributes = attrs
32
+ end
33
+
34
+ if RUBY_ENGINE == 'opal'
35
+ base.instance_exec do
36
+ def attribute(name, options = {})
37
+ attribute_conditions[name] = options
38
+
39
+ define_method(name) do
40
+ _get_attribute(name)
41
+ end
42
+
43
+ define_method("#{name}=") do |val|
44
+ _validate_attribute(name, val)
45
+ changed!
46
+ @_changed_attributes[name] = val
47
+ end
48
+ end
49
+ end
50
+
51
+ def _get_attribute(name)
52
+ return @_changed_attributes[name] if @_changed_attributes.key?(name)
53
+ path = @_store_path + [name]
54
+ result = Redux.fetch_by_path(*path)
55
+ return nil if `result === null`
56
+ result
57
+ end
58
+
59
+ def _get_attributes
60
+ raw_attributes = Redux.fetch_by_path(*@_store_path)
61
+ hash = Hash.new(raw_attributes)
62
+ hash.merge!(@_changed_attributes) if @_changed_attributes
63
+ hash
64
+ end
65
+
66
+ def _get_selected_attributes
67
+ attributes = _get_attributes.dup
68
+ if @_selected_attributes && !@_selected_attributes.empty?
69
+ attributes.each_key do |attr|
70
+ unless @_selected_attributes.include?(attr) || @_selected_attributes.include?(attr)
71
+ attributes.delete(attr)
72
+ end
73
+ end
74
+ end
75
+ if @_excluded_attributes && !@_excluded_attributes.empty?
76
+ @_excluded_attributes.each { |attr| attributes.delete(attr) }
77
+ end
78
+ attributes
79
+ end
80
+ else
81
+ base.instance_exec do
82
+ def attribute(name, options = {})
83
+ attribute_conditions[name] = options
84
+
85
+ define_method(name) do
86
+ @_raw_attributes[name]
87
+ end
88
+
89
+ define_method("#{name}=") do |val|
90
+ _validate_attribute(name, val)
91
+ changed!
92
+ @_raw_attributes[name] = val
93
+ end
94
+ end
95
+ end
96
+
97
+ def _get_attributes
98
+ @_raw_attributes
99
+ end
100
+
101
+ def _get_selected_attributes
102
+ attributes = _get_attributes.transform_keys(&:to_s)
103
+ self.class.attribute_conditions.each do |attr, options|
104
+ attributes.delete(attr.to_s) if options[:server_only]
105
+ end
106
+ if @_selected_attributes && !@_selected_attributes.empty?
107
+ attributes.each_key do |attr|
108
+ unless @_selected_attributes.include?(attr.to_sym) || @_selected_attributes.include?(attr)
109
+ attributes.delete(attr)
110
+ end
111
+ end
112
+ end
113
+ if @_excluded_attributes && !@_excluded_attributes.empty?
114
+ @_excluded_attributes.each { |attr| attributes.delete(attr.to_s) }
115
+ end
116
+ attributes
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,116 +1,106 @@
1
1
  module Isomorfeus
2
2
  # available settings
3
3
  class << self
4
- def cached_array_classes
5
- @cached_array_classes ||= {}
4
+ def instance_from_sid(sid)
5
+ data_class = cached_data_class(sid[0])
6
+ data_class.new(key: sid[1])
6
7
  end
7
8
 
8
- def cached_array_class(class_name)
9
- return cached_array_classes[class_name] if cached_array_classes.key?(class_name)
10
- cached_array_classes[class_name] = "::#{class_name}".constantize
11
- end
12
-
13
- def cached_collection_classes
14
- @cached_collection_classes ||= {}
15
- end
16
-
17
- def cached_collection_class(class_name)
18
- return cached_collection_classes[class_name] if cached_collection_classes.key?(class_name)
19
- cached_collection_classes[class_name] = "::#{class_name}".constantize
20
- end
21
-
22
- def cached_edge_classes
23
- @cached_edge_classes ||= {}
24
- end
25
-
26
- def cached_edge_class(class_name)
27
- return cached_edge_classes[class_name] if cached_edge_classes.key?(class_name)
28
- cached_edge_classes[class_name] = "::#{class_name}".constantize
29
- end
30
-
31
- def cached_graph_classes
32
- @cached_graph_classes ||= {}
33
- end
34
-
35
- def cached_graph_class(class_name)
36
- return cached_graph_classes[class_name] if cached_graph_classes.key?(class_name)
37
- cached_graph_classes[class_name] = "::#{class_name}".constantize
38
- end
39
-
40
- def cached_hash_classes
41
- @cached_hash_classes ||= {}
42
- end
43
-
44
- def cached_hash_class(class_name)
45
- return cached_hash_classes[class_name] if cached_hash_classes.key?(class_name)
46
- cached_hash_classes[class_name] = "::#{class_name}".constantize
47
- end
48
-
49
- def cached_node_classes
50
- @cached_node_classes ||= {}
51
- end
52
-
53
- def cached_node_class(class_name)
54
- return cached_node_classes[class_name] if cached_node_classes.key?(class_name)
55
- cached_node_classes[class_name] = "::#{class_name}".constantize
56
- end
57
-
58
- if RUBY_ENGINE != 'opal'
59
- def valid_array_class_names
60
- @valid_array_class_names ||= Set.new
61
- end
62
-
63
- def valid_array_class_name?(class_name)
64
- valid_array_class_names.include?(class_name)
9
+ if RUBY_ENGINE == 'opal'
10
+ def cached_data_classes
11
+ @cached_data_classes ||= `{}`
65
12
  end
66
13
 
67
- def add_valid_array_class(klass)
68
- class_name = klass.name
69
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
70
- valid_array_class_names << class_name
14
+ def cached_data_class(class_name)
15
+ return "::#{class_name}".constantize if Isomorfeus.development?
16
+ return cached_data_classes.JS[class_name] if cached_data_classes.JS[class_name]
17
+ cached_data_classes.JS[class_name] = "::#{class_name}".constantize
71
18
  end
72
-
73
- def valid_collection_class_names
74
- @valid_collection_class_names ||= Set.new
19
+ else
20
+ def cached_data_classes
21
+ @cached_data_classes ||= {}
75
22
  end
76
23
 
77
- def valid_collection_class_name?(class_name)
78
- valid_collection_class_names.include?(class_name)
24
+ def cached_data_class(class_name)
25
+ return "::#{class_name}".constantize if Isomorfeus.development?
26
+ return cached_data_classes[class_name] if cached_data_classes.key?(class_name)
27
+ cached_data_classes[class_name] = "::#{class_name}".constantize
79
28
  end
80
29
 
81
- def add_valid_collection_class(klass)
82
- class_name = klass.name
83
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
84
- valid_collection_class_names << class_name
30
+ def valid_data_classes
31
+ @valid_data_classes ||= {}
85
32
  end
86
33
 
87
- def valid_graph_class_names
88
- @valid_graph_class_names ||= Set.new
34
+ def valid_data_class_name?(class_name)
35
+ valid_data_classes.key?(class_name)
89
36
  end
90
37
 
91
- def valid_graph_class_name?(class_name)
92
- valid_graph_class_names.include?(class_name)
38
+ def add_valid_data_class(klass)
39
+ valid_data_classes[raw_class_name(klass)] = true
93
40
  end
94
41
 
95
- def add_valid_graph_class(klass)
96
- class_name = klass.name
97
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
98
- valid_graph_class_names << class_name
42
+ def connect_to_arango
43
+ arango_options = if Isomorfeus.production? then Isomorfeus.arango_production
44
+ elsif Isomorfeus.development? then Isomorfeus.arango_development
45
+ elsif Isomorfeus.test? then Isomorfeus.arango_test
46
+ end
47
+ arango_options = {}.merge(arango_options)
48
+ database = arango_options.delete(:database)
49
+ Arango.connect_to(**arango_options)
50
+ begin
51
+ Arango.current_server.get_database(database)
52
+ rescue Exception => e
53
+ raise "Can't connect to database '#{database}' (#{e.message})."
54
+ end
99
55
  end
100
56
 
101
- def valid_hash_class_names
102
- @valid_hash_class_names ||= Set.new
57
+ def prepare_arango_database
58
+ #arango_options = if Isomorfeus.production? then Isomorfeus.arango_production
59
+ # elsif Isomorfeus.development? then Isomorfeus.arango_development
60
+ # elsif Isomorfeus.test? then Isomorfeus.arango_test
61
+ # end
62
+ #arango_options = {}.merge(arango_options)
63
+ #database = arango_options.delete(:database)
64
+ #Arango.connect_to(**arango_options)
65
+ #db = nil
66
+ #begin
67
+ # opened_db = Arango.current_server.get_database(database)
68
+ # db = opened_db.name
69
+ #rescue Exception => e
70
+ # db = nil
71
+ # unless e.message.include?('database not found')
72
+ # raise "Can't check if database '#{database}' exists."
73
+ # end
74
+ #end
75
+ #unless db
76
+ # begin
77
+ # Arango.current_server.create_database(database)
78
+ # rescue Exception => e
79
+ # raise "Can't create database '#{database}' (#{e.message}).\nPlease make sure database '#{database}' exists."
80
+ # end
81
+ # begin
82
+ # Arango.current_server.get_database(database)
83
+ # rescue Exception => e
84
+ # raise "Can't connect to database '#{database}' (#{e.message})."
85
+ # end
86
+ #end
87
+ #
88
+ #Arango.current_server.install_opal_module(database)
89
+ #unless Arango.current_database.collection_exist?('IsomorfeusSessions')
90
+ # Arango.current_database.create_collection('IsomorfeusSessions')
91
+ #end
92
+ #unless Arango.current_database.collection_exist?('IsomorfeusObjectStore')
93
+ # Arango.current_database.create_collection('IsomorfeusObjectStore')
94
+ #end
103
95
  end
104
96
 
105
- def valid_hash_class_name?(class_name)
106
- valid_hash_class_names.include?(class_name)
97
+ def arango_configured?
98
+ !!(Isomorfeus.arango_production && Isomorfeus.arango_development && Isomorfeus.arango_test)
107
99
  end
108
100
 
109
- def add_valid_hash_class(klass)
110
- class_name = klass.name
111
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
112
- valid_hash_class_names << class_name
113
- end
101
+ attr_accessor :arango_production
102
+ attr_accessor :arango_development
103
+ attr_accessor :arango_test
114
104
  end
115
105
  end
116
106
  end
@@ -0,0 +1,133 @@
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
+ raise "#{@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
+ raise "#{@c}: #{@p} class not #{@o[:class]}" unless @e.class == @o[:class]
57
+ elsif @o.key?(:is_a)
58
+ raise "#{@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
+ raise "#{@c}: #{@p} is not a boolean" unless @e.class == TrueClass || @e.class == FalseClass
63
+ end
64
+ end
65
+ end
66
+
67
+ # all other checks
68
+
69
+ def run_checks!
70
+ if @o.key?(:validate)
71
+ @o[:validate].each do |m, l|
72
+ send('c_' + m, l)
73
+ end
74
+ end
75
+ end
76
+
77
+ # specific validations
78
+ def c_gt(v)
79
+ raise "#{@c}: #{@p} not greater than #{v}!" unless @e > v
80
+ end
81
+
82
+ def c_lt(v)
83
+ raise "#{@c}: #{@p} not less than #{v}!" unless @e < v
84
+ end
85
+
86
+ def c_keys(v)
87
+ raise "#{@c}: #{@p} keys dont fit!" unless @e.keys.sort == v.sort
88
+ end
89
+
90
+ def c_size(v)
91
+ raise "#{@c}: #{@p} length/size is not #{v}" unless @e.size == v
92
+ end
93
+
94
+ def c_matches(v)
95
+ raise "#{@c}: #{@p} does not match #{v}" unless v.match?(@e)
96
+ end
97
+
98
+ def c_max(v)
99
+ raise "#{@c}: #{@p} is larger than #{v}" unless @e <= v
100
+ end
101
+
102
+ def c_min(v)
103
+ raise "#{@c}: #{@p} is smaller than #{v}" unless @e >= v
104
+ end
105
+
106
+ def c_max_size(v)
107
+ raise "#{@c}: #{@p} is larger than #{v}" unless @e.size <= v
108
+ end
109
+
110
+ def c_min_size(v)
111
+ raise "#{@c}: #{@p} is smaller than #{v}" unless @e.size >= v
112
+ end
113
+
114
+ def c_direction(v)
115
+ raise "#{@c}: #{@p} is positive" if v == :negative && @e >= 0
116
+ raise "#{@c}: #{@p} is negative" if v == :positive && @e < 0
117
+ end
118
+
119
+ def c_test
120
+ raise "#{@c}: #{@p} test condition check failed" unless @o[:test].call(@e)
121
+ end
122
+
123
+ def c_sub_type(v)
124
+ case v
125
+ when :email
126
+ # TODO
127
+ when :url
128
+ # TODO
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,155 @@
1
+ module Isomorfeus
2
+ module Data
3
+ module GenericClassApi
4
+ if RUBY_ENGINE == 'opal'
5
+ def create(key:, **things)
6
+ instance = new(key: key, **things)
7
+ instance.promise_save
8
+ instance
9
+ end
10
+
11
+ def promise_create(key:, **things)
12
+ new(key: key, **things).promise_save
13
+ end
14
+
15
+ def destroy(key:)
16
+ promise_destroy(key: key)
17
+ true
18
+ end
19
+
20
+ def promise_destroy(key:)
21
+ Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :destroy, key: key).then do |agent|
22
+ if agent.processed
23
+ agent.result
24
+ else
25
+ agent.processed = true
26
+ if agent.response.key?(:error)
27
+ `console.error(#{agent.response[:error].to_n})`
28
+ raise agent.response[:error]
29
+ end
30
+ Isomorfeus.store.dispatch(type: 'DATA_DESTROY', data: agent.full_response[:data])
31
+ agent.result = true
32
+ end
33
+ end
34
+ end
35
+
36
+ def load(key:)
37
+ instance = self.new(key: key)
38
+ self.promise_load(key: key, instance: instance) unless instance.loaded?
39
+ instance
40
+ end
41
+
42
+ def promise_load(key:, instance: nil)
43
+ instance = self.new(key: key) unless instance
44
+ Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :load, key: key).then do |agent|
45
+ if agent.processed
46
+ agent.result
47
+ else
48
+ agent.processed = true
49
+ if agent.response.key?(:error)
50
+ `console.error(#{agent.response[:error].to_n})`
51
+ raise agent.response[:error]
52
+ end
53
+ instance._load_from_store!
54
+ Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.full_response[:data])
55
+ agent.result = instance
56
+ end
57
+ end
58
+ end
59
+
60
+ def promise_query(props = {})
61
+ validate_props(props)
62
+ props_json = props.to_json
63
+ instance = self.new(key) unless instance
64
+ Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, 'query', props_json).then do |agent|
65
+ if agent.processed
66
+ agent.result
67
+ else
68
+ agent.processed = true
69
+ if agent.response.key?(:error)
70
+ `console.error(#{agent.response[:error].to_n})`
71
+ raise agent.response[:error]
72
+ end
73
+ Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.full_response[:data])
74
+ agent.result = instance
75
+ end
76
+ end
77
+ end
78
+
79
+ # execute
80
+ def execute_destroy(_); end
81
+ def execute_load(_); end
82
+ def execute_query(_); end
83
+ def execute_save(_); end
84
+
85
+ # callbacks
86
+ def on_destroy(_); end
87
+ def on_load(_); end
88
+ def on_query(_); end
89
+ def on_save(_); end
90
+ else
91
+ def promise_create(key:, **things)
92
+ instance = self.create(key: key, **things)
93
+ result_promise = Promise.new
94
+ result_promise.resolve(instance)
95
+ result_promise
96
+ end
97
+
98
+ def promise_destroy(key:)
99
+ self.destroy(key: key)
100
+ result_promise = Promise.new
101
+ result_promise.resolve(true)
102
+ result_promise
103
+ end
104
+
105
+ def promise_load(key:)
106
+ instance = self.load(key: key)
107
+ result_promise = Promise.new
108
+ result_promise.resolve(instance)
109
+ result_promise
110
+ end
111
+
112
+ def promise_query(props)
113
+ instance = self.query(props)
114
+ result_promise = Promise.new
115
+ result_promise.resolve(instance)
116
+ result_promise
117
+ end
118
+
119
+ # execute
120
+ def execute_destroy(&block)
121
+ @_destroy_block = block
122
+ end
123
+
124
+ def execute_load(&block)
125
+ @_load_block = block
126
+ end
127
+
128
+ def execute_query(&block)
129
+ @_query_block = block
130
+ end
131
+
132
+ def execute_save(&block)
133
+ @_save_block = block
134
+ end
135
+
136
+ # callbacks
137
+ def on_destroy(&block)
138
+ @_on_destroy_block = block
139
+ end
140
+
141
+ def on_load(&block)
142
+ @_on_load_block = block
143
+ end
144
+
145
+ def on_query(&block)
146
+ @_on_query_block = block
147
+ end
148
+
149
+ def on_save(&block)
150
+ @_on_save_block = block
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end