From ac746b12d9b0d4d6eef635939b2517bfe731943d Mon Sep 17 00:00:00 2001 From: Max De Marzi Date: Mon, 4 Jun 2012 08:23:07 -0500 Subject: [PATCH] moving to Oj parser, batch gremlin support, streaming cypher, still need to get streaming batch working --- lib/neography.rb | 4 +++- lib/neography/config.rb | 4 +++- lib/neography/crack_parser.rb | 7 ------ lib/neography/oj_parser.rb | 8 +++++++ lib/neography/rest.rb | 18 +++++++++++++-- neography.gemspec | 2 +- spec/integration/rest_batch_spec.rb | 35 ++++++++++++++++++++++++++++- spec/integration/streaming_spec.rb | 19 ++++++++++++++++ 8 files changed, 84 insertions(+), 13 deletions(-) delete mode 100644 lib/neography/crack_parser.rb create mode 100644 lib/neography/oj_parser.rb create mode 100644 spec/integration/streaming_spec.rb diff --git a/lib/neography.rb b/lib/neography.rb index b279d15..24b136a 100644 --- a/lib/neography.rb +++ b/lib/neography.rb @@ -19,12 +19,14 @@ def find_and_require_user_defined_code require 'crack' require 'httparty' require 'json' +require 'oj' require 'logger' require 'ostruct' require 'os' require 'zip/zipfilesystem' -require 'neography/crack_parser' +require 'neography/oj_parser' + require 'neography/config' require 'neography/rest' require 'neography/neography' diff --git a/lib/neography/config.rb b/lib/neography/config.rb index fd9d384..643a53f 100644 --- a/lib/neography/config.rb +++ b/lib/neography/config.rb @@ -15,6 +15,8 @@ class << self; attr_accessor :protocol, :server, :port, :directory, :cypher_path @authentication = {} @username = nil @password = nil - @parser = {:parser => CrackParser} + #@parser = {:parser => YajlParser} + #@parser = {:parser => CrackParser} + @parser = {:parser => OjParser} end end \ No newline at end of file diff --git a/lib/neography/crack_parser.rb b/lib/neography/crack_parser.rb deleted file mode 100644 index c1c35ed..0000000 --- a/lib/neography/crack_parser.rb +++ /dev/null @@ -1,7 +0,0 @@ -class CrackParser < HTTParty::Parser - - protected - def json - Crack::JSON.parse(body) - end -end \ No newline at end of file diff --git a/lib/neography/oj_parser.rb b/lib/neography/oj_parser.rb new file mode 100644 index 0000000..94ebd82 --- /dev/null +++ b/lib/neography/oj_parser.rb @@ -0,0 +1,8 @@ +class OjParser < HTTParty::Parser + + protected + def json + #Oj::Doc.parse(body) + Oj.load(body) + end +end \ No newline at end of file diff --git a/lib/neography/rest.rb b/lib/neography/rest.rb index f9e818e..3fd05db 100644 --- a/lib/neography/rest.rb +++ b/lib/neography/rest.rb @@ -392,7 +392,7 @@ def get_shortest_weighted_path(from, to, relationships, weight_attr='weight', de end def execute_query(query, params = {}) - options = { :body => {:query => query, :params => params}.to_json, :headers => {'Content-Type' => 'application/json'} } + options = { :body => {:query => query, :params => params}.to_json, :headers => {'Content-Type' => 'application/json', 'Accept' => 'application/json;stream=true'} } result = post(@cypher_path, options) end @@ -407,10 +407,19 @@ def batch(*args) Array(args).each_with_index do |c,i| batch << {:id => i}.merge(get_batch(c)) end - options = { :body => batch.to_json, :headers => {'Content-Type' => 'application/json'} } + options = { :body => batch.to_json, :headers => {'Content-Type' => 'application/json', 'Accept' => 'application/json;stream=true'} } post("/batch", options) end + def batch_not_streaming(*args) + batch = [] + Array(args).each_with_index do |c,i| + batch << {:id => i}.merge(get_batch(c)) + end + options = { :body => batch.to_json, :headers => {'Content-Type' => 'application/json'} } + post("/batch", options) + end + # For testing (use a separate neo4j instance) # call this before each test or spec def clean_database(sanity_check = "not_really") @@ -456,6 +465,11 @@ def get_batch(args) {:method => "GET", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{args[3]}"} when :get_node_relationships {:method => "GET", :to => "/node/#{get_id(args[1])}/relationships/#{args[2] || 'all'}"} + when :execute_script + {:method => "POST", :to => @gremlin_path, :body => {:script => args[1], :params => args[2]}} + # execute_query returning "exception => java.lang.NullPointerException" + when :execute_query + {:method => "POST", :to => @cypher_path, :body => {:query => args[1], :params => args[2]}} else raise "Unknown option #{args[0]}" end diff --git a/neography.gemspec b/neography.gemspec index 7f00a8d..a70427c 100644 --- a/neography.gemspec +++ b/neography.gemspec @@ -22,10 +22,10 @@ Gem::Specification.new do |s| s.add_development_dependency "rspec" s.add_development_dependency "net-http-spy", "0.2.1" s.add_development_dependency "rake", "~> 0.8.7" - s.add_dependency "crack", "0.1.8" s.add_dependency "httparty", "0.8.1" s.add_dependency "rake", ">= 0.8.7" s.add_dependency "json" s.add_dependency "os" s.add_dependency "rubyzip" + s.add_dependency "oj" end diff --git a/spec/integration/rest_batch_spec.rb b/spec/integration/rest_batch_spec.rb index 2f34abd..a31346d 100644 --- a/spec/integration/rest_batch_spec.rb +++ b/spec/integration/rest_batch_spec.rb @@ -202,7 +202,6 @@ existing_index.first["self"].should == new_node["self"] @neo.remove_node_from_index(index_name, key, value, new_node) end - end it "can get a node index" do index_name = generate_text(6) @@ -235,6 +234,40 @@ batch_result.first["body"].first["end"].split('/').last.should == node2["self"].split('/').last end + it "can batch gremlin" do + batch_result = @neo.batch [:execute_script, "g.v(0)"] + batch_result.first.should have_key("id") + batch_result.first.should have_key("from") + batch_result.first["body"]["self"].split('/').last.should == "0" + end + + it "can batch gremlin with parameters" do + new_node = @neo.create_node + id = new_node["self"].split('/').last + batch_result = @neo.batch [:execute_script, "g.v(id)", {:id => id.to_i}] + batch_result.first.should have_key("id") + batch_result.first.should have_key("from") + batch_result.first["body"]["self"].split('/').last.should == id + end + + it "can batch cypher" do + batch_result = @neo.batch [:execute_query, "start n=node(0) return n"] + batch_result.first.should have_key("id") + batch_result.first.should have_key("from") + pending "exception => java.lang.NullPointerException" + end + + it "can batch cypher with parameters" do + new_node = @neo.create_node + id = new_node["self"].split('/').last + batch_result = @neo.batch [:execute_script, "start n=node({id}) return n", {:id => id.to_i}] + batch_result.first.should have_key("id") + batch_result.first.should have_key("from") + pending "exception => java.lang.NullPointerException" + end + + end + describe "referenced batch" do it "can create a relationship from two newly created nodes" do batch_result = @neo.batch [:create_node, {"name" => "Max"}], [:create_node, {"name" => "Marc"}], [:create_relationship, "friends", "{0}", "{1}", {:since => "high school"}] diff --git a/spec/integration/streaming_spec.rb b/spec/integration/streaming_spec.rb new file mode 100644 index 0000000..abb9d60 --- /dev/null +++ b/spec/integration/streaming_spec.rb @@ -0,0 +1,19 @@ +require File.join(File.dirname(__FILE__), '..', 'spec_helper') + +describe Neography::Rest do + before(:each) do + @neo = Neography::Rest.new + end + + it "can batch a bunch of nodes streaming" do + commands = 500.times.collect{|x| [:create_node, {:name => "node-#{x}"}]} + Benchmark.bm do |x| + x.report("batch ") { @new_nodes = @neo.batch_not_streaming *commands } + x.report("streaming batch ") { @new_nodes_streaming = @neo.batch *commands } + end + @new_nodes.should_not be_nil + @new_nodes_streaming.should_not be_nil + pending + end + +end \ No newline at end of file