Skip to content

Commit

Permalink
Various progress...
Browse files Browse the repository at this point in the history
  • Loading branch information
cheerfulstoic committed Jan 20, 2016
1 parent 65e743d commit 21c41ef
Show file tree
Hide file tree
Showing 19 changed files with 109 additions and 172 deletions.
14 changes: 4 additions & 10 deletions lib/neo4j/active_base.rb
Expand Up @@ -21,18 +21,12 @@ def run_transaction(run_in_tx = true)
end
end

def new_query(options = {})
Neo4j::Core::Query.new({session: current_transaction || current_session}.merge(options))
def wait_for_schema_changes
current_session.wait_for_schema_changes
end

# For making schema changes in a separate session
# So that we don't have issues with data and schema changes
# in the same transaction
def schema_session
if current_session
adaptor = current_session.instance_variable_get('@adaptor')
SessionRegistry.schema_session = Neo4j::Core::CypherSession.new(adaptor)
end
def new_query(options = {})
Neo4j::Core::Query.new({session: current_transaction || current_session}.merge(options))
end

def current_transaction
Expand Down
2 changes: 1 addition & 1 deletion lib/neo4j/active_base/session_registry.rb
Expand Up @@ -6,7 +6,7 @@ module ActiveBase
class SessionRegistry
extend ActiveSupport::PerThreadRegistry

attr_accessor :current_session, :schema_session
attr_accessor :current_session
end
end
end
6 changes: 3 additions & 3 deletions lib/neo4j/active_node/labels.rb
Expand Up @@ -105,8 +105,8 @@ def find_by!(values)

# Deletes all nodes and connected relationships from Cypher.
def delete_all
neo4j_session.query("MATCH (n:`#{mapped_label_name}`) OPTIONAL MATCH n-[r]-() DELETE n,r")
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
Expand All @@ -127,7 +127,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
Expand Down
26 changes: 9 additions & 17 deletions lib/neo4j/active_node/labels/index.rb
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
20 changes: 15 additions & 5 deletions lib/neo4j/active_node/persistence.rb
Expand Up @@ -67,8 +67,8 @@ def create_model
# @param [Array] labels The labels to use for creating the new node.
# @return [Neo4j::Node] A CypherNode or EmbeddedNode
def _create_node(node_props, labels = labels_for_create)
query = "CREATE (n:#{Array(labels).join(':')}) SET n = {props} RETURN n"
Neo4j::ActiveBase.current_transaction.query(query, {props: node_props}, wrap_level: :core_entity).to_a[0].n
query = "CREATE (n:`#{Array(labels).join('`:`')}`) SET n = {props} RETURN n"
neo4j_query(query, {props: node_props}, wrap_level: :core_entity).to_a[0].n
end

# As the name suggests, this inserts the primary key (id property) into the properties hash.
Expand All @@ -89,6 +89,12 @@ def labels_for_create

private

def destroy_query
require 'pry'
binding.pry
query_as(:n).optional_match('(n)-[r]-()').delete(:n, :r)
end

# The pending associations are cleared during the save process, so it's necessary to
# build the processable hash before it begins. If there are nodes and associations that
# need to be created after the node is saved, a new transaction is started.
Expand Down Expand Up @@ -129,15 +135,15 @@ def create!(*args)
end

def merge(attributes)
neo4j_session.query.merge(n: {self.mapped_label_names => attributes})
neo4j_query.merge(n: {self.mapped_label_names => attributes})
.on_create_set(n: on_create_props(attributes))
.on_match_set(n: on_match_props)
.pluck(:n).first
end

def find_or_create(find_attributes, set_attributes = {})
on_create_attributes = set_attributes.reverse_merge(on_create_props(find_attributes))
neo4j_session.query.merge(n: {self.mapped_label_names => find_attributes})
neo4j_query.merge(n: {self.mapped_label_names => find_attributes})
.on_create_set(n: on_create_attributes)
.pluck(:n).first
end
Expand All @@ -154,7 +160,11 @@ def find_or_create_by!(attributes, &block)

def load_entity(id)
query = object_query_base(id).return(:n)
neo4j_session.query(query).first.n
neo4j_query(query).first.n
end

def query_as(neo_id, var = :n)
Neo4j::ActiveBase.new_query.match(var).where(var => {neo_id: neo_id})
end

private
Expand Down
4 changes: 2 additions & 2 deletions lib/neo4j/active_rel/initialize.rb
Expand Up @@ -19,8 +19,8 @@ def init_on_load(persisted_rel, from_node_id, to_node_id, type)
def init_on_reload(unwrapped_reloaded)
@attributes = nil
init_on_load(unwrapped_reloaded,
unwrapped_reloaded._start_node_id,
unwrapped_reloaded._end_node_id,
unwrapped_reloaded.start_node_id,
unwrapped_reloaded.end_node_id,
unwrapped_reloaded.rel_type)
self
end
Expand Down
13 changes: 10 additions & 3 deletions lib/neo4j/active_rel/persistence.rb
Expand Up @@ -54,8 +54,7 @@ def create_model
def query_as(var)
# This should query based on the nodes, not the rel neo_id, I think
# Also, picky point: Should the var be `n`?
Neo4j::Core::Query.new(session: Neo4j::ActiveBase.current_session)
.match("()-[#{var}]-()").where(var => {neo_id: neo_id})
self.class.query_as(neo_id, var)
end

module ClassMethods
Expand Down Expand Up @@ -88,7 +87,11 @@ def create_method
end

def load_entity(id)
Neo4j::Relationship.load(id)
query_as(id).pluck(:r).first
end

