Skip to content

Commit

Permalink
Auto Commit should be optional. It can now be enabled by requiring th…
Browse files Browse the repository at this point in the history
…e neo4j/auto_tx instead of neo4j [#44]
  • Loading branch information
andreas committed Jun 16, 2009
1 parent 7c0271c commit 5762bf2
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 68 deletions.
37 changes: 19 additions & 18 deletions README.rdoc
Expand Up @@ -27,6 +27,7 @@ It uses two powerful and mature java libraries:
* Twitter - http://twitter.com/ronge
* API Yard Documentation - http://neo4j.rubyforge.org/
* Source repo - git://github.com/andreasronge/neo4j.git
* Mailing list - https://lists.neo4j.org/mailman/listinfo/user

=== Presentation Materials and other URLs
* Ruby Manor 2008 - Jonathan Conway: http://jaikoo.com/assets/presentations/neo4j.pdf
Expand Down Expand Up @@ -90,6 +91,17 @@ Example of creating a neo4j node:

Almost all Neo4j operation must be wrapped in a transaction as shown above.
In the following examples we assume that the operations are inside an Neo4j transaction.
Neo4j.rb supports auto commits without wrapping Neo4j operations in Neo4j::Transactions.
To enable that require the file 'neo4j/auto_tx' instead of 'neo4j'

Example

require 'neo4j/auto_tx'

# no need to wrap operations in Neo4j::Transaction.run do .. end
Node.new

This feature should be used for testing and development purpose.

=== Setting Properties

Expand Down Expand Up @@ -1130,8 +1142,6 @@ Notice there is also a otherway of finding nodes, see the Neo4j::NodeMixin#trave
=== Transactions

All operations that work with the node space (even read operations) must be wrapped in a transaction.
Luckly neo4j.rb will automatically create a transaction for those operation that needs it if one is not already provided.

For example all get, set and find operations will start a new transaction if none is already not runnig (for that thread).

If you want to perform a set of operation in a single transaction, use the Neo4j::Transaction.run method:
Expand All @@ -1143,21 +1153,8 @@ Example
node2.bar = "hi"
}

There is also a TransactionalMixin that lets you declare which method should be wrapped inside a transaction.
Example:

class Person
include Neo4j::NodeMixin
extend Neo4j::TransactionalMixin

property :name, :age

def do_stuff
# ... no transaction stuff needed to be written here.
end

transactional :do_stuff
end
There is also a auto commit feature available which is enabled by requiring 'neo4j/auto_tx' instead of 'neo4j',
see the three minutes tutorial above.

==== Rollback

Expand Down Expand Up @@ -1195,7 +1192,7 @@ For example to index the proeprties foo and bar

Everytime a node of type SomeNode (or a subclass) is create, deleted or updated the lucene index of will be updated.

=== Updating Lucene Index
=== Reindexing

Sometimes it's neccessarly to change the index of a class after alot of node instances already have been created.
To delete an index use the class method 'remove_index'
Expand Down Expand Up @@ -1227,6 +1224,10 @@ In order to use the update_index method you must include the reindexer neo4j.rb
This extensions will keep a relationship to each created node so that it later can recreate
the index by traversing those relationships.

=== Updating Lucene Index

The lucene index will be updated after the transaction commits. It is not possible to
query for something that has been created inside the same transaction as where the query is performed.

=== Quering (using lucene)

Expand Down
5 changes: 5 additions & 0 deletions lib/neo4j/auto_tx.rb
@@ -0,0 +1,5 @@

NEO4J_AUTO_TX = true
loaded = require 'neo4j'
puts "LOADED" if loaded
puts "NOT LOADED" unless loaded
1 change: 1 addition & 0 deletions lib/neo4j/extensions/tx_tracker.rb
Expand Up @@ -57,6 +57,7 @@ def on_property_changed(node, key, old_value, new_value)

def undo_tx
tx_node = tx_nodes.first
return if (tx_node.nil?)
tracked_node_id = tx_node[:tracked_node_id]

