58 lines
2.1 KiB
Ruby
58 lines
2.1 KiB
Ruby
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
|