Permalink
Browse files

Merge be8e507 into 13f888a

  • Loading branch information...
cheerfulstoic committed Apr 19, 2016
2 parents 13f888a + be8e507 commit 8b0ffd94819e61b2debfacf5524f889fa662c612
Showing with 677 additions and 642 deletions.
  1. +1 −0 .agignore
  2. +2 −1 Gemfile
  3. +15 −10 docs/Setup.rst
  4. +4 −0 lib/neo4j.rb
  5. +49 −0 lib/neo4j/active_base.rb
  6. +12 −0 lib/neo4j/active_base/session_registry.rb
  7. +1 −2 lib/neo4j/active_node.rb
  8. +2 −2 lib/neo4j/active_node/has_n.rb
  9. +1 −1 lib/neo4j/active_node/has_n/association/rel_factory.rb
  10. +4 −5 lib/neo4j/active_node/id_property.rb
  11. +6 −4 lib/neo4j/active_node/labels.rb
  12. +9 −17 lib/neo4j/active_node/labels/index.rb
  13. +24 −24 lib/neo4j/active_node/node_wrapper.rb
  14. +21 −11 lib/neo4j/active_node/persistence.rb
  15. +2 −2 lib/neo4j/active_node/query/query_proxy.rb
  16. +1 −1 lib/neo4j/active_node/query/query_proxy_methods.rb
  17. +1 −1 lib/neo4j/active_node/query/query_proxy_methods_of_mass_updating.rb
  18. +2 −2 lib/neo4j/active_rel/initialize.rb
  19. +16 −3 lib/neo4j/active_rel/persistence.rb
  20. +6 −4 lib/neo4j/active_rel/query.rb
  21. +24 −16 lib/neo4j/active_rel/rel_wrapper.rb
  22. +5 −1 lib/neo4j/active_rel/related_node.rb
  23. +0 −1 lib/neo4j/config.rb
  24. +3 −3 lib/neo4j/migration.rb
  25. +44 −20 lib/neo4j/railtie.rb
  26. +14 −12 lib/neo4j/schema/operation.rb
  27. +20 −11 lib/neo4j/shared.rb
  28. +3 −3 lib/neo4j/shared/callbacks.rb
  29. +20 −5 lib/neo4j/shared/persistence.rb
  30. +1 −1 lib/neo4j/shared/query_factory.rb
  31. +1 −1 lib/neo4j/shared/validations.rb
  32. +1 −1 neo4j.gemspec
  33. +12 −14 spec/e2e/active_model_spec.rb
  34. +3 −3 spec/e2e/active_rel/persistence/query_factory_spec.rb
  35. +3 −3 spec/e2e/active_rel_spec.rb
  36. +25 −25 spec/e2e/has_many_spec.rb
  37. +0 −8 spec/e2e/has_one_spec.rb
  38. +18 −18 spec/e2e/id_property_spec.rb
  39. +2 −2 spec/e2e/migration_spec.rb
  40. +0 −2 spec/e2e/module_handling.rb
  41. +1 −1 spec/e2e/neo4j-core_spec.rb
  42. +4 −6 spec/e2e/node_wrapping_spec.rb
  43. +9 −18 spec/e2e/query_spec.rb
  44. +0 −44 spec/e2e/rels_spec.rb
  45. +3 −3 spec/e2e/shared/query_factory_spec.rb
  46. +1 −1 spec/e2e/transaction_spec.rb
  47. +3 −3 spec/e2e/wrapped_transactions_spec.rb
  48. +5 −4 spec/integration/label_spec.rb
  49. +160 −160 spec/integration/node_persistence_spec.rb
  50. +5 −1 spec/shared_examples/timestamped_model.rb
  51. +78 −67 spec/spec_helper.rb
  52. +1 −1 spec/unit/active_node/query_spec.rb
  53. +1 −2 spec/unit/active_node/validation_spec.rb
  54. +0 −2 spec/unit/active_rel/persistence_spec_bad.rb
  55. +28 −18 spec/unit/active_rel/rel_wrapper_spec.rb
  56. +0 −71 spec/unit/shared/identity_spec.rb