if (tx_node[:created])
Expand Down
5 changes: 3 additions & 2 deletions lib/neo4j/mixins/transactional.rb
Expand Up @@ -2,12 +2,13 @@ module Neo4j

#
# Includes support for wrapping a method in a Neo4j transaction.
# If the constant NEO4J_AUTO_TX is defined then the specified methods will be wrapped in a transaction.
#
module TransactionalMixin

def transactional(*methods)
return
# return unless (Neo4j::Config[:auto_tx])
return unless defined? NEO4J_AUTO_TX
puts "transactional: #{methods.inspect}"
methods.each do |name|
orig_name = (name.to_s == '<<') ? '_append' : "_original_#{name}"
self.send :alias_method, orig_name, name
Expand Down
11 changes: 2 additions & 9 deletions lib/neo4j/relationships/has_list.rb
Expand Up @@ -16,7 +16,6 @@ def initialize(node, type, &filter)
#
# :api: public
def <<(other)
Neo4j::Transaction.run do
# does node have a relationship ?
if (@node.relationship?(@type))
# get that relationship
Expand All @@ -31,35 +30,28 @@ def <<(other)
# the first node will be set
@node.relationships.outgoing(@type) << other
end
end
end

# Returns true if the list is empty
#
# :api: public
def empty?
Transaction.run do
!iterator.hasNext
end
end

def first
Transaction.run do
iter = iterator
return nil unless iter.hasNext
n = iter.next
Neo4j.load(n.get_id)
end
end

def each
Neo4j::Transaction.run do
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.load(n.get_id)
end
end
end
def iterator
stop_evaluator = org.neo4j.api.core.StopEvaluator::END_OF_GRAPH
Expand All @@ -70,10 +62,11 @@ def iterator
types_and_dirs << org.neo4j.api.core.Direction::OUTGOING
@node.internal_node.traverse(traverser_order, stop_evaluator, returnable_evaluator, types_and_dirs.to_java(:object)).iterator
end

transactional :empty?, :<<
end



end

end
6 changes: 2 additions & 4 deletions lib/neo4j/relationships/has_n.rb
Expand Up @@ -70,9 +70,7 @@ def new(other)
from, to = @node, other
from, to = to, from unless @info[:outgoing]

r = Neo4j::Transaction.run {
from.internal_node.createRelationshipTo(to.internal_node, @type)
}
r = from.internal_node.createRelationshipTo(to.internal_node, @type)
from.class.relationships_info[@type.name.to_sym][:relationship].new(r)
end

Expand Down Expand Up @@ -106,7 +104,7 @@ def <<(other)
end


transactional :<<
transactional :<<, :new
end

end
Expand Down
25 changes: 12 additions & 13 deletions lib/neo4j/relationships/node_traverser.rb
Expand Up @@ -8,6 +8,7 @@ class IllegalTraversalArguments < StandardError;
# Contains state about one specific traversal to be performed.
class NodeTraverser
include Enumerable
extend TransactionalMixin

attr_reader :internal_node

Expand Down Expand Up @@ -71,25 +72,21 @@ def both(*types)
end

def empty?
Neo4j::Transaction.run {!iterator.hasNext}
!iterator.hasNext
end

def first
Neo4j::Transaction.run do
iter = iterator
return nil unless iter.hasNext
n = iter.next
Neo4j.load(n.get_id)
end
iter = iterator
return nil unless iter.hasNext
n = iter.next
Neo4j.load(n.get_id)
end

def each
Neo4j::Transaction.run do
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.load(n.get_id)
end
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.load(n.get_id)
end
end

Expand All @@ -107,6 +104,8 @@ def to_s
"NodeTraverser [direction=#{@direction}, type=#{@type}]"
end


transactional :empty?, :first
end


