activegraph 10.0.0.pre.alpha.6
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 +7 -0
- data/CHANGELOG.md +1989 -0
- data/CONTRIBUTORS +12 -0
- data/Gemfile +24 -0
- data/README.md +107 -0
- data/bin/rake +17 -0
- data/config/locales/en.yml +5 -0
- data/config/neo4j/add_classnames.yml +1 -0
- data/config/neo4j/config.yml +38 -0
- data/lib/neo4j.rb +116 -0
- data/lib/neo4j/active_base.rb +89 -0
- data/lib/neo4j/active_node.rb +108 -0
- data/lib/neo4j/active_node/callbacks.rb +8 -0
- data/lib/neo4j/active_node/dependent.rb +11 -0
- data/lib/neo4j/active_node/dependent/association_methods.rb +49 -0
- data/lib/neo4j/active_node/dependent/query_proxy_methods.rb +51 -0
- data/lib/neo4j/active_node/enum.rb +26 -0
- data/lib/neo4j/active_node/has_n.rb +612 -0
- data/lib/neo4j/active_node/has_n/association.rb +278 -0
- data/lib/neo4j/active_node/has_n/association/rel_factory.rb +61 -0
- data/lib/neo4j/active_node/has_n/association/rel_wrapper.rb +23 -0
- data/lib/neo4j/active_node/has_n/association_cypher_methods.rb +108 -0
- data/lib/neo4j/active_node/id_property.rb +224 -0
- data/lib/neo4j/active_node/id_property/accessor.rb +62 -0
- data/lib/neo4j/active_node/initialize.rb +21 -0
- data/lib/neo4j/active_node/labels.rb +207 -0
- data/lib/neo4j/active_node/labels/index.rb +37 -0
- data/lib/neo4j/active_node/labels/reloading.rb +21 -0
- data/lib/neo4j/active_node/node_list_formatter.rb +13 -0
- data/lib/neo4j/active_node/node_wrapper.rb +54 -0
- data/lib/neo4j/active_node/orm_adapter.rb +82 -0
- data/lib/neo4j/active_node/persistence.rb +187 -0
- data/lib/neo4j/active_node/property.rb +60 -0
- data/lib/neo4j/active_node/query.rb +76 -0
- data/lib/neo4j/active_node/query/query_proxy.rb +374 -0
- data/lib/neo4j/active_node/query/query_proxy_eager_loading.rb +177 -0
- data/lib/neo4j/active_node/query/query_proxy_eager_loading/association_tree.rb +75 -0
- data/lib/neo4j/active_node/query/query_proxy_enumerable.rb +110 -0
- data/lib/neo4j/active_node/query/query_proxy_find_in_batches.rb +19 -0
- data/lib/neo4j/active_node/query/query_proxy_link.rb +139 -0
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +302 -0
- data/lib/neo4j/active_node/query/query_proxy_methods_of_mass_updating.rb +86 -0
- data/lib/neo4j/active_node/query_methods.rb +68 -0
- data/lib/neo4j/active_node/reflection.rb +86 -0
- data/lib/neo4j/active_node/rels.rb +11 -0
- data/lib/neo4j/active_node/scope.rb +166 -0
- data/lib/neo4j/active_node/unpersisted.rb +48 -0
- data/lib/neo4j/active_node/validations.rb +59 -0
- data/lib/neo4j/active_rel.rb +67 -0
- data/lib/neo4j/active_rel/callbacks.rb +15 -0
- data/lib/neo4j/active_rel/initialize.rb +28 -0
- data/lib/neo4j/active_rel/persistence.rb +134 -0
- data/lib/neo4j/active_rel/persistence/query_factory.rb +95 -0
- data/lib/neo4j/active_rel/property.rb +95 -0
- data/lib/neo4j/active_rel/query.rb +101 -0
- data/lib/neo4j/active_rel/rel_wrapper.rb +31 -0
- data/lib/neo4j/active_rel/related_node.rb +87 -0
- data/lib/neo4j/active_rel/types.rb +82 -0
- data/lib/neo4j/active_rel/validations.rb +8 -0
- data/lib/neo4j/ansi.rb +14 -0
- data/lib/neo4j/class_arguments.rb +39 -0
- data/lib/neo4j/config.rb +135 -0
- data/lib/neo4j/core.rb +14 -0
- data/lib/neo4j/core/connection_failed_error.rb +6 -0
- data/lib/neo4j/core/cypher_error.rb +37 -0
- data/lib/neo4j/core/driver.rb +66 -0
- data/lib/neo4j/core/has_uri.rb +63 -0
- data/lib/neo4j/core/instrumentable.rb +36 -0
- data/lib/neo4j/core/label.rb +158 -0
- data/lib/neo4j/core/logging.rb +44 -0
- data/lib/neo4j/core/node.rb +23 -0
- data/lib/neo4j/core/querable.rb +88 -0
- data/lib/neo4j/core/query.rb +487 -0
- data/lib/neo4j/core/query_builder.rb +32 -0
- data/lib/neo4j/core/query_clauses.rb +727 -0
- data/lib/neo4j/core/query_ext.rb +24 -0
- data/lib/neo4j/core/query_find_in_batches.rb +49 -0
- data/lib/neo4j/core/relationship.rb +13 -0
- data/lib/neo4j/core/responses.rb +50 -0
- data/lib/neo4j/core/result.rb +33 -0
- data/lib/neo4j/core/schema.rb +30 -0
- data/lib/neo4j/core/schema_errors.rb +12 -0
- data/lib/neo4j/core/wrappable.rb +30 -0
- data/lib/neo4j/errors.rb +57 -0
- data/lib/neo4j/migration.rb +148 -0
- data/lib/neo4j/migrations.rb +27 -0
- data/lib/neo4j/migrations/base.rb +77 -0
- data/lib/neo4j/migrations/check_pending.rb +20 -0
- data/lib/neo4j/migrations/helpers.rb +105 -0
- data/lib/neo4j/migrations/helpers/id_property.rb +75 -0
- data/lib/neo4j/migrations/helpers/relationships.rb +66 -0
- data/lib/neo4j/migrations/helpers/schema.rb +51 -0
- data/lib/neo4j/migrations/migration_file.rb +24 -0
- data/lib/neo4j/migrations/runner.rb +195 -0
- data/lib/neo4j/migrations/schema.rb +44 -0
- data/lib/neo4j/migrations/schema_migration.rb +14 -0
- data/lib/neo4j/model_schema.rb +139 -0
- data/lib/neo4j/paginated.rb +27 -0
- data/lib/neo4j/railtie.rb +105 -0
- data/lib/neo4j/schema/operation.rb +102 -0
- data/lib/neo4j/shared.rb +60 -0
- data/lib/neo4j/shared/attributes.rb +216 -0
- data/lib/neo4j/shared/callbacks.rb +68 -0
- data/lib/neo4j/shared/cypher.rb +37 -0
- data/lib/neo4j/shared/declared_properties.rb +204 -0
- data/lib/neo4j/shared/declared_property.rb +109 -0
- data/lib/neo4j/shared/declared_property/index.rb +37 -0
- data/lib/neo4j/shared/enum.rb +167 -0
- data/lib/neo4j/shared/filtered_hash.rb +79 -0
- data/lib/neo4j/shared/identity.rb +34 -0
- data/lib/neo4j/shared/initialize.rb +64 -0
- data/lib/neo4j/shared/marshal.rb +23 -0
- data/lib/neo4j/shared/mass_assignment.rb +64 -0
- data/lib/neo4j/shared/permitted_attributes.rb +28 -0
- data/lib/neo4j/shared/persistence.rb +282 -0
- data/lib/neo4j/shared/property.rb +240 -0
- data/lib/neo4j/shared/query_factory.rb +102 -0
- data/lib/neo4j/shared/rel_type_converters.rb +43 -0
- data/lib/neo4j/shared/serialized_properties.rb +30 -0
- data/lib/neo4j/shared/type_converters.rb +433 -0
- data/lib/neo4j/shared/typecasted_attributes.rb +98 -0
- data/lib/neo4j/shared/typecaster.rb +53 -0
- data/lib/neo4j/shared/validations.rb +44 -0
- data/lib/neo4j/tasks/migration.rake +202 -0
- data/lib/neo4j/timestamps.rb +11 -0
- data/lib/neo4j/timestamps/created.rb +9 -0
- data/lib/neo4j/timestamps/updated.rb +9 -0
- data/lib/neo4j/transaction.rb +139 -0
- data/lib/neo4j/type_converters.rb +7 -0
- data/lib/neo4j/undeclared_properties.rb +53 -0
- data/lib/neo4j/version.rb +3 -0
- data/lib/neo4j/wrapper.rb +4 -0
- data/lib/rails/generators/neo4j/migration/migration_generator.rb +14 -0
- data/lib/rails/generators/neo4j/migration/templates/migration.erb +9 -0
- data/lib/rails/generators/neo4j/model/model_generator.rb +88 -0
- data/lib/rails/generators/neo4j/model/templates/migration.erb +9 -0
- data/lib/rails/generators/neo4j/model/templates/model.erb +15 -0
- data/lib/rails/generators/neo4j/upgrade_v8/templates/migration.erb +17 -0
- data/lib/rails/generators/neo4j/upgrade_v8/upgrade_v8_generator.rb +32 -0
- data/lib/rails/generators/neo4j_generator.rb +119 -0
- data/neo4j.gemspec +51 -0
- metadata +421 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'neo4j/core/relationship'
|
|
2
|
+
|
|
3
|
+
wrapping_proc = proc do |relationship|
|
|
4
|
+
Neo4j::RelWrapping.wrapper(relationship)
|
|
5
|
+
end
|
|
6
|
+
Neo4j::Driver::Types::Relationship.wrapper_callback(wrapping_proc)
|
|
7
|
+
|
|
8
|
+
module Neo4j
|
|
9
|
+
module RelWrapping
|
|
10
|
+
class << self
|
|
11
|
+
def wrapper(rel)
|
|
12
|
+
rel.props.symbolize_keys!
|
|
13
|
+
begin
|
|
14
|
+
most_concrete_class = class_from_type(rel.rel_type).constantize
|
|
15
|
+
return rel unless most_concrete_class < Neo4j::ActiveRel
|
|
16
|
+
most_concrete_class.new
|
|
17
|
+
rescue NameError => e
|
|
18
|
+
raise e unless e.message =~ /(uninitialized|wrong) constant/
|
|
19
|
+
|
|
20
|
+
return rel
|
|
21
|
+
end.tap do |wrapped_rel|
|
|
22
|
+
wrapped_rel.init_on_load(rel, rel.start_node_id, rel.end_node_id, rel.type)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def class_from_type(rel_type)
|
|
27
|
+
Neo4j::ActiveRel::Types::WRAPPED_CLASSES[rel_type] || Neo4j::ActiveRel::Types::WRAPPED_CLASSES[rel_type] = rel_type.to_s.downcase.camelize
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module Neo4j::ActiveRel
|
|
2
|
+
# A container for ActiveRel's :inbound and :outbound methods. It provides lazy loading of nodes.
|
|
3
|
+
# It's important (or maybe not really IMPORTANT, but at least worth mentioning) that calling method_missing
|
|
4
|
+
# will result in a query to load the node if the node is not already loaded.
|
|
5
|
+
class RelatedNode
|
|
6
|
+
class UnsetRelatedNodeError < Neo4j::Error; end
|
|
7
|
+
|
|
8
|
+
# ActiveRel's related nodes can be initialized with nothing, an integer, or a fully wrapped node.
|
|
9
|
+
#
|
|
10
|
+
# Initialization with nothing happens when a new, non-persisted ActiveRel object is first initialized.
|
|
11
|
+
#
|
|
12
|
+
# Initialization with an integer happens when a relationship is loaded from the database. It loads using the ID
|
|
13
|
+
# because that is provided by the Cypher response and does not require an extra query.
|
|
14
|
+
def initialize(node = nil)
|
|
15
|
+
@node = valid_node_param?(node) ? node : (fail Neo4j::InvalidParameterError, 'RelatedNode must be initialized with either a node ID or node')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Loads the node if needed, then conducts comparison.
|
|
19
|
+
def ==(other)
|
|
20
|
+
loaded if @node.is_a?(Integer)
|
|
21
|
+
@node == other
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns the neo_id of a given node without loading.
|
|
25
|
+
def neo_id
|
|
26
|
+
loaded? ? @node.neo_id : @node
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Loads a node from the database or returns the node if already laoded
|
|
30
|
+
def loaded
|
|
31
|
+
fail UnsetRelatedNodeError, 'Node not set, cannot load' if @node.nil?
|
|
32
|
+
@node = if @node.respond_to?(:neo_id)
|
|
33
|
+
@node
|
|
34
|
+
else
|
|
35
|
+
Neo4j::ActiveBase.new_query.match(:n).where(n: {neo_id: @node}).pluck(:n).first
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param [String, Symbol, Array] clazz An alternate label to use in the event the node is not present or loaded
|
|
40
|
+
def cypher_representation(clazz)
|
|
41
|
+
case
|
|
42
|
+
when !set?
|
|
43
|
+
"(#{formatted_label_list(clazz)})"
|
|
44
|
+
when set? && !loaded?
|
|
45
|
+
"(Node with neo_id #{@node})"
|
|
46
|
+
else
|
|
47
|
+
node_class = self.class
|
|
48
|
+
id_name = node_class.id_property_name
|
|
49
|
+
labels = ':' + node_class.mapped_label_names.join(':')
|
|
50
|
+
|
|
51
|
+
"(#{labels} {#{id_name}: #{@node.id.inspect}})"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Boolean] indicates whether a node has or has not been fully loaded from the database
|
|
56
|
+
def loaded?
|
|
57
|
+
@node.respond_to?(:neo_id)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def set?
|
|
61
|
+
!@node.nil?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def method_missing(*args, &block)
|
|
65
|
+
loaded.send(*args, &block)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
69
|
+
loaded if @node.is_a?(Numeric)
|
|
70
|
+
@node.respond_to?(method_name) ? true : super
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def class
|
|
74
|
+
loaded.send(:class)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
def formatted_label_list(list)
|
|
80
|
+
list.is_a?(Array) ? list.join(' || ') : list
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def valid_node_param?(node)
|
|
84
|
+
node.nil? || node.is_a?(Integer) || node.respond_to?(:neo_id)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
module ActiveRel
|
|
3
|
+
# provides mapping of type to model name
|
|
4
|
+
module Types
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
# WRAPPED_CLASSES maps relationship types to ActiveRel models.
|
|
8
|
+
#
|
|
9
|
+
# Typically, it's a 1:1 relationship, with a type having a model of the same name. Sometimes, someone needs to be a precious
|
|
10
|
+
# snowflake and have a model name that doesn't match the rel type, so this comes in handy.
|
|
11
|
+
#
|
|
12
|
+
# As an example, Chris often finds it easier to name models after the classes that use the relationship: `StudentLesson` instead of
|
|
13
|
+
# `EnrolledIn`, because it's easier to remember "A student has a relationship to lesson" than "the type of relationship between Student
|
|
14
|
+
# and Lesson is 'EnrolledIn'." After all, that is a big part of why we have models, right? To make our lives easier?
|
|
15
|
+
#
|
|
16
|
+
# A model is added to WRAPPED_CLASSES when it is initalized AND when the `type` class method is called within a model. This means that
|
|
17
|
+
# it's possible a model will be added twice: once with the rel_type version of the model name, again with the custom type. deal_with_it.gif.
|
|
18
|
+
WRAPPED_CLASSES = {}
|
|
19
|
+
|
|
20
|
+
included do
|
|
21
|
+
type self.namespaced_model_name, true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module ClassMethods
|
|
25
|
+
include Neo4j::Shared::RelTypeConverters
|
|
26
|
+
|
|
27
|
+
def inherited(subclass)
|
|
28
|
+
subclass.type subclass.namespaced_model_name, true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# When called without arguments, it will return the current setting or supply a default.
|
|
32
|
+
# When called with arguments, it will change the current setting.
|
|
33
|
+
# @param [String] given_type sets the relationship type when creating relationships via this class
|
|
34
|
+
# @param [Boolean] auto Should the given_type be changed in compliance with the gem's rel decorator setting?
|
|
35
|
+
def type(given_type = nil, auto = false)
|
|
36
|
+
case
|
|
37
|
+
when !given_type && rel_type?
|
|
38
|
+
@rel_type
|
|
39
|
+
when given_type
|
|
40
|
+
assign_type!(given_type, auto)
|
|
41
|
+
else
|
|
42
|
+
assign_type!(namespaced_model_name, true)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
alias rel_type type
|
|
46
|
+
alias _type type # should be deprecated
|
|
47
|
+
|
|
48
|
+
def namespaced_model_name
|
|
49
|
+
case Neo4j::Config[:module_handling]
|
|
50
|
+
when :demodulize
|
|
51
|
+
self.name.demodulize
|
|
52
|
+
when Proc
|
|
53
|
+
Neo4j::Config[:module_handling].call(self.name)
|
|
54
|
+
else
|
|
55
|
+
self.name
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def _wrapped_classes
|
|
60
|
+
WRAPPED_CLASSES
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def add_wrapped_class(type)
|
|
64
|
+
# WRAPPED_CLASSES[type.to_sym.downcase] = self.name
|
|
65
|
+
_wrapped_classes[type.to_sym] = self.name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def rel_type?
|
|
69
|
+
!!@rel_type
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def assign_type!(given_type, auto)
|
|
75
|
+
@rel_type = (auto ? decorated_rel_type(given_type) : given_type).tap do |type|
|
|
76
|
+
add_wrapped_class(type)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
data/lib/neo4j/ansi.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
module ClassArguments
|
|
3
|
+
class << self
|
|
4
|
+
INVALID_CLASS_ARGUMENT_ERROR = 'option must by String, Symbol, false, nil, or an Array of Symbols/Strings'
|
|
5
|
+
|
|
6
|
+
def valid_argument?(class_argument)
|
|
7
|
+
[NilClass, String, Symbol, FalseClass].include?(class_argument.class) ||
|
|
8
|
+
(class_argument.is_a?(Array) && class_argument.all? { |c| [Symbol, String].include?(c.class) })
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def validate_argument!(class_argument, context)
|
|
12
|
+
return if valid_argument?(class_argument)
|
|
13
|
+
|
|
14
|
+
fail ArgumentError, "#{context} #{INVALID_CLASS_ARGUMENT_ERROR} (was #{class_argument.inspect})"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def active_node_model?(class_constant)
|
|
18
|
+
class_constant.included_modules.include?(Neo4j::ActiveNode)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def constantize_argument(class_argument)
|
|
22
|
+
case class_argument
|
|
23
|
+
when 'any', :any, false, nil
|
|
24
|
+
nil
|
|
25
|
+
when Array
|
|
26
|
+
class_argument.map(&method(:constantize_argument))
|
|
27
|
+
else
|
|
28
|
+
class_argument.to_s.constantize.tap do |class_constant|
|
|
29
|
+
if !active_node_model?(class_constant)
|
|
30
|
+
fail ArgumentError, "#{class_constant} is not an ActiveNode model"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
rescue NameError
|
|
35
|
+
raise ArgumentError, "Could not find class: #{class_argument}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/neo4j/config.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
# == Keeps configuration for neo4j
|
|
3
|
+
#
|
|
4
|
+
# == Configurations keys
|
|
5
|
+
class Config
|
|
6
|
+
DEFAULT_FILE = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'neo4j', 'config.yml'))
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
# In keeping with the Rails convention, this class writer lets you globally configure
|
|
10
|
+
# the incluse of timestamps on your nodes and rels. It defaults to false, requiring manual
|
|
11
|
+
# timestamp inclusion.
|
|
12
|
+
# @return [Boolean] the true/false value specified.
|
|
13
|
+
|
|
14
|
+
# @return [Integer] The location of the default configuration file.
|
|
15
|
+
def default_file
|
|
16
|
+
@default_file ||= DEFAULT_FILE
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Sets the location of the configuration YAML file and old deletes configurations.
|
|
20
|
+
# @param [String] file_path represent the path to the file.
|
|
21
|
+
def default_file=(file_path)
|
|
22
|
+
delete_all
|
|
23
|
+
@defaults = nil
|
|
24
|
+
@default_file = File.expand_path(file_path)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [Hash] the default file loaded by yaml
|
|
28
|
+
def defaults
|
|
29
|
+
require 'yaml'
|
|
30
|
+
@defaults ||= ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(default_file))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Reads from the default_file if configuration is not set already
|
|
34
|
+
# @return [Hash] the configuration
|
|
35
|
+
def configuration
|
|
36
|
+
return @configuration if @configuration
|
|
37
|
+
|
|
38
|
+
@configuration = ActiveSupport::HashWithIndifferentAccess.new
|
|
39
|
+
@configuration.merge!(defaults)
|
|
40
|
+
@configuration
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Yields the configuration
|
|
44
|
+
#
|
|
45
|
+
# @example
|
|
46
|
+
# Neo4j::Config.use do |config|
|
|
47
|
+
# config[:storage_path] = '/var/neo4j'
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# @return nil
|
|
51
|
+
# @yield config
|
|
52
|
+
# @yieldparam [Neo4j::Config] config - this configuration class
|
|
53
|
+
def use
|
|
54
|
+
@configuration ||= ActiveSupport::HashWithIndifferentAccess.new
|
|
55
|
+
yield @configuration
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Sets the value of a config entry.
|
|
60
|
+
#
|
|
61
|
+
# @param [Symbol] key the key to set the parameter for
|
|
62
|
+
# @param val the value of the parameter.
|
|
63
|
+
def []=(key, val)
|
|
64
|
+
configuration[key.to_s] = val
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param [Symbol] key The key of the config entry value we want
|
|
68
|
+
# @return the the value of a config entry
|
|
69
|
+
def [](key)
|
|
70
|
+
configuration[key.to_s]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def fetch(key, default)
|
|
74
|
+
configuration.fetch(key, default)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Remove the value of a config entry.
|
|
78
|
+
#
|
|
79
|
+
# @param [Symbol] key the key of the configuration entry to delete
|
|
80
|
+
# @return The value of the removed entry.
|
|
81
|
+
def delete(key)
|
|
82
|
+
configuration.delete(key)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Remove all configuration. This can be useful for testing purpose.
|
|
86
|
+
#
|
|
87
|
+
# @return nil
|
|
88
|
+
def delete_all
|
|
89
|
+
@configuration = nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [Hash] The config as a hash.
|
|
93
|
+
def to_hash
|
|
94
|
+
configuration.to_hash
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @return [String] The config as a YAML
|
|
98
|
+
def to_yaml
|
|
99
|
+
configuration.to_yaml
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def fail_on_pending_migrations
|
|
103
|
+
Neo4j::Config[:fail_on_pending_migrations].nil? ? true : Neo4j::Config[:fail_on_pending_migrations]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def include_root_in_json
|
|
107
|
+
# we use ternary because a simple || will always evaluate true
|
|
108
|
+
Neo4j::Config[:include_root_in_json].nil? ? true : Neo4j::Config[:include_root_in_json]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def module_handling
|
|
112
|
+
Neo4j::Config[:module_handling] || :none
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @return [Class] The configured timestamps type (e.g. Integer) or the default DateTime.
|
|
116
|
+
def timestamp_type
|
|
117
|
+
Neo4j::Config[:timestamp_type] || DateTime
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def association_model_namespace
|
|
121
|
+
Neo4j::Config[:association_model_namespace] || nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def association_model_namespace_string
|
|
125
|
+
namespace = Neo4j::Config[:association_model_namespace]
|
|
126
|
+
return nil if namespace.nil?
|
|
127
|
+
"::#{namespace}"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def enums_case_sensitive
|
|
131
|
+
Neo4j::Config[:enums_case_sensitive] || false
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
data/lib/neo4j/core.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'neo4j/transaction'
|
|
2
|
+
require 'neo4j/core/instrumentable'
|
|
3
|
+
require 'neo4j/core/query'
|
|
4
|
+
require 'neo4j/core/driver'
|
|
5
|
+
require 'neo4j/core/responses'
|
|
6
|
+
|
|
7
|
+
require 'neo4j_ruby_driver'
|
|
8
|
+
require 'neo4j/core/wrappable'
|
|
9
|
+
require 'neo4j/core/node'
|
|
10
|
+
require 'neo4j/core/relationship'
|
|
11
|
+
|
|
12
|
+
Neo4j::Driver::Types::Entity.include Neo4j::Core::Wrappable
|
|
13
|
+
Neo4j::Driver::Types::Node.prepend Neo4j::Core::Node
|
|
14
|
+
Neo4j::Driver::Types::Relationship.include Neo4j::Core::Relationship
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Neo4j
|
|
2
|
+
module Core
|
|
3
|
+
class CypherError < StandardError
|
|
4
|
+
attr_reader :code, :original_message, :stack_trace
|
|
5
|
+
|
|
6
|
+
def initialize(code = nil, original_message = nil, stack_trace = nil)
|
|
7
|
+
@code = code
|
|
8
|
+
@original_message = original_message
|
|
9
|
+
@stack_trace = stack_trace
|
|
10
|
+
|
|
11
|
+
msg = <<-ERROR
|
|
12
|
+
Cypher error:
|
|
13
|
+
#{ANSI::CYAN}#{code}#{ANSI::CLEAR}: #{original_message}
|
|
14
|
+
#{stack_trace}
|
|
15
|
+
ERROR
|
|
16
|
+
super(msg)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.new_from(code, message, stack_trace = nil)
|
|
20
|
+
error_class_from(code).new(code, message, stack_trace)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.error_class_from(code)
|
|
24
|
+
case code
|
|
25
|
+
when /(ConstraintValidationFailed|ConstraintViolation)/
|
|
26
|
+
SchemaErrors::ConstraintValidationFailedError
|
|
27
|
+
when /IndexAlreadyExists/
|
|
28
|
+
SchemaErrors::IndexAlreadyExistsError
|
|
29
|
+
when /ConstraintAlreadyExists/ # ?????
|
|
30
|
+
SchemaErrors::ConstraintAlreadyExistsError
|
|
31
|
+
else
|
|
32
|
+
CypherError
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|