[DBD::Pg 2/8] Add support for UTF-8 statement strings
dbdpg-commits-gENoVmVU/[email protected] Wed, 21 May 2014 15:35:11 +0000
| Newsgroups | gmane.comp.db.postgresql.dbdpg.cvs |
|---|---|
| Message-ID | <[email protected]> |
Committed by =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <[email protected]> Subject: [DBD::Pg 2/8] Add support for UTF-8 statement strings --- dbdimp.c | 5 ++++- dbdimp.h | 4 ++-- t/30unicode.t | 58 ++++++++++++++++++++++++++++++++++++---------------------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/dbdimp.c b/dbdimp.c index fed72bd..59e2f61 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -1530,13 +1530,16 @@ SV * pg_db_pg_notifies (SV * dbh, imp_dbh_t * imp_dbh) /* ================================================================== */ -int dbd_st_prepare (SV * sth, imp_sth_t * imp_sth, char * statement, SV * attribs) +int dbd_st_prepare_sv (SV * sth, imp_sth_t * imp_sth, SV * statement_sv, SV * attribs) { dTHX; D_imp_dbh_from_sth; STRLEN mypos=0, wordstart, newsize; /* Used to find and set firstword */ SV **svp; /* To help parse the arguments */ + statement_sv = pg_rightgraded_sv(aTHX_ statement_sv, imp_dbh->client_encoding_utf8); + char *statement = SvPV_nolen(statement_sv); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin dbd_st_prepare (statement: %s)\n", THEADER_slow, statement); if ('\0' == *statement) diff --git a/dbdimp.h b/dbdimp.h index abc082a..5e4f72f 100644 --- a/dbdimp.h +++ b/dbdimp.h @@ -158,8 +158,8 @@ int dbd_st_STORE_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv, SV * valuesv #define dbd_discon_all pg_discon_all int dbd_discon_all (SV * drh, imp_drh_t * imp_drh); -#define dbd_st_prepare pg_st_prepare -int dbd_st_prepare (SV * sth, imp_sth_t * imp_sth, char * statement, SV * attribs); +#define dbd_st_prepare_sv pg_st_prepare_sv +int dbd_st_prepare_sv (SV * sth, imp_sth_t * imp_sth, SV * statement_sv, SV * attribs); #define dbd_bind_ph pg_bind_ph int dbd_bind_ph (SV * sth, imp_sth_t * imp_sth, SV * ph_name, SV * newvalue, IV sql_type, SV * attribs, int is_inout, IV maxlen); diff --git a/t/30unicode.t b/t/30unicode.t index ad45fc5..bec7d12 100644 --- a/t/30unicode.t +++ b/t/30unicode.t @@ -9,7 +9,7 @@ use strict; use warnings; use utf8; use charnames ':full'; -use Encode; +use Encode qw(encode_utf8); use Test::More; use lib 't','.'; require 'dbdpg_test_setup.pl'; @@ -29,33 +29,47 @@ my $name_d = my $name_u = "\N{LATIN CAPITAL LETTER E WITH ACUTE}milie du Ch\N{LA utf8::downgrade($name_d); utf8::upgrade($name_u); +# Before 5.12.0 the text to the left of => gets to be SvUTF8() under use utf8; +# even if it's plain ASCII. This would confuse what we test for below. foreach ( - [upgraded => text => $name_u], - [downgraded => text => $name_d], + [upgraded => 'text' => $name_u], + [downgraded => 'text' => $name_d], [upgraded => 'text[]' => [$name_u]], [downgraded => 'text[]' => [$name_d]], [mixed => 'text[]' => [$name_d,$name_u]], ) { my ($state, $type, $value) = @$_; - $dbh->{pg_enable_utf8} = 1; - - my $SQL = "SELECT ?::$type"; - my $sth = $dbh->prepare($SQL); - $sth->execute($value); - my $result = $sth->fetchall_arrayref->[0][0]; - $t = "Fetching $state UTF-8 $type from the database returns proper value"; - is_deeply ($result, $value, $t); - $t = "Fetching $state UTF-8 $type from the database returns string with UTF-8 flag on"; - ok (utf8::is_utf8($_), $t) for (ref $result ? @{$result} : $result); - - $dbh->{pg_enable_utf8} = 0; - $sth->execute($value); - $result = $sth->fetchall_arrayref->[0][0]; - $t = "Fetching $state UTF-8 $type from the database returns proper string (pg_enable_utf8=0)"; - utf8::encode($_) for (ref $value ? @{$value} : $value); - is_deeply ($result, $value, $t); - $t = "Fetching $state UTF-8 $type from the database returns string with UTF-8 flag off (pg_enable_utf8=0)"; - ok (!utf8::is_utf8($result), $t) for (ref $result ? @{$result} : $result); + foreach ( + [placeholder => "SELECT ?::$type", $value], + (($type eq 'text') ? ( + [interpolated => "SELECT '$value'::$type"], + ):()), + ) { + foreach my $enable_utf8 (1, 0) { + my ($qtype, $sql, @args) = @$_; + my $desc = "$state UTF-8 $qtype $type (pg_enable_utf8=$enable_utf8)"; + is(utf8::is_utf8($sql), ($state eq 'upgraded'), "$desc query has correct flag") + if $qtype eq 'interpolated'; + if ($state ne 'mixed') { + foreach my $arg (map { ref($_) ? @{$_} : $_ } @args) { + is(utf8::is_utf8($arg), ($state eq 'upgraded'), "$desc arg has correct flag") + } + } + $dbh->{pg_enable_utf8} = $enable_utf8; + + my $sth = $dbh->prepare($sql); + $sth->execute(@args); + my $result = $sth->fetchall_arrayref->[0][0]; + my $return_value = + $enable_utf8 ? $value : + ref $value ? [ map encode_utf8($_), @{$value} ] : + encode_utf8($value); + $t = "$desc returns proper value"; + is_deeply ($result, $return_value, $t); + $t = "$desc returns string with correct UTF-8 flag "; + is(utf8::is_utf8($_), !!$enable_utf8, $t) for (ref $result ? @{$result} : $result); + } + } } $t = 'Generated string is not utf8'; -- 1.8.4