Mongoose

 view release on metacpan or  search on metacpan

lib/Mongoose/Engine.pm  view on Meta::CPAN

        elsif ( $type->is_a_type_of('ArrayRef') ) {
            if ( defined $type->{type_parameter} ) {
                # ArrayRef[ parameter ]
                my $param = $type->{type_parameter};
                if ( my $param_class = $param->{class} ) {
                    my @objs;
                    for my $item ( @{ $doc->{$name} || [] } ) {
                        push @objs, $self->_expand_subtype( $param_class, $item, $scope );
                    }
                    $doc->{$name} = \@objs;
                }
                else {
                    $doc->{$name} ||= [];
                }
            }

            next;
        }
        elsif ( $type->is_a_type_of('DateTime') ) {
            $doc->{$name} = $doc->{$name}->as_datetime,
            next;
        }
        elsif( $type->is_a_type_of('FileHandle') ) {
            $doc->{$name} = Mongoose::File->new(
                file_id  => $doc->{$name}->id,
                bucket   => $self->db->gfs
            );
            next;
        }

        if( $class->can('meta') ) { # moose subobject

            if ( $class->does('Mongoose::EmbeddedDocument') ) {
                $doc->{$name} = bless $doc->{$name}, $class;
            }
            elsif ( $class->does('Mongoose::Document') ) {
                if ( ref $doc->{$name} eq 'BSON::DBRef' ) {
                    my $_id = $doc->{$name}->id;
                    if ( my $circ_doc = $scope->{"$_id"} ) {
                        $doc->{$name} = bless( $circ_doc , $class );
                        $scope->{ "$circ_doc->{_id}" } = $doc->{$name};
                    }
                    else {
                        $scope->{ "$doc->{_id}" } = $doc;
                        $doc->{$name} = $class->find_one({ _id=>$_id }, undef, $scope );
                    }
                }
            }
            elsif( $class->isa('Mongoose::Join') ) {
                my $ref_arr = delete( $doc->{$name} );
                my $ref_class = $type->type_parameter->class ;
                $doc->{$name} = bless {
                    class => $class_main, field => $name, parent => $doc->{_id},
                    with_class => $ref_class, children => $ref_arr, buffer => {}
                } => $class;
            }
        }
        else { #non-moose
            my $data = delete $doc->{$name};
            if ( my $data_class = ref $data ) {
                $doc->{$name} = $data_class eq 'boolean' ? $data : bless $data => $class;
            }
            else {
                push @later, { attrib => $name, value => $data };
            }
        }
    }

    return undef unless defined $doc;
    bless $doc => $class_main;
    for ( @later )  {
        my $attr = $class_main->meta->get_attribute($_->{attrib});
        if( defined $attr ) {
            # works for read-only values
            $attr->set_value($doc, $_->{value});
        } else {
            # sometimes get_attribute is undef, old method instead:
            my $meth = $_->{attrib};
            $doc->$meth($_->{value});
        }
    }

    $doc->expanded;
    $doc;
}

# Called after doc is expanded, a good point for some black magic
# Mostly needed to allow old mongoose document classes to
# manipulate dates on nested types.
sub expanded {}

sub _joint_fields {
    my $self = shift;
    return map { $_->name }
        grep { $_->type_constraint->isa('Mongoose::Join') }
        $self->meta->get_all_attributes;
}

sub fix_integrity {
    my ($self, @fields ) = @_;
    my $id = $self->_id;
    @fields = $self->_joint_fields unless scalar @fields;
    for my $field ( @fields ) {
        my @children = $self->$field->_children_refs;
        $self->collection->update( { _id=>$id }, { '$set'=>{ $field=>\@children } } );
    }
}

sub _unbless_full {
    require Data::Structure::Util;
    Data::Structure::Util::unbless( shift );
}

sub save { _save(@_) }
sub _save {
    my ( $self, @scope ) = @_;
    my $coll = $self->collection;
    my $doc = $self->collapse( @scope );
    return unless defined $doc;

    if ( my $id = $self->_id ) { ## update on my id
        my $ret = $coll->replace_one( { _id => $id }, $doc, { upsert => 1 } );
        return $id;
    }
    else {
        if ( ref Mongoose->class_config($self)->{pk} ) {
            # if we have a pk and no _id, we must have a new
            # document, so we insert to allow the pk constraint
            # to ensure uniqueness; the 'safe' parameter ensures
            # an exception is thrown on a duplicate

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.224 second using v1.00-cache-2.02-grep-82fe00e-cpan-1925d2aa809 )