[Rt-commit] [svn] r1771 - in DBIx-SearchBuilder/trunk: .
SearchBuilder t
jesse at pallas.eruditorum.org
jesse at pallas.eruditorum.org
Wed Nov 10 01:58:16 EST 2004
Author: jesse
Date: Wed Nov 10 01:58:15 2004
New Revision: 1771
Modified:
DBIx-SearchBuilder/trunk/ (props changed)
DBIx-SearchBuilder/trunk/Changes
DBIx-SearchBuilder/trunk/SearchBuilder.pm
DBIx-SearchBuilder/trunk/SearchBuilder/Record.pm
DBIx-SearchBuilder/trunk/t/01records.t
Log:
r8977 at tinbook: jesse | 2004-11-10T06:59:18.707372Z
- SearchBuilder now truncates strings before inserting them into character
types in the database as mysql generally does. Additionally, it truncates
things at utf8 character boundaries...as mysql does not.
Modified: DBIx-SearchBuilder/trunk/Changes
==============================================================================
--- DBIx-SearchBuilder/trunk/Changes (original)
+++ DBIx-SearchBuilder/trunk/Changes Wed Nov 10 01:58:15 2004
@@ -10,8 +10,11 @@
- Refactoring of DBIx::SearchBuilder::Record::Cachable for performance
improvement
- Added a FlushCache method to DBIx::SearchBuilder::Record::Cachable.
-
- Started to flesh out a...test suite
+ - SearchBuilder now truncates strings before inserting them into character
+ types in the database as mysql generally does. Additionally, it truncates
+ things at utf8 character boundaries...as mysql does not.
+
1.12
Modified: DBIx-SearchBuilder/trunk/SearchBuilder.pm
==============================================================================
--- DBIx-SearchBuilder/trunk/SearchBuilder.pm (original)
+++ DBIx-SearchBuilder/trunk/SearchBuilder.pm Wed Nov 10 01:58:15 2004
@@ -5,7 +5,7 @@
use strict;
use vars qw($VERSION);
-$VERSION = "1.12";
+$VERSION = "1.13_01";
=head1 NAME
Modified: DBIx-SearchBuilder/trunk/SearchBuilder/Record.pm
==============================================================================
--- DBIx-SearchBuilder/trunk/SearchBuilder/Record.pm (original)
+++ DBIx-SearchBuilder/trunk/SearchBuilder/Record.pm Wed Nov 10 01:58:15 2004
@@ -632,10 +632,12 @@
sub __Set {
my $self = shift;
- my %args = ( 'Field' => undef,
- 'Value' => undef,
- 'IsSQL' => undef,
- @_ );
+ my %args = (
+ 'Field' => undef,
+ 'Value' => undef,
+ 'IsSQL' => undef,
+ @_
+ );
$args{'Column'} = $args{'Field'};
$args{'IsSQLFunction'} = $args{'IsSQL'};
@@ -648,64 +650,86 @@
unless ( defined( $args{'Column'} ) && $args{'Column'} ) {
$ret->as_array( 0, 'No column specified' );
- $ret->as_error( errno => 5,
- do_backtrace => 0,
- message => "No column specified" );
- return ($ret->return_value);
+ $ret->as_error(
+ errno => 5,
+ do_backtrace => 0,
+ message => "No column specified"
+ );
+ return ( $ret->return_value );
}
my $column = lc $args{'Column'};
- if ( ( defined $self->__Value($column) )
- and ( $args{'Value'} eq $self->__Value($column) ) ) {
+ if ( ( defined $self->__Value($column) )
+ and ( $args{'Value'} eq $self->__Value($column) ) )
+ {
$ret->as_array( 0, "That is already the current value" );
- $ret->as_error( errno => 1,
- do_backtrace => 0,
- message => "That is already the current value" );
- return ($ret->return_value);
+ $ret->as_error(
+ errno => 1,
+ do_backtrace => 0,
+ message => "That is already the current value"
+ );
+ return ( $ret->return_value );
}
elsif ( !defined( $args{'Value'} ) ) {
$ret->as_array( 0, "No value passed to _Set" );
- $ret->as_error( errno => 2,
- do_backtrace => 0,
- message => "No value passed to _Set" );
- return ($ret->return_value);
+ $ret->as_error(
+ errno => 2,
+ do_backtrace => 0,
+ message => "No value passed to _Set"
+ );
+ return ( $ret->return_value );
}
- else {
- my $method = "Validate" . $args{'Column'};
- unless ( $self->$method( $args{'Value'} ) ) {
- $ret->as_array( 0, 'Illegal value for ' . $args{'Column'} );
- $ret->as_error(errno => 3,
- do_backtrace => 0,
- message => "Illegal value for " . $args{'Column'}
- );
- return ($ret->return_value);
- }
- $args{'Table'} = $self->Table();
- $args{'PrimaryKeys'} = { $self->PrimaryKeys() };
- my $val = $self->_Handle->UpdateRecordValue(%args);
- unless ($val) {
- $ret->as_array( 0,
- $args{'Column'}
- . " could not be set to "
- . $args{'Value'} . "." );
- $ret->as_error( errno => 4,
- do_backtrace => 0,
- message => $args{'Column'}
- . " could not be set to "
- . $args{'Value'} . "." );
- return ($ret->return_value);
- }
- if ( $args{'IsSQLFunction'} ) {
- $self->Load( $self->Id );
- }
- else {
- $self->{'values'}->{"$column"} = $args{'Value'};
- }
+ # First, we truncate the value, if we need to.
+ #
+
+
+ my $value = $self->TruncateValue ( $args{'Column'}, $args{'Value'});
+ unless ($value eq $args{'Value'}) {
+ $args{'OriginalValue'} = $args{'Value'};
+ $args{'Value'} = $value;
+ }
+
+
+
+ my $method = "Validate" . $args{'Column'};
+ unless ( $self->$method( $args{'Value'} ) ) {
+ $ret->as_array( 0, 'Illegal value for ' . $args{'Column'} );
+ $ret->as_error(
+ errno => 3,
+ do_backtrace => 0,
+ message => "Illegal value for " . $args{'Column'}
+ );
+ return ( $ret->return_value );
+ }
+
+ $args{'Table'} = $self->Table();
+ $args{'PrimaryKeys'} = { $self->PrimaryKeys() };
+
+ my $val = $self->_Handle->UpdateRecordValue(%args);
+ unless ($val) {
+ my $message =
+ $args{'Column'} . " could not be set to " . $args{'Value'} . "." ;
+ $ret->as_array( 0, $message);
+ $ret->as_error(
+ errno => 4,
+ do_backtrace => 0,
+ message => $message
+ );
+ return ( $ret->return_value );
+ }
+ # If we've performed some sort of "functional update"
+ # then we need to reload the object from the DB to know what's
+ # really going on. (ex SET Cost = Cost+5)
+ if ( $args{'IsSQLFunction'} ) {
+ $self->Load( $self->Id );
+ }
+ else {
+ $self->{'values'}->{"$column"} = $args{'Value'};
}
$ret->as_array( 1, "The new value has been set." );
- return ($ret->return_value);
+ return ( $ret->return_value );
}
# }}}
@@ -733,6 +757,58 @@
# }}}
+# {{{ sub TruncateValue
+
+=head2 TruncateValue KEY VALUE
+
+Truncate a value that's about to be set so that it will fit inside the database'
+s idea of how big the column is.
+
+(Actually, it looks at searchbuilder's concept of the database, not directly into the db).
+
+=cut
+
+sub TruncateValue {
+ my $self = shift;
+ my $key = shift;
+ my $value = shift;
+
+ my $metadata = $self->_ClassAccessible->{$key};
+
+ my $truncate_to;
+ if ( $metadata->{'length'} && !$metadata->{'is_numeric'} ) {
+ $truncate_to = $metadata->{'length'};
+ }
+ elsif ( $metadata->{'type'} =~ /char\((\d+)\)/ ) {
+ $truncate_to = $1;
+ }
+
+ return ($value) unless ($truncate_to); # don't need to truncate
+
+ # Perl 5.6 didn't speak unicode
+ return substr( $value, 0, $truncate_to ) unless ( $] >= 5.007 );
+
+ require Encode;
+
+ if ( Encode::is_utf8($value) ) {
+ return Encode::decode(
+ utf8 => substr( Encode::encode( utf8 => $value ), 0, $truncate_to ),
+ Encode::FB_QUIET(),
+ );
+ }
+ else {
+ return Encode::encode(
+ utf8 => Encode::decode(
+ utf8 => substr( $value, 0, $truncate_to ),
+ Encode::FB_QUIET(),
+ )
+ );
+
+ }
+
+}
+# }}}
+
# {{{ sub _Object
=head2 _Object
@@ -1026,6 +1102,11 @@
my ($key);
foreach $key ( keys %attribs ) {
my $method = "Validate$key";
+
+ #Truncate things that are too long for their datatypes
+ my $value = $self->TruncateValue ($key => $attribs{$key});
+ $attribs{$key} = $value unless ($value eq $attribs{$key});
+
unless ( $self->$method( $attribs{$key} ) ) {
delete $attribs{$key};
}
Modified: DBIx-SearchBuilder/trunk/t/01records.t
==============================================================================
--- DBIx-SearchBuilder/trunk/t/01records.t (original)
+++ DBIx-SearchBuilder/trunk/t/01records.t Wed Nov 10 01:58:15 2004
@@ -44,6 +44,47 @@
is($rec->Name, 'Obra', "We did actually change the name");
+# Validate truncation on update
+
+($val,$msg) = $rec->SetName('1234567890123456789012345678901234567890');
+
+ok($val, $msg) ;
+
+is($rec->Name, '12345678901234', "Truncated on update");
+
+
+
+# Test unicode truncation:
+my $univalue = "這是個測試";
+
+($val,$msg) = $rec->SetName($univalue.$univalue);
+
+ok($val, $msg) ;
+
+is($rec->Name, '這是個測');
+
+
+
+# make sure we do _not_ truncate things which should not be truncated
+($val,$msg) = $rec->SetEmployeeId('1234567890');
+
+ok($val, $msg) ;
+
+is($rec->EmployeeId, '1234567890', "Did not truncate id on create");
+
+# make sure we do truncation on create
+my $newrec = TestApp::Address->new($handle);
+my $newid = $newrec->Create( Name => '1234567890123456789012345678901234567890',
+ EmployeeId => '1234567890' );
+
+$newrec->Load($newid);
+
+ok ($newid, "Created a new record");
+is($newrec->Name, '12345678901234', "Truncated on create");
+is($newrec->EmployeeId, '1234567890', "Did not truncate id on create");
+
+
+
package TestApp::Address;
use base qw/DBIx::SearchBuilder::Record/;
@@ -62,7 +103,7 @@
id =>
{read => 1, type => 'int(11)', default => ''},
Name =>
- {read => 1, write => 1, type => 'varchar(36)', default => ''},
+ {read => 1, write => 1, type => 'varchar(14)', default => ''},
Phone =>
{read => 1, write => 1, type => 'varchar(18)', default => ''},
EmployeeId =>
More information about the Rt-commit
mailing list