def query_as(neo_id, var = :r)
Neo4j::ActiveBase.new_query.match("()-[#{var}]-()").where(var => {neo_id: neo_id})
end
end

Expand All @@ -98,6 +101,10 @@ def create_method

private

def destroy_query
query_as(:r).delete(:r)
end

def validate_node_classes!
[from_node, to_node].each do |node|
type = from_node == node ? :_from_class : :_to_class
Expand Down
10 changes: 6 additions & 4 deletions lib/neo4j/active_rel/query.rb
Expand Up @@ -12,8 +12,10 @@ def find(id, session = self.neo4j_session)
end

# Loads the relationship using its neo_id.
def find_by_id(key, session = Neo4j::ActiveBase.current_session)
session.query.match('()-[r]-()').where('ID(r)' => key.to_i).limit(1).return(:r).first.r
def find_by_id(key, session = nil)
options = session ? {session: session} : {}
query ||= Neo4j::ActiveBase.new_query(options)
query.match('()-[r]-()').where('ID(r)' => key.to_i).limit(1).return(:r).first.r
end

# Performs a very basic match on the relationship.
Expand Down Expand Up @@ -47,12 +49,12 @@ def deprecation_warning!

def where_query
deprecation_warning!
Neo4j::Session.query.match("#{cypher_string(:outbound)}-[r1:`#{self._type}`]->#{cypher_string(:inbound)}")
Neo4j::ActiveBase.new_query.match("#{cypher_string(:outbound)}-[r1:`#{self._type}`]->#{cypher_string(:inbound)}")
end

def all_query
deprecation_warning!
Neo4j::Session.query.match("#{cypher_string}-[r1:`#{self._type}`]->#{cypher_string(:inbound)}")
Neo4j::ActiveBase.new_query.match("#{cypher_string}-[r1:`#{self._type}`]->#{cypher_string(:inbound)}")
end

def cypher_string(dir = :outbound)
Expand Down
4 changes: 2 additions & 2 deletions lib/neo4j/migration.rb
Expand Up @@ -75,7 +75,7 @@ def add_ids_to(model)
end

def idless_count(label, id_property)
Neo4j::Session.query.match(n: label).where("NOT has(n.#{id_property})").pluck('COUNT(n) AS ids').first
Neo4j::ActiveBase.new_query.match(n: label).where("NOT has(n.#{id_property})").pluck('COUNT(n) AS ids').first
end

def print_status(last_time_taken, max_per_batch, nodes_left)
Expand All @@ -94,7 +94,7 @@ def print_status(last_time_taken, max_per_batch, nodes_left)
def id_batch_set(label, id_property, new_ids, count)
tx = Neo4j::Transaction.new

Neo4j::Session.query("MATCH (n:`#{label}`) WHERE NOT has(n.#{id_property})
Neo4j::ActiveBase.current_session.query("MATCH (n:`#{label}`) WHERE NOT has(n.#{id_property})
with COLLECT(n) as nodes, #{new_ids} as ids
FOREACH(i in range(0,#{count - 1})|
FOREACH(node in [nodes[i]]|
Expand Down
22 changes: 7 additions & 15 deletions lib/neo4j/schema/operation.rb
@@ -1,10 +1,10 @@
module Neo4j
module Schema
class Operation
attr_reader :label_name, :property, :options
attr_reader :label, :property, :options

def initialize(label_name, property, options = default_options)
@label_name = label_name.to_sym
def initialize(label, property, options = default_options)
@label = label
@property = property.to_sym
@options = options
end
Expand All @@ -19,10 +19,6 @@ def create!
schema_query(:"create_#{type}")
end

def label_object
@label_object ||= Neo4j::Label.create(label_name)
end

def incompatible_operation_classes
self.class.incompatible_operation_classes
end
Expand All @@ -33,7 +29,7 @@ def drop!

def drop_incompatible!
incompatible_operation_classes.each do |clazz|
operation = clazz.new(label_name, property)
operation = clazz.new(@label, property)
operation.drop! if operation.exist?
end
end
Expand All @@ -53,11 +49,7 @@ def type
private

def schema_query(method)
# If there is a transaction going on, this could block
# So we run in a thread and it will go through at the next opportunity
Thread.new do
label_object.send(method, property, options, Neo4j::ActiveBase.schema_session)
end
label.send(method, property, options)
end
end

Expand All @@ -71,7 +63,7 @@ def type
end

def exist?
label_object.indexes[:property_keys].include?([property])
label.index?(property)
end
end

Expand All @@ -90,7 +82,7 @@ def create!
end

def exist?
Neo4j::Label.constraint?(label_name, property)
label.uniqueness_constraint?(property)
end

def default_options
Expand Down
18 changes: 18 additions & 0 deletions lib/neo4j/shared.rb
Expand Up @@ -9,13 +9,27 @@ module Shared

module ClassMethods
# TODO: Deprecate neo4j_session_name(name)

SelfDeprecation.:neo4j_session_name

def neo4j_session
Neo4j::ActiveBase.current_session
end

def current_transaction
Neo4j::ActiveBase.current_transaction
end

def neo4j_current_transaction_or_session
current_transaction || neo4j_session
end

# This should be used everywhere. Should make it easy
# to support a session-per-model system
def neo4j_query(*args)
puts 'querying...'
neo4j_current_transaction_or_session.query(*args)
end
end

included do
Expand All @@ -30,5 +44,9 @@ def self.i18n_scope
def declared_properties
self.class.declared_properties
end

def neo4j_query(*args)
self.class.neo4j_query(*args)
end
end
end

0 comments on commit 21c41ef

Please sign in to comment.