Expand Down
1 change: 0 additions & 1 deletion lib/neo4j/relationships/relationship.rb
Expand Up @@ -9,7 +9,6 @@ module Relationships
class Relationship
extend Neo4j::TransactionalMixin
include Neo4j::RelationshipMixin
# include Neo4j::DynamicAccessorMixin
end
end
end
22 changes: 10 additions & 12 deletions lib/neo4j/relationships/relationship_traverser.rb
Expand Up @@ -5,6 +5,7 @@ module Relationships
#
class RelationshipTraverser
include Enumerable
extend TransactionalMixin

attr_reader :internal_node

Expand Down Expand Up @@ -49,15 +50,13 @@ def both(type = nil)
#
# :api: public
def <<(other_node)
Transaction.run do
type = Relationships::RelationshipType.instance(@type.to_s)
rel = @internal_node.createRelationshipTo(other_node.internal_node, type)
Neo4j.instance.load_relationship(rel)
end
type = Relationships::RelationshipType.instance(@type.to_s)
rel = @internal_node.createRelationshipTo(other_node.internal_node, type)
Neo4j.instance.load_relationship(rel)
end

def empty?
Neo4j::Transaction.run {!iterator.hasNext}
!iterator.hasNext
end

# Return the first relationship or nil
Expand All @@ -77,12 +76,10 @@ def [](other_node)


def each
Neo4j::Transaction.run do
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.instance.load_relationship(n)
end
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.instance.load_relationship(n)
end
end

Expand Down Expand Up @@ -123,6 +120,7 @@ def each
end
end

transactional :empty?, :<<
end


Expand Down
20 changes: 11 additions & 9 deletions test/neo4j/node_lucene_spec.rb
Expand Up @@ -52,7 +52,7 @@ class TestNode
describe "Neo4j & Lucene Transaction Synchronization:" do
before(:all) do
start
Neo4j.load_reindexer
Neo4j.load_reindexer
undefine_class :TestNode
class TestNode
include Neo4j::NodeMixin
Expand Down Expand Up @@ -127,7 +127,7 @@ class TestNode
describe "A node with no lucene index" do
before(:all) do
start
Neo4j.load_reindexer
Neo4j.load_reindexer
class TestNodeWithNoIndex
include Neo4j::NodeMixin
end
Expand All @@ -148,7 +148,7 @@ class TestNodeWithNoIndex
describe "Find with sorting" do
before(:all) do
start
Neo4j.load_reindexer
Neo4j.load_reindexer
undefine_class :Person7
class Person7
include Neo4j::NodeMixin
Expand Down Expand Up @@ -198,7 +198,7 @@ def init_node(name, city)
describe "Find Nodes using Lucene and tokenized index" do
before(:all) do
start
Neo4j.load_reindexer
Neo4j.load_reindexer
undefine_class :Person
class Person
include Neo4j::NodeMixin
Expand Down Expand Up @@ -276,7 +276,7 @@ def to_s
describe "Find nodes using Lucene" do
before(:all) do
start
Neo4j.load_reindexer
Neo4j.load_reindexer
class TestNode
include Neo4j::NodeMixin
property :name, :age, :male, :height
Expand Down Expand Up @@ -370,8 +370,10 @@ class TestNode
found.size.should == 1

# when
TestNode.remove_index(:name)
TestNode.update_index
Neo4j::Transaction.run do
TestNode.remove_index(:name)
TestNode.update_index
end

# then
found = TestNode.find(:name => 'foo2')
Expand All @@ -382,7 +384,7 @@ class TestNode
before(:each) do
undefine_class :PersonNode
start
Neo4j.load_reindexer
Neo4j.load_reindexer
class PersonNode
include Neo4j::NodeMixin
property :name
Expand Down Expand Up @@ -416,7 +418,7 @@ class PersonNode
before(:each) do
undefine_class :PersonNode
start
Neo4j.load_reindexer
Neo4j.load_reindexer
class PersonNode
include Neo4j::NodeMixin
property :name
Expand Down

0 comments on commit 5762bf2

Please sign in to comment.