MQUL
view release on metacpan or search on metacpan
lib/MQUL.pm view on Meta::CPAN
##############################################
# _has_adv_que( \%hash ) #
# ========================================== #
# $hash - the hash-ref to search in #
# ------------------------------------------ #
# returns true if the hash-ref has any of #
# the lang's advanced query operators #
##############################################
sub _has_adv_que {
my $hash = shift;
foreach (
'$gt', '$gte', '$lt', '$lte', '$all', '$exists', '$mod',
'$eq', '$ne', '$in', '$nin', '$size', '$type'
)
{
return 1 if exists $hash->{$_};
}
return;
}
##############################################
# _value_in( $value, \@array ) #
# ========================================== #
# $value - the value to check for #
# $array - the array to search in #
# ------------------------------------------ #
# returns true if the value is one of the #
# values from the array. #
##############################################
sub _value_in {
my ( $value, $array ) = @_;
foreach (@$array) {
next if is_float($_) && !is_float($value);
next if !is_float($_) && is_float($value);
return 1 if is_float($_) && $value == $_;
return 1 if !is_float($_) && $value eq $_;
}
return;
}
=head2 update_doc( \%document, \%update )
Receives a document hash-ref and an update hash-ref, and updates the
document in-place according to the update hash-ref. Also returns the document
after the update. If the update hash-ref doesn't have any of the update
modifiers described by the language, then the update hash-ref is considered
as what the document should now be, and so will simply replace the document
hash-ref (once again, in accordance with MongoDB).
See L<MQUL::Reference/"UPDATE STRUCTURE"> to learn about the structure of
update hash-refs.
=cut
sub update_doc {
my ( $doc, $obj ) = @_;
croak "MQUL::update_doc() requires a document hash-ref."
unless defined $doc && ref $doc && ref $doc eq 'HASH';
croak "MQUL::update_doc() requires an update hash-ref."
unless defined $obj && ref $obj && ref $obj eq 'HASH';
# we only need to do something if the $obj hash-ref has any advanced
# update operations, otherwise $obj is meant to be the new $doc
if ( &_has_adv_upd($obj) ) {
foreach my $op ( keys %$obj ) {
if ( $op eq '$inc' ) {
# increase numerically
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
$doc->{$field} ||= 0;
$doc->{$field} += $obj->{$op}->{$field};
}
} elsif ( $op eq '$set' ) {
# set key-value pairs
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
$doc->{$field} = $obj->{$op}->{$field};
}
} elsif ( $op eq '$unset' ) {
# remove key-value pairs
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
delete $doc->{$field} if $obj->{$op}->{$field};
}
} elsif ( $op eq '$rename' ) {
# rename attributes
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
$doc->{ $obj->{$op}->{$field} } = delete $doc->{$field}
if exists $doc->{$field};
}
} elsif ( $op eq '$push' ) {
# push values to end of arrays
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
croak "The $field attribute is not an array in the doc."
if defined $doc->{$field}
&& ref $doc->{$field} ne 'ARRAY';
$doc->{$field} ||= [];
push( @{ $doc->{$field} }, $obj->{$op}->{$field} );
}
} elsif ( $op eq '$pushAll' ) {
# push a list of values to end of arrays
next unless ref $obj->{$op} eq 'HASH';
foreach my $field ( keys %{ $obj->{$op} } ) {
croak "The $field attribute is not an array in the doc."
if defined $doc->{$field}
( run in 0.871 second using v1.01-cache-2.11-cpan-5a3173703d6 )