DB-Object

 view release on metacpan or  search on metacpan

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

        }
    }
    return( $self );
}

sub elements { return( shift->_set_get_object_without_init( 'elements', 'DB::Object::Query::Elements', @_ ) ); }

# The field name
sub field { return( shift->_set_get_scalar_or_object( 'field', 'DB::Object::Fields::Field', @_ ) ); }

sub fo
{
    my $self = shift( @_ );
    if( @_ )
    {
        return( $self->error( "Value provided for method fo() in class ", ref( $self ), " is not a DB::Object::Fields::Field object." ) ) if( !$self->_is_a( $_[0] => 'DB::Object::Fields::Field' ) );
        $self->{fo} = shift( @_ );
    }
    return( $self->{fo} ) if( $self->{fo} );
    my $f = $self->field;
    my $fo;
    if( $self->_is_a( $f => 'DB::Object::Fields::Field' ) )
    {
        $fo = $f;
    }
    elsif( defined( $f ) && CORE::length( $f // '' ) )
    {
        $fo = $self->query_object->table_object->fields( $f );
    }
    $self->{fo} = $fo if( defined( $fo ) );
    return( $self->new_null ) if( !defined( $fo ) && Wanted::want( 'OBJECT' ) );
    return( $fo );
}

# The formatting for insert, e.g.: field = value, or possibly field = ?, or even field = $1
sub format { return( shift->_set_get_scalar_as_object( 'format', @_ ) ); }

# The generic representation of this element if we want to bind data to it
sub generic { return( shift->_set_get_scalar_as_object( 'generic', @_ ) ); }

# If this is a numbered placeholder
sub index { return( shift->_set_get_number( { field => 'index', undef_ok => 1 }, @_ ) ); }

# sub is_numbered { return( shift->_set_get_boolean( 'is_numbered', @_ ) ); }
sub is_numbered
{
    my $self = shift( @_ );
    my $placeholder = $self->placeholder;
    return(0) if( !defined( $placeholder ) );
    my $placeholder_re = $self->query_object->database_object->_placeholder_regexp;
    if( $placeholder =~ /^$placeholder_re$/ && defined( $+{index} ) )
    {
        return(1);
    }
    return(0);
}

# The placeholder, such as ?, $2, ?2, or others supported by the driver
sub placeholder { return( shift->_set_get_scalar_as_object({
    field => 'placeholder',
    callbacks => 
    {
        set => sub
        {
            # $val is a scalar object (Module::Generic::Scalar)
            my( $self, $val ) = @_;
            my $placeholder_re = $self->query_object->database_object->_placeholder_regexp;
            return( $val ) if( $self->_is_scalar( $val ) && $self->_can( $val => 'defined' ) && !$val->defined );
            if( defined( $val ) && "$val" =~ /^(?:$placeholder_re)$/ )
            {
                # Could be undef
                $self->index( $+{index} );
            }
            else
            {
                $self->index( undef );
            }
            return( $val );
        }
    }
}, @_ ) ); }

sub query_object { return( shift->_set_get_object( 'query_object', 'DB::Object::Query', @_ ) ); }

# The field data type to be used when binding parameters
# sub type { return( shift->_set_get_scalar_as_object( 'type', @_ ) ); }
sub type { return( shift->_set_get_scalar_as_object( { field => 'type', callbacks => 
{
    get => sub
    {
        my( $self, $val ) = @_;
        my $field = $self->field;
        if( ( !defined( $val ) || !$val->defined || !CORE::length( $val // '' ) ) &&
            $self->_is_a( $field => 'DB::Object::Fields::Field' ) )
        {
            $val = $field->datatype->constant;
        }
        return( $val );
    }
}}, @_ ) ); }

# The value to bind, if any at all. So could be undef
sub value { return( shift->_set_get_scalar_as_object( 'value', @_ ) ); }

sub FREEZE
{
    my $self       = CORE::shift( @_ );
    my $serialiser = CORE::shift( @_ ) // '';
    my $class      = CORE::ref( $self );

    # We keep a strict allow-list to avoid accidentally freezing DBI handles or other
    # process-local state.
    my @props = @{$self->{_fields}};

    my $hash = {};
    foreach my $prop ( @props )
    {
        if( CORE::exists( $self->{ $prop } ) &&
            defined( $self->{ $prop } ) &&
            CORE::ref( $self->{ $prop } ) ne 'CODE' )
        {
            $hash->{ $prop } = $self->{ $prop };
        }
    }

    # Return an array reference rather than a list so this works with Sereal and CBOR.
    # Before Sereal version 4.023, Sereal did not support multiple values returned.
    if( $serialiser eq 'Sereal' )
    {
        require Sereal::Encoder;
        require version;

        if( version->parse( Sereal::Encoder->VERSION ) < version->parse( '4.023' ) )
        {
            CORE::return( [$class, $hash] );
        }
    }

    # But Storable wants a list with the first element being the serialised element
    CORE::return( $class, $hash );
}

sub STORABLE_freeze { return( shift->FREEZE( @_ ) ); }

sub STORABLE_thaw { return( shift->THAW( @_ ) ); }

sub THAW



( run in 3.664 seconds using v1.01-cache-2.11-cpan-5735350b133 )