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 )