activegraph-extensions 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9c33fee6eede1db2664a17ae82a9f7dcb0d3611b2665605a024fd184a2695fa9
4
+ data.tar.gz: ea57d1a76c541d3b5c8c655f1b4cea22142917c83500a2275f4f2fc177f120af
5
+ SHA512:
6
+ metadata.gz: dc88d9b5d715d803ede073cfd97f60bdbb4b1efe93231416a95ba3963d5831af872bf7e55e53906061693009f9e052e725dea8e80bd8a1a5e44864221659b4ad
7
+ data.tar.gz: d0b79494bac58f25b9c972951c7bce4d27beb33c5bdcbf865905a81401375b344ab9b9cb101360e93aa1db9bfcc14015ecc1b7a853623e90f9a6a7ca59ff67a0
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ # Change Log
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'listen', '< 3.1'
6
+ active_model_version = ENV['ACTIVE_MODEL_VERSION']
7
+ gem 'activemodel', "~> #{active_model_version}" if active_model_version&.length&.positive?
8
+
9
+ #gem 'zeitwerk'
10
+
11
+ group :test do
12
+ gem 'coveralls', require: false
13
+ gem 'overcommit'
14
+ gem 'codecov', require: false
15
+ gem 'simplecov', require: false
16
+ gem 'simplecov-html', require: false
17
+ gem 'its'
18
+ gem 'test-unit'
19
+ gem 'colored'
20
+ gem 'dotenv'
21
+ gem 'timecop'
22
+ gem 'pry'
23
+ gem 'activegraph'
24
+ end
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # Extensions to activegraph gem.
@@ -0,0 +1,45 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'active_graph_extensions/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'activegraph-extensions'
8
+ s.version = ActiveGraphExtensions::VERSION
9
+
10
+ s.required_ruby_version = '>= 2.5'
11
+
12
+ s.authors = 'Amit Suryavanshi'
13
+ s.email = 'amitbsuryavabshi@mail.com'
14
+ s.homepage = 'https://github.com/neo4jrb/activegraph-extensions/'
15
+ s.summary = 'Additional features to activegraph'
16
+ s.license = 'MIT'
17
+ s.description = <<-DESCRIPTION
18
+ Additional features to activegraph, like sideload limiting, authorizing sideloads etc.
19
+ DESCRIPTION
20
+
21
+ s.require_path = 'lib'
22
+ s.files = Dir.glob('{bin,lib,config}/**/*') + %w(README.md CHANGELOG.md Gemfile activegraph-extensions.gemspec)
23
+ s.executables = []
24
+ s.extra_rdoc_files = %w( README.md )
25
+ s.rdoc_options = ['--quiet', '--title', 'Neo4j.rb', '--line-numbers', '--main', 'README.rdoc', '--inline-source']
26
+
27
+ s.platform = 'java'
28
+
29
+ s.add_dependency('parslet')
30
+ s.add_dependency('activegraph')
31
+
32
+ s.add_development_dependency('guard')
33
+ s.add_development_dependency('guard-rspec')
34
+ s.add_development_dependency('guard-rubocop')
35
+ s.add_development_dependency('neo4j-rake_tasks', '>= 0.3.0')
36
+ # s.add_development_dependency("neo4j-#{ENV['driver'] == 'java' ? 'java' : 'ruby'}-driver", '~> 4.1.0.beta.1')
37
+ s.add_development_dependency('os')
38
+ s.add_development_dependency('pry')
39
+ s.add_development_dependency('railties', '>= 4.0')
40
+ s.add_development_dependency('rake')
41
+ s.add_development_dependency('rubocop', '>= 0.56.0')
42
+ s.add_development_dependency('yard')
43
+ s.add_development_dependency('dryspec')
44
+ s.add_development_dependency('rspec', '< 3.10') # Cannot proxy frozen objects
45
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ # We need earlier proxy to generate cypher in query proxy eagerloading
7
+ module QueryProxy
8
+ def branch(&block)
9
+ proxy = super
10
+ proxy.instance_variable_set(:@break_proxy, as(identity).instance_eval(&block))
11
+ proxy
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ module QueryProxyEagerLoading
7
+ # Used for eager loading associations with scope
8
+ module AssociationEagerLoad
9
+ extend ActiveSupport::Concern
10
+
11
+ class_methods do
12
+ def associations_to_eagerload
13
+ @associations_to_eagerload
14
+ end
15
+
16
+ def association_nodes(key, ids, filter)
17
+ send(@associations_to_eagerload[key], ids, filter)
18
+ end
19
+
20
+ def eagerload_associations(config)
21
+ @associations_to_eagerload = config
22
+ end
23
+
24
+ def eagerload_association?(key)
25
+ @associations_to_eagerload.keys.include?(key)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ module QueryProxyEagerLoading
7
+ module AssociationLimiting
8
+ def self.included(base)
9
+ base.attr_reader(:default_assoc_limit)
10
+ end
11
+
12
+ private
13
+
14
+ def rel_collection_str(path)
15
+ limit = association_limit(path)
16
+ collection_name = "[#{relationship_name(path)}, #{escape(path_name(path))}] "
17
+ collection = limit.present? ? "apoc.agg.slice(#{collection_name}, 0, #{limit})" : "collect(#{collection_name})"
18
+ "#{collection} AS #{escape("#{path_name(path)}_collection")}"
19
+ end
20
+
21
+ def relationship_name(path)
22
+ if path.last.rel_length
23
+ "last(relationships(#{escape("#{path_name(path)}_path")}))"
24
+ else
25
+ escape("#{path_name(path)}_rel")
26
+ end
27
+
28
+ end
29
+
30
+ def convert_to_list(collection_name, limit)
31
+ limit.present? ? "apoc.agg.slice(#{collection_name}, 0, #{limit})" : "collect(#{collection_name})"
32
+ end
33
+
34
+ def association_limit(path)
35
+ return if multipath?(path)
36
+
37
+ limit = path.last&.association_limit
38
+ limit.blank? || limit.to_i > default_assoc_limit ? default_assoc_limit : limit
39
+ end
40
+
41
+ def with_association_query_part(base_query, path, previous_with_vars)
42
+ with_args = [identity, rel_collection_str(path), *previous_with_vars]
43
+
44
+ optional_match_with_where(base_query, path, previous_with_vars).with(with_args)
45
+ end
46
+
47
+ def limit_node_in_where_clause(query, path)
48
+ root_path = path[0..0]
49
+ query.where("`#{path_name(root_path)}` in [i IN #{node_from_collection(root_path)} | i[1]]")
50
+ end
51
+
52
+ def node_from_collection(path_step)
53
+ "`#{path_name(path_step)}_collection`"
54
+ end
55
+
56
+ def path_alias(node_alias)
57
+ var_fix(node_alias, :path)
58
+ end
59
+
60
+ def rel_alias(node_alias)
61
+ var_fix(node_alias, :rel)
62
+ end
63
+
64
+ def multipath?(path)
65
+ path.size > 1
66
+ end
67
+
68
+ def association_limit_present?(path)
69
+ association_limit(path).present?
70
+ end
71
+
72
+ def multipath_with_sideload_limit?(path)
73
+ multipath?(path) && association_limit_present?(path[0..0])
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ module QueryProxyEagerLoading
7
+ # Used to append auth scopes to query proxy eagerloading
8
+ module EagerLoadingOrder
9
+ def optional_order(query, path, previous_with_vars)
10
+ node_alias = path_name(path)
11
+ order_clause = order_clause_for_query(node_alias)
12
+ if path.last.rel_length
13
+ order_clause.reject! { |el| el.include?('_rel') }
14
+ query.order("length(`#{node_alias}_path`)", *order_clause)
15
+ .with(*with_variables(path, node_alias, previous_with_vars))
16
+ else
17
+ query.order(*order_clause).with(*with_variables(path, node_alias, previous_with_vars))
18
+ end
19
+ end
20
+
21
+ def order_clause_for_query(node_alias)
22
+ (order = @order_spec&.fetch(node_alias, nil)) ? order.map(&method(:nested_order_clause).curry.call(node_alias)) : []
23
+ end
24
+
25
+ def nested_order_clause(node_alias, order_spec)
26
+ [node_or_rel_alias(node_alias, order_spec), name(order_spec)].join('.')
27
+ end
28
+
29
+ def order_clause(key, order_spec)
30
+ property_with_direction = name(order_spec)
31
+ node_alias = node_aliase_for_collection(key, order_spec) || node_aliase_for_order(property_with_direction)
32
+ [node_alias, property_with_direction].compact.join('.')
33
+ end
34
+
35
+ def skip_order?
36
+ @order_spec.blank? || @order_spec.keys.all?(&:blank?)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ module QueryProxyEagerLoading
7
+ # Tree allowing storage of additional information about the associations
8
+ class EnhancedTree < ::ActiveGraph::Node::Query::QueryProxyEagerLoading::AssociationTree
9
+ attr_reader :options, :association_limit
10
+
11
+ def initialize(model, name = nil, rel_length = nil, association_limit = nil)
12
+ @association_limit = association_limit
13
+ super(model, name, rel_length)
14
+ end
15
+
16
+ def add_spec_and_validate(spec)
17
+ add_spec(spec)
18
+ validate_for_zero_length_paths
19
+ end
20
+
21
+ def validate_for_zero_length_paths
22
+ fail 'Can not eager load more than one zero length path.' if values.count(&:zero_length_path?) > 1
23
+ end
24
+
25
+ def zero_length_path?
26
+ rel_length&.fetch(:min, nil)&.to_s == '0' || values.any?(&:zero_length_path?)
27
+ end
28
+
29
+ def add_key(key, length = nil, assoc_limit = nil)
30
+ self[key] ||= self.class.new(model, key, length, assoc_limit)
31
+ end
32
+
33
+ def add_nested(key, value, length = nil, assoc_limit = nil)
34
+ add_key(key, length, assoc_limit).add_spec(value)
35
+ end
36
+
37
+ def process_string(str)
38
+ # head, rest = str.split('.', 2)
39
+ # head, association_limit = extract_assoc_limit(head)
40
+ # k, length = head.split('*', -2)
41
+ # length = { max: length } if length
42
+ #add_nested(k.to_sym, rest, length, association_limit)
43
+ map = StringParsers::RelationParser.new.parse(str)
44
+ add_nested(map[:rel_name].to_sym, map[:rest_str].to_s.presence, map[:length_part], map[:limit_digit])
45
+ end
46
+
47
+ # def extract_assoc_limit(str)
48
+ # transformer = StringParsers::RelationParamTransformer.new(str)
49
+ # [transformer.rel_name_n_length, transformer.rel_limit_number]
50
+ # end
51
+
52
+ def process_hash(spec)
53
+ spec = spec.dup
54
+ @options = spec.delete(:_options)
55
+ super(spec)
56
+ end
57
+
58
+ def target_class(model, key)
59
+ association = model.associations[key.to_sym]
60
+ fail "Invalid association: #{[*path, key].join('.')}" unless association
61
+ model.associations[key].target_class
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ module QueryProxyEagerLoading
7
+ # Used to append auth scopes to query proxy eagerloading
8
+ module ScopeEagerLoading
9
+ def authorized_rel(path, var)
10
+ rel_model = relationship_model(path)
11
+ return {} if @opts.blank? || !(auth_scope = authorized_scope(rel_model, path))
12
+ conf = { rels: [], chain: {} }
13
+ proxy = auth_scope.call(var, "#{var}_rel", user: @opts[:user],
14
+ properties: properties_for(rel_model),
15
+ privileges: @opts[:privileges],
16
+ rel_length: path.last.rel_length)
17
+ proxy_rel_parts(proxy.instance_variable_get(:@break_proxy) || proxy, conf)
18
+ conf
19
+ end
20
+
21
+ def properties_for(rel_model)
22
+ return [] unless @opts[:properties]
23
+ @opts[:properties].select { |prop| prop.model.name == rel_model.name }.map(&:name)
24
+ end
25
+
26
+ def relationship_model(path)
27
+ path[0..-2].inject(model) { |mod, rel| mod.send(rel.name).model }
28
+ end
29
+
30
+ def authorized_scope(rel_model, path)
31
+ rel_model.scopes["authorized_#{path.last.association.name}".to_sym]
32
+ end
33
+
34
+ def proxy_rel_parts(auth_proxy, conf)
35
+ return unless auth_proxy&.association
36
+ rel_length = auth_proxy.instance_variable_get(:@rel_length)
37
+ conf[:rels] << relationship_part(auth_proxy.association, auth_proxy.identity, rel_length)
38
+ assign_config_chain(conf, auth_proxy, rel_length)
39
+ proxy_rel_parts(auth_proxy.query_proxy, conf)
40
+ end
41
+
42
+ def assign_config_chain(conf, auth_proxy, rel_length)
43
+ return unless (auth_chain = auth_proxy.instance_variable_get(:@chain))
44
+ conf[:chain][[auth_proxy.identity, rel_length ? "#{auth_proxy.identity}_rel" : nil]] = auth_chain
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,148 @@
1
+ module ActiveGraphExtensions
2
+ module Node
3
+ module Query
4
+ module QueryProxyEagerLoading
5
+ extend ActiveSupport::Concern
6
+ include AssociationLimiting
7
+ include ScopeEagerLoading
8
+ include EagerLoadingOrder
9
+
10
+ def association_tree_class
11
+ EnhancedTree
12
+ end
13
+
14
+ def with_ordered_associations(spec, order, opts = {})
15
+ @default_assoc_limit = opts[:default_assoc_limit]
16
+ @with_vars = opts[:with_vars]
17
+ @order_spec = order.with_indifferent_access unless spec.empty?
18
+ @opts = opts
19
+ with_associations(spec)
20
+ end
21
+
22
+ def first
23
+ limit(1).to_a.first
24
+ end
25
+
26
+ class_methods do
27
+ def rel?(order_spec)
28
+ order_spec.is_a?(Hash) ? 0 : 1
29
+ end
30
+ end
31
+
32
+ def with_associations(*spec)
33
+ new_link.tap do |new_query_proxy|
34
+ new_query_proxy.with_associations_tree = with_associations_tree.clone
35
+ new_query_proxy.with_associations_tree.add_spec_and_validate(spec)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def query_from_association_tree
42
+ previous_with_vars = defalut_previous_with_vars
43
+ with_associations_tree.paths.inject(query_as(identity).with(base_query_with_vars)) do |query, path|
44
+ with_association_query_part(query, path, previous_with_vars).tap do
45
+ previous_with_vars << var_fix(path_name(path), :collection)
46
+ end
47
+ end
48
+ end
49
+
50
+ def defalut_previous_with_vars
51
+ @with_vars&.dup || []
52
+ end
53
+
54
+ def base_query_with_vars
55
+ [ensure_distinct(identity)] + (@with_vars || [])
56
+ end
57
+
58
+ def optional_match_with_where(query, path, vars)
59
+ computed_query = super
60
+ computed_query = limit_node_in_where_clause(computed_query, path) if multipath_with_sideload_limit?(path)
61
+ skip_order? && !path.last.rel_length ? computed_query : optional_order(computed_query, path, vars)
62
+ end
63
+
64
+ def optional_match(base_query, path)
65
+ start_path = "#{escape("#{path_name(path)}_path")}=(#{identity})"
66
+ conf = authorized_rel(path, path_name(path[0..-1]))
67
+ query = construct_optional_match(start_path, base_query, conf[:rels] ? path[0..-2] : path, conf[:rels])
68
+ conf[:rels] ? apply_chain(conf[:chain], query) : query
69
+ end
70
+
71
+ def construct_optional_match(start_path, base_query, path, scope_rels)
72
+ base_query.optional_match(
73
+ "#{start_path}#{path.each_with_index.map do |element, index|
74
+ relationship_part(element.association, path_name(path[0..index]), element.rel_length)
75
+ end.join}#{(scope_rels || []).reverse.join}"
76
+ )
77
+ end
78
+
79
+ def apply_chain(chain, query)
80
+ chain.each do |key, links|
81
+ query = links.inject(query) do |q, link|
82
+ args = link.args(*key)
83
+ args.is_a?(Array) ? q.send(link.clause, *args) : q.send(link.clause, args)
84
+ end
85
+ end
86
+ query
87
+ end
88
+
89
+ def with_variables(path, node_alias, previous_with_vars)
90
+ [identity, path.last.rel_length ? path_alias(node_alias) : rel_alias(node_alias), var_fix(node_alias)] +
91
+ previous_with_vars
92
+ end
93
+
94
+ def before_pluck(query)
95
+ return query if skip_order? && !include_with_path_length?
96
+ base_query = query.order(
97
+ (@order_spec || []).flat_map { |key, order_specs| order_specs.map(&method(:order_clause).curry.call(key)) }
98
+ )
99
+ query_from_chain(@postponed_chain, base_query, identity)
100
+ end
101
+
102
+ def node_aliase_for_collection(key, order_spec)
103
+ "#{var(key, :collection, &:itself)}[0][#{self.class.rel?(order_spec)}]" if key.present?
104
+ end
105
+
106
+ def node_aliase_for_order(property_with_direction)
107
+ identity unless @with_vars&.include?(property_with_direction.split(' ').first.to_sym)
108
+ end
109
+
110
+ def name(order_spec)
111
+ Array(order_spec).flatten.last.to_s
112
+ end
113
+
114
+ def node_or_rel_alias(node_alias, order_spec)
115
+ var(node_alias, order_spec.is_a?(Hash) ? :rel : nil, &:itself)
116
+ end
117
+
118
+ CLAUSES_TO_POSTPONE = %i[limit order skip].freeze
119
+
120
+ def include_with_path_length?(path = @with_associations_tree)
121
+ path.present? && (path.rel_length.present? || path.any? { |_, val| include_with_path_length?(val) })
122
+ end
123
+
124
+ def chain
125
+ return super if skip_order? && !include_with_path_length?
126
+ clauses = !skip_order? ? CLAUSES_TO_POSTPONE : %i[order]
127
+ @postponed_chain, other_chain = super.partition { |link| clauses.include?(link.clause) }
128
+ other_chain
129
+ end
130
+
131
+ def perform_query
132
+ @_cache = ActiveGraph::Node::Query::QueryProxyEagerLoading::IdentityMap.new
133
+ build_query
134
+ .map do |record, eager_data|
135
+ record = cache_and_init(record, with_associations_tree)
136
+ eager_data.zip(with_associations_tree.paths.map(&:last)).each do |eager_records, element|
137
+ eager_records.each do |eager_record|
138
+ next unless eager_record.first&.type&.to_s == element.association.relationship_type.to_s
139
+ add_to_cache(*eager_record, element)
140
+ end
141
+ end
142
+ record
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ module Query
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module Node
5
+ end
6
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module StringParsers
5
+ # Parsing relationships with length
6
+ class RelationParser < ::Parslet::Parser
7
+ rule(:asterix) { str('*') }
8
+ rule(:digit) { match('[\d]').repeat }
9
+ rule(:range) { str('..') }
10
+ rule(:dot) { str('.') }
11
+ rule(:zero) { str('0') }
12
+ rule(:length_1) { zero.as(:min) >> range >> digit.maybe.as(:max) }
13
+ rule(:length_2) { digit.maybe.as(:max) }
14
+ rule(:length) { asterix >> (length_1 | length_2) }
15
+ rule(:rel) { match('[a-z,_]').repeat.as(:rel_name) }
16
+ rule(:limit) { digit.as(:limit_digit) >> asterix }
17
+ rule(:key) { limit.maybe >> rel >> length.as(:length_part).maybe }
18
+ rule(:anything) { match('.').repeat }
19
+ rule(:root) { key >> dot.maybe >> anything.maybe.as(:rest_str) }
20
+
21
+ rule(:rel_sequence) { infix_expression(key, [dot, 1, :left]) }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveGraphExtensions
4
+ module StringParsers
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveGraphExtensions
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_graph'
2
+ require 'parslet'
3
+
4
+ module ActiveGraphExtensions
5
+ end
6
+
7
+ loader = Zeitwerk::Loader.for_gem
8
+ loader.inflector.inflect 'version' => 'VERSION'
9
+ loader.ignore(File.expand_path('activegraph-extensions.rb', __dir__))
10
+ loader.setup
11
+
12
+ ActiveGraph::Node::Query::QueryProxy.include ActiveGraphExtensions::Node::Query::QueryProxyEagerLoading
13
+ ActiveGraph::Node::Query::QueryProxy.prepend ActiveGraphExtensions::Node::Query::QueryProxy
14
+
15
+ ActiveGraph::Node.include ActiveGraphExtensions::Node::Query::QueryProxyEagerLoading::AssociationEagerLoad
metadata ADDED
@@ -0,0 +1,264 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activegraph-extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: java
6
+ authors:
7
+ - Amit Suryavanshi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ name: parslet
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ name: activegraph
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ name: guard
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ name: guard-rspec
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ name: guard-rubocop
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 0.3.0
89
+ name: neo4j-rake_tasks
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 0.3.0
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ name: os
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ name: pry
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '4.0'
131
+ name: railties
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '4.0'
139
+ - !ruby/object:Gem::Dependency
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ name: rake
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 0.56.0
159
+ name: rubocop
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: 0.56.0
167
+ - !ruby/object:Gem::Dependency
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ name: yard
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ name: dryspec
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "<"
199
+ - !ruby/object:Gem::Version
200
+ version: '3.10'
201
+ name: rspec
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "<"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.10'
209
+ description: " Additional features to activegraph, like sideload limiting, authorizing\
210
+ \ sideloads etc.\n"
211
+ email: amitbsuryavabshi@mail.com
212
+ executables: []
213
+ extensions: []
214
+ extra_rdoc_files:
215
+ - README.md
216
+ files:
217
+ - CHANGELOG.md
218
+ - Gemfile
219
+ - README.md
220
+ - activegraph-extensions.gemspec
221
+ - lib/active_graph_extensions/node.rb
222
+ - lib/active_graph_extensions/node/query.rb
223
+ - lib/active_graph_extensions/node/query/query_proxy.rb
224
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading.rb
225
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading/association_eager_load.rb
226
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading/association_limiting.rb
227
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading/eager_loading_order.rb
228
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading/enhanced_tree.rb
229
+ - lib/active_graph_extensions/node/query/query_proxy_eager_loading/scope_eager_loading.rb
230
+ - lib/active_graph_extensions/string_parsers.rb
231
+ - lib/active_graph_extensions/string_parsers/relation_parser.rb
232
+ - lib/active_graph_extensions/version.rb
233
+ - lib/activegraph-extensions.rb
234
+ homepage: https://github.com/neo4jrb/activegraph-extensions/
235
+ licenses:
236
+ - MIT
237
+ metadata: {}
238
+ post_install_message:
239
+ rdoc_options:
240
+ - "--quiet"
241
+ - "--title"
242
+ - Neo4j.rb
243
+ - "--line-numbers"
244
+ - "--main"
245
+ - README.rdoc
246
+ - "--inline-source"
247
+ require_paths:
248
+ - lib
249
+ required_ruby_version: !ruby/object:Gem::Requirement
250
+ requirements:
251
+ - - ">="
252
+ - !ruby/object:Gem::Version
253
+ version: '2.5'
254
+ required_rubygems_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ requirements: []
260
+ rubygems_version: 3.0.6
261
+ signing_key:
262
+ specification_version: 4
263
+ summary: Additional features to activegraph
264
+ test_files: []