Skip to content

Commit

Permalink
Release 0.0.12 fix for Neo4j::Config used by Rails
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasronge committed Apr 19, 2012
1 parent ccaba2b commit a4ac3bd
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 6 deletions.
1 change: 1 addition & 0 deletions lib/neo4j-core.rb
Expand Up @@ -60,6 +60,7 @@ module Neo4j

require 'neo4j-core/cypher/cypher'
require 'neo4j-core/cypher/result_wrapper'
require 'neo4j-core/hash_with_indifferent_access'

require 'neo4j/algo'
require 'neo4j/cypher'
Expand Down
165 changes: 165 additions & 0 deletions lib/neo4j-core/hash_with_indifferent_access.rb
@@ -0,0 +1,165 @@
module Neo4j
module Core
# Stolen from http://as.rubyonrails.org/classes/HashWithIndifferentAccess.html
# We don't want to depend on active support
class HashWithIndifferentAccess < Hash

# Always returns true, so that <tt>Array#extract_options!</tt> finds members of this class.
def extractable_options?
true
end

def with_indifferent_access
dup
end

def nested_under_indifferent_access
self
end

def initialize(constructor = {})
if constructor.is_a?(Hash)
super()
update(constructor)
else
super(constructor)
end
end

def default(key = nil)
if key.is_a?(Symbol) && include?(key = key.to_s)
self[key]
else
super
end
end

def self.new_from_hash_copying_default(hash)
new(hash).tap do |new_hash|
new_hash.default = hash.default
end
end

alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
alias_method :regular_update, :update unless method_defined?(:regular_update)

# Assigns a new value to the hash:
#
# hash = HashWithIndifferentAccess.new
# hash[:key] = "value"
#
def []=(key, value)
regular_writer(convert_key(key), convert_value(value))
end

alias_method :store, :[]=

# Updates the instantized hash with values from the second:
#
# hash_1 = HashWithIndifferentAccess.new
# hash_1[:key] = "value"
#
# hash_2 = HashWithIndifferentAccess.new
# hash_2[:key] = "New Value!"
#
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
#
def update(other_hash)
if other_hash.is_a? HashWithIndifferentAccess
super(other_hash)
else
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
self
end
end

alias_method :merge!, :update

# Checks the hash for a key matching the argument passed in:
#
# hash = HashWithIndifferentAccess.new
# hash["key"] = "value"
# hash.key? :key # => true
# hash.key? "key" # => true
#
def key?(key)
super(convert_key(key))
end

alias_method :include?, :key?
alias_method :has_key?, :key?
alias_method :member?, :key?

# Fetches the value for the specified key, same as doing hash[key]
def fetch(key, *extras)
super(convert_key(key), *extras)
end

# Returns an array of the values at the specified indices:
#
# hash = HashWithIndifferentAccess.new
# hash[:a] = "x"
# hash[:b] = "y"
# hash.values_at("a", "b") # => ["x", "y"]
#
def values_at(*indices)
indices.collect {|key| self[convert_key(key)]}
end

# Returns an exact copy of the hash.
def dup
self.class.new(self).tap do |new_hash|
new_hash.default = default
end
end

# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash.
# Does not overwrite the existing hash.
def merge(hash)
self.dup.update(hash)
end

# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
def reverse_merge(other_hash)
super self.class.new_from_hash_copying_default(other_hash)
end

def reverse_merge!(other_hash)
replace(reverse_merge( other_hash ))
end

# Removes a specified key from the hash.
def delete(key)
super(convert_key(key))
end

def stringify_keys!; self end
def stringify_keys; dup end
# undef :symbolize_keys!
def symbolize_keys; to_hash.symbolize_keys end
def to_options!; self end

# Convert to a Hash with String keys.
def to_hash
Hash.new(default).merge!(self)
end

protected
def convert_key(key)
key.kind_of?(Symbol) ? key.to_s : key
end

def convert_value(value)
if value.is_a? Hash
value #.nested_under_indifferent_access
elsif value.is_a?(Array)
value.dup.replace(value.map { |e| convert_value(e) })
else
value
end
end
end

end
end
2 changes: 1 addition & 1 deletion lib/neo4j-core/version.rb
@@ -1,5 +1,5 @@
module Neo4j
module Core
VERSION = "0.0.11"
VERSION = "0.0.12"
end
end
6 changes: 3 additions & 3 deletions lib/neo4j/config.rb
Expand Up @@ -37,7 +37,7 @@ def default_file=(file_path)
# @return [Hash] the default file loaded by yaml
def defaults
require 'yaml'
@defaults ||= YAML.load_file(default_file)
@defaults ||= Neo4j::Core::HashWithIndifferentAccess.new(YAML.load_file(default_file))
end

# @return [String] the expanded path of the Config[:storage_path] property
Expand All @@ -56,7 +56,7 @@ def storage_path
# @yield config
# @yieldparam [Neo4j::Config] config - this configuration class
def use
@configuration ||= {}
@configuration ||= Neo4j::Core::HashWithIndifferentAccess.new
yield @configuration
nil
end
Expand Down Expand Up @@ -125,7 +125,7 @@ def to_java_map

# @return The a new configuration using default values as a hash.
def setup()
@configuration = {}
@configuration = Neo4j::Core::HashWithIndifferentAccess.new
@configuration.merge!(defaults)
@configuration
end
Expand Down
5 changes: 3 additions & 2 deletions lib/neo4j/neo4j.rb
Expand Up @@ -71,9 +71,10 @@ def started_db
db
end

# @return [String, nil] the current storage path of a running neo4j database. If the database is not running it returns nil.
# If the database is not running it returns Neo4j::Config.storage_path otherwise it asks the database
# @return [String] the current storage path of the database
def storage_path
return nil unless db.running?
return Neo4j::Config.storage_path unless db.running?
db.storage_path
end

Expand Down
16 changes: 16 additions & 0 deletions spec/neo4j/config_spec.rb
Expand Up @@ -44,6 +44,22 @@
end
end

describe "Using string and Symbols as keys" do
it "does not matter" do
Neo4j::Config[:blabla] = 'foo_bar'
Neo4j::Config["blabla"].should == 'foo_bar'

Neo4j::Config["blabla2"] = 'foo_bar2'
Neo4j::Config[:blabla2].should == 'foo_bar2'

Neo4j::Config.setup.merge!(:kalle => 'foo', 'sune' => 'bar')
Neo4j::Config[:kalle].should == 'foo'
Neo4j::Config["kalle"].should == 'foo'
Neo4j::Config[:sune].should == 'bar'
Neo4j::Config["sune"].should == 'bar'
end
end

describe "#to_java_map" do
it "returns a java map" do
Neo4j::Config.to_java_map.java_class.to_s.should == "java.util.HashMap"
Expand Down

0 comments on commit a4ac3bd

Please sign in to comment.