View
@@ -0,0 +1 @@
*.rst
View
@@ -2,7 +2,8 @@ source 'http://rubygems.org'
gemspec
gem 'neo4j-core', github: 'neo4jrb/neo4j-core', branch: 'master' if ENV['CI']
# gem 'neo4j-core', github: 'neo4jrb/neo4j-core', branch: 'master' if ENV['CI']
gem 'neo4j-core', path: '../neo4j-core'
# gem 'active_attr', github: 'neo4jrb/active_attr', branch: 'performance'
# gem 'active_attr', path: '../active_attr'
View
@@ -86,31 +86,36 @@ An example ``config/neo4j.yml`` file:
.. code-block:: yaml
development:
type: server_db
type: http
url: http://localhost:7474
test:
type: server_db
type: http
url: http://localhost:7575
production:
type: server_db
type: http
url: http://neo4j:password@localhost:7000
You can also use your Rails configuration. The following example can be put into ``config/application.rb`` or any of your environment configurations (``config/environments/(development|test|production).rb``) file:
.. code-block:: ruby
config.neo4j.session_type = :server_db
config.neo4j.session_path = 'http://localhost:7474'
config.neo4j.session_type = :http
config.neo4j.session_url = 'http://localhost:7474'
# Or, for embedded in jRuby
config.neo4j.session_type = :embedded
config.neo4j.session_path = '/path/to/graph.db'
Neo4j requires authentication by default but if you install using the built-in :doc:`rake tasks </RakeTasks>`) authentication is disabled. If you are using authentication you can configure it like this:
.. code-block:: ruby
config.neo4j.session_path = 'http://neo4j:password@localhost:7474'
config.neo4j.session_url = 'http://neo4j:password@localhost:7474'
Of course it's often the case that you don't want to expose your username / password / URL in your repository. In these cases you can use the ``NEO4J_TYPE`` (either ``server_db`` or ``embedded_db``) and ``NEO4J_URL``/``NEO4J_PATH`` environment variables.
Of course it's often the case that you don't want to expose your username / password / URL in your repository. In these cases you can use the ``NEO4J_TYPE`` (either ``http`` or ``embedded``) and ``NEO4J_URL``/``NEO4J_PATH`` environment variables.
Configuring Faraday
^^^^^^^^^^^^^^^^^^^
@@ -156,7 +161,7 @@ In Ruby
.. code-block:: ruby
# In JRuby or MRI, using Neo4j Server mode. When the railtie is included, this happens automatically.
Neo4j::Session.open(:server_db)
Neo4j::Session.open(:http)
Embedded mode in JRuby
``````````````````````
@@ -165,7 +170,7 @@ In jRuby you can access the data in server mode as above. If you want to run th
.. code-block:: ruby
session = Neo4j::Session.open(:embedded_db, '/folder/db')
session = Neo4j::Session.open(:embedded, '/folder/db')
session.start
Embedded mode means that Neo4j is running inside your jRuby process. This allows for direct access to the Neo4j Java APIs for faster and more direct querying.
@@ -201,7 +206,7 @@ Rails configuration
.. code-block:: ruby
config.neo4j.session_type = :server_db
config.neo4j.session_type = :http
# GrapheneDB
config.neo4j.session_path = ENV["GRAPHENEDB_URL"] || 'http://localhost:7474'
# Graph Story
View
@@ -3,6 +3,10 @@
require 'neo4j-core'
require 'neo4j/core/cypher_session'
require 'neo4j/core/query'
require 'neo4j/active_base'
require 'neo4j/active_base/session_registry'
require 'active_model'
require 'active_support/concern'
require 'active_support/core_ext/class/attribute.rb'
View
@@ -0,0 +1,49 @@
module Neo4j
# To contain any base login for ActiveNode/ActiveRel which
# is external to the main classes
module ActiveBase
class << self
# private?
def current_session
SessionRegistry.current_session.tap do |session|
fail 'No session defined!' if session.nil?
end
end
def current_transaction_or_session
current_transaction || current_session
end
def query(*args)
current_transaction_or_session.query(*args)
end
# Should support setting session via config options
def set_current_session(session)
SessionRegistry.current_session = session
end
def set_current_session_by_adaptor(adaptor)
set_current_session(Neo4j::Core::CypherSession.new(adaptor))
end
def run_transaction(run_in_tx = true)
Neo4j::Transaction.run(current_session, run_in_tx) do |tx|
yield tx
end
end
def new_transaction
Neo4j::Transaction.new(current_session)
end
def new_query(options = {})
Neo4j::Core::Query.new({session: current_session}.merge(options))
end
def current_transaction
Neo4j::Transaction.current_for(current_session)
end
end
end
end
@@ -0,0 +1,12 @@
require 'active_support/per_thread_registry'
module Neo4j
module ActiveBase
# Provides a simple API to manage sessions in a thread-safe manner
class SessionRegistry
extend ActiveSupport::PerThreadRegistry
attr_accessor :current_session
end
end
end
View
@@ -86,8 +86,7 @@ def self.inherit_id_property(other)
end
end
Neo4j::Session.on_next_session_available do |_|
next if manual_id_property?
if !manual_id_property?
id_property :uuid, auto: :uuid unless self.id_property?
name = Neo4j::Config[:id_property]
@@ -363,7 +363,7 @@ def define_has_many_setter(name)
clear_deferred_nodes_for_association(name)
Neo4j::Transaction.run { association_proxy(name).replace_with(other_nodes) }
self.class.run_transaction { association_proxy(name).replace_with(other_nodes) }
end
end
@@ -439,7 +439,7 @@ def define_has_one_setter(name)
if persisted?
other_node.save if other_node.respond_to?(:persisted?) && !other_node.persisted?
association_proxy_cache.clear # TODO: Should probably just clear for this association...
Neo4j::Transaction.run { association_proxy(name).replace_with(other_node) }
self.class.run_transaction { association_proxy(name).replace_with(other_node) }
# handle_non_persisted_node(other_node)
else
defer_create(name, other_node, clear: true)
@@ -44,7 +44,7 @@ def _create_relationship_with_factory
def _match_query(other_node, wrapper)
nodes = _nodes_for_create(other_node, wrapper.from_node_identifier, wrapper.to_node_identifier)
Neo4j::Session.current.query.match_nodes(nodes)
Neo4j::ActiveBase.new_query.match_nodes(nodes)
end
def _nodes_for_create(other_node, from_node_id, to_node_id)
@@ -138,11 +138,10 @@ def find_by_ids(ids)
def id_property(name, conf = {})
self.manual_id_property = true
Neo4j::Session.on_next_session_available do |_|
@id_property_info = {name: name, type: conf}
TypeMethods.define_id_methods(self, name, conf)
constraint(name, type: :unique) unless conf[:constraint] == false
end
@id_property_info = {name: name, type: conf}
TypeMethods.define_id_methods(self, name, conf)
constraint(name, type: :unique) unless conf[:constraint] == false
end
# rubocop:disable Style/PredicateName
@@ -1,3 +1,5 @@
require 'neo4j/core/label'
module Neo4j
module ActiveNode
# Provides a mapping between neo4j labels and Ruby classes
@@ -71,7 +73,7 @@ def self.model_for_labels(labels)
def self.clear_wrapped_models
WRAPPED_CLASSES.clear
MODELS_FOR_LABELS_CACHE.clear
Neo4j::Node::Wrapper::CONSTANTS_FOR_LABELS_CACHE.clear
Neo4j::NodeWrapping::CONSTANTS_FOR_LABELS_CACHE.clear
end
module ClassMethods
@@ -105,8 +107,8 @@ def find_by!(values)
# Deletes all nodes and connected relationships from Cypher.
def delete_all
self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`) OPTIONAL MATCH n-[r]-() DELETE n,r")
self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`) DELETE n")
neo4j_query("MATCH (n:`#{mapped_label_name}`) OPTIONAL MATCH n-[r]-() DELETE n,r")
# neo4j_query("MATCH (n:`#{mapped_label_name}`) DELETE n")
end
# Returns each node to Ruby and calls `destroy`. Be careful, as this can be a very slow operation if you have many nodes. It will generate at least
@@ -127,7 +129,7 @@ def mapped_label_name
# @return [Neo4j::Label] the label for this class
def mapped_label
Neo4j::Label.create(mapped_label_name)
Neo4j::Core::Label.new(mapped_label_name, neo4j_session)
end
def base_class
@@ -20,38 +20,30 @@ module ClassMethods
# index :name
# end
def index(property)
Neo4j::Session.on_next_session_available do |_|
declared_properties.index_or_fail!(property, id_property_name)
schema_create_operation(:index, property)
end
declared_properties.index_or_fail!(property, id_property_name)
schema_create_operation(:index, property)
end
# Creates a neo4j constraint on this class for given property
#
# @example
# Person.constraint :name, type: :unique
def constraint(property, constraints = {type: :unique})
Neo4j::Session.on_next_session_available do
declared_properties.constraint_or_fail!(property, id_property_name)
schema_create_operation(:constraint, property, constraints)
end
declared_properties.constraint_or_fail!(property, id_property_name)
schema_create_operation(:constraint, property, constraints)
end
# @param [Symbol] property The name of the property index to be dropped
def drop_index(property, options = {})
Neo4j::Session.on_next_session_available do
declared_properties[property].unindex! if declared_properties[property]
schema_drop_operation(:index, property, options)
end
declared_properties[property].unindex! if declared_properties[property]
schema_drop_operation(:index, property, options)
end
# @param [Symbol] property The name of the property constraint to be dropped
# @param [Hash] constraint The constraint type to be dropped.
def drop_constraint(property, constraint = {type: :unique})
Neo4j::Session.on_next_session_available do
declared_properties[property].unconstraint! if declared_properties[property]
schema_drop_operation(:constraint, property, constraint)
end
declared_properties[property].unconstraint! if declared_properties[property]
schema_drop_operation(:constraint, property, constraint)
end
def index?(property)
@@ -80,7 +72,7 @@ def new_schema_class(type, property, options)
Neo4j::Schema::UniqueConstraintOperation
else
fail "Unknown Schema Operation class #{type}"
end.new(mapped_label_name, property, options)
end.new(mapped_label, property, options)
end
end
end
@@ -1,35 +1,35 @@
require 'active_support/inflector'
require 'neo4j/core/node'
class Neo4j::Node
# The wrapping process is what transforms a raw CypherNode or EmbeddedNode from Neo4j::Core into a healthy ActiveNode (or ActiveRel) object.
module Wrapper
# this is a plugin in the neo4j-core so that the Ruby wrapper will be wrapped around the Neo4j::Node objects
def wrapper
found_class = class_to_wrap
return self if not found_class
wrapping_proc = Proc.new do |node|
found_class = Neo4j::NodeWrapping.class_to_wrap(node.labels)
next node if not found_class
found_class.new.tap do |wrapped_node|
wrapped_node.init_on_load(self, self.props)
end
end
def class_to_wrap
load_classes_from_labels
Neo4j::ActiveNode::Labels.model_for_labels(labels).tap do |model_class|
Neo4j::Node::Wrapper.populate_constants_for_labels_cache(model_class, labels)
end
end
private
def load_classes_from_labels
labels.each { |label| Neo4j::Node::Wrapper.constant_for_label(label) }
end
found_class.new.tap do |wrapped_node|
wrapped_node.init_on_load(node, node.props)
end
end
Neo4j::Core::Node.wrapper_callback(wrapping_proc)
module Neo4j
module NodeWrapping
# Only load classes once for performance
CONSTANTS_FOR_LABELS_CACHE = {}
class << self
def class_to_wrap(labels)
load_classes_from_labels(labels)
Neo4j::ActiveNode::Labels.model_for_labels(labels).tap do |model_class|
populate_constants_for_labels_cache(model_class, labels)
end
end
private
def load_classes_from_labels(labels)
labels.each { |label| constant_for_label(label) }
end
def constant_for_label(label)
CONSTANTS_FOR_LABELS_CACHE[label] || CONSTANTS_FOR_LABELS_CACHE[label] = constantized_label(label)
end
Oops, something went wrong.

0 comments on commit 8b0ffd9

Please sign in to comment.