Skip to content

Instantly share code, notes, and snippets.

@karupanerura
Created September 2, 2011 01:28
Show Gist options
  • Save karupanerura/1187738 to your computer and use it in GitHub Desktop.
Save karupanerura/1187738 to your computer and use it in GitHub Desktop.
DBIx::Skinny::Utils::CondMerge
package DBIx::Skinny::Utils::CondMerge;
use strict;
use warnings;
use Hash::Merge;
our @EXPORT_OK = qw/skinny_cond_merge/;
use Exporter::Lite;
### XXX: 全てのケースを試したわけではないのでバグあるかも
Hash::Merge::specify_behavior(
+{
'SCALAR' => +{
'SCALAR' => sub {
[-and => $_[0], $_[1]];
},
'ARRAY' => sub {
($_[1][0] eq '-and') ?
[ @{$_[1]}, $_[0] ] :
[ -and => $_[0], @{$_[1]} ];
},
'HASH' => sub {
[-and => $_[0], $_[1]];
},
},
'ARRAY' => +{
'SCALAR' => sub {
($_[0][0] eq '-and') ?
[ @{$_[0]}, $_[1] ] :
[ -and => @{$_[0]}, $_[1] ];
},
'ARRAY' => sub {
[-and => +{'IN' => $_[0]}, +{'IN' => $_[1]} ];
},
'HASH' => sub {
($_[0][0] eq '-and') ?
[ @{$_[0]}, $_[1] ]:
[-and => +{'IN' => $_[0]}, $_[1]];
},
},
'HASH' => +{
'SCALAR' => sub {
[-and => $_[0], $_[1]];
},
'ARRAY' => sub {
($_[1][0] eq '-and') ?
[ @{$_[1]}, $_[0] ]:
[-and => +{'IN' => $_[1]}, $_[0]];
},
'HASH' => sub {
[-and => $_[0], $_[1]];
},
},
}
, 'DBIx::SkinnyRule'
);
sub skinny_cond_merge {
my @conds = @_;
return shift(@conds) if(@conds == 1);
my %merged = %{ shift(@conds) };
foreach my $cond (@conds) {
foreach my $key (%$cond) {
if (exists($merged{$key}) and exists($cond->{$key})) {
$merged{$key} = Hash::Merge::_merge_hashes(+{ $key => $merged{$key} }, +{ $key => $cond->{$key} })->{$key};
}
elsif (exists($cond->{$key})) {
$merged{$key} = $cond->{$key};
}
}
}
return \%merged;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment