DB-Object

 view release on metacpan or  search on metacpan

lib/DB/Object.pm  view on Meta::CPAN


        local $@;
        my $sth_dbi = eval
        {
            local( $SIG{__DIE__} )  = sub{ };
            local( $SIG{__WARN__} ) = sub{ };
            $dbo->{dbh}->prepare_cached( $query, ( scalar( keys( %$prepare_options ) ) ? $prepare_options : () ) );
        };

        if( $@ )
        {
            $repo->unlock if( $repo );
            return( $self->error( "Error preparing cached SQL query: $@\nQuery was:\n$query" ) );
        }

        $sth->{sth} = $sth_dbi;
        $repo->unlock if( $repo );
    }

    # The statement is not cached anywhere, so we prepare it now
    if( !defined( $sth ) )
    {
        my $prepare_options = {};
        if( $q && $self->_is_a( $q, "${base_class}::Query" ) )
        {
            $prepare_options = $q->prepare_options->as_hash;
        }

        if( !( $sth = $dbo->prepare( $query, ( scalar( keys( %$prepare_options ) ) ? $prepare_options : () ) ) ) )
        {
            $repo->unlock if( $repo );
            return( $self->pass_error( $dbo->error ) );
        }

        # File cache (explicit mode only)
        if( $cache && $use_file_cache && $cache_file )
        {
            if( !$dbo->Module::Generic::serialise( $sth,
                file       => $cache_file,
                lock       => 1,
                serialiser => $serialiser,
            ) )
            {
                $repo->unlock if( $repo );
                return( $self->pass_error( $dbo->error ) );
            }
        }
        # If caching is off, but the query is a binded parameters' one,
        # make the current object hold the statement object
        elsif( $bind )
        {
            $self->{sth} = $sth;
        }
        $repo->unlock if( $repo );
    }
    else
    {
        $repo->unlock if( $repo );
    }

    # Ensure we unlock even if sth came from mem cache path where we unlocked earlier
    $repo->unlock if( $repo );

    # Attach query object to statement (this can be dangerous if the statement is long-lived;
    # keep your query object small / reset/dirty it aggressively)
    $sth->query_object( $q ) if( $dbo->_is_a( $q, "${base_class}::Query" ) );
    $sth->table_object( $self ) if( $self->isa( "${base_class}::Tables" ) );

    # Caching the query as a constant
    if( $q && $dbo->_is_object( $q ) && $q->isa( "${base_class}::Query" ) )
    {
        my $constant = $q->constant;
        if( $constant && scalar( keys( %$constant ) ) )
        {
            foreach my $k (qw( pack file line ))
            {
                return( $self->error( "Could not find the parameter \"$k\" in the constant query hash reference." ) ) if( !$constant->{ $k } );
            }

            # We temporarily not store the query object, and see if this affects positively the memory consumption.
            # $constant->{query_object} = $q;
            # $dbo->constant_queries_cache_set( $constant );
        }
    }

    return( $sth );
}

sub _check_connect_param
{
    my $self  = shift( @_ );
    my $param = shift( @_ );
    my $valid = $self->_connection_parameters( $param );
    my $opts  = $self->_connection_options( $param );
    foreach my $k ( keys( %$param ) )
    {
        # If it is not in the list and it does not start with an upper case; those are like RaiseError, AutoCommit, etc
        if( CORE::length( $param->{ $k } ) && !grep( /^$k$/, @$valid ) && !CORE::exists( $opts->{ $k } ) )
        {
            return( $self->error( "Invalid parameter '$k'." ) );
        }
    }
    my @opts_to_remove = keys( %$opts );
    CORE::delete( @$param{ @opts_to_remove } ) if( scalar( @opts_to_remove ) );
    $param->{opt} = $opts;
    $param->{database} = CORE::delete( $param->{db} ) if( !length( $param->{database} ) && $param->{db} );
    return( $param );
}

sub _check_default_option
{
    my $self = shift( @_ );
    my $opts = $self->_get_args_as_hash( @_ );
    # return( $self->error( "Provided option is not a hash reference." ) ) if( !$self->_is_hash( $opts ) );
    # This method should be superseded by an inherited class
    return( $opts );
}

# Simplistic clone by design. We do not want a recursive clone like Clone::clone()
sub _clone
{



( run in 1.077 second using v1.01-cache-2.11-cpan-39bf76dae61 )