Project

General

Profile

Download (2.11 KB) Statistics
| Branch: | Tag: | Revision:
module Puppet::Parser::Functions
newfunction(:mysql_deepmerge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
Recursively merges two or more hashes together and returns the resulting hash.

For example:

$hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } }
$hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } }
$merged_hash = mysql_deepmerge($hash1, $hash2)
# The resulting hash is equivalent to:
# $merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } }

When there is a duplicate key that is a hash, they are recursively merged.
When there is a duplicate key that is not a hash, the key in the rightmost hash will "win."
When there are conficting uses of dashes and underscores in two keys (which mysql would otherwise equate),
the rightmost style will win.

ENDHEREDOC

if args.length < 2
raise Puppet::ParseError, ("mysql_deepmerge(): wrong number of arguments (#{args.length}; must be at least 2)")
end

result = Hash.new
args.each do |arg|
next if arg.is_a? String and arg.empty? # empty string is synonym for puppet's undef
# If the argument was not a hash, skip it.
unless arg.is_a?(Hash)
raise Puppet::ParseError, "mysql_deepmerge: unexpected argument type #{arg.class}, only expects hash arguments"
end

# Now we have to traverse our hash assigning our non-hash values
# to the matching keys in our result while following our hash values
# and repeating the process.
overlay( result, arg )
end
return( result )
end
end

def has_normalized!(hash, key)
return true if hash.has_key?( key )
return false unless key.match(/-|_/)
other_key = key.include?('-') ? key.gsub( '-', '_' ) : key.gsub( '_', '-' )
return false unless hash.has_key?( other_key )
hash[key] = hash.delete( other_key )
return true;
end

def overlay( hash1, hash2 )
hash2.each do |key, value|
if(has_normalized!( hash1, key ) and value.is_a?(Hash) and hash1[key].is_a?(Hash))
overlay( hash1[key], value )
else
hash1[key] = value
end
end
end
(1-1/3)