1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#!perl -w
# Test the COPY functionality
use Test::More;
use DBI;
use strict;
$|=1;
if (defined $ENV{DBI_DSN}) {
plan tests => 26;
} else {
plan skip_all => 'Cannot run test unless DBI_DSN is defined. See the README file';
}
my $dbh = DBI->connect($ENV{DBI_DSN}, $ENV{DBI_USER}, $ENV{DBI_PASS},
{RaiseError => 1, PrintError => 0, AutoCommit => 0});
ok( defined $dbh, "Connect to database for bytea testing");
my ($sth,$count,$result,$expected,@data);
my $pglibversion = $dbh->{pg_lib_version};
my $pgversion = $dbh->{pg_server_version};
my $table = 'dbd_pg_test4';
## (Re)create a second test table with few columns to test a "bare" COPY
## (7.2 does not allow column names in the COPY statement)
my $schema = DBD::Pg::_pg_use_catalog($dbh);
my $SQL = "SELECT COUNT(*) FROM pg_class WHERE relname=?";
if ($schema) {
$schema = exists $ENV{DBD_SCHEMA} ? $ENV{DBD_SCHEMA} : 'public';
$dbh->do("SET search_path TO " . $dbh->quote_identifier($schema));
$SQL = "SELECT COUNT(*) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n ".
"WHERE c.relnamespace=n.oid AND c.relname=? AND n.nspname=".
$dbh->quote($schema);
}
$sth = $dbh->prepare($SQL);
$sth->execute($table);
$count = $sth->fetchall_arrayref()->[0][0];
if (1==$count) {
$dbh->do(sprintf "DROP TABLE %s$table", $schema ? "$schema." : '');
}
$dbh->do(qq{CREATE TABLE $table(id2 integer, val2 text)});
$dbh->commit();
#
# Test of the pg_putline and pg_endcopy methods
#
## pg_putline should fail unless we are in a COPY IN state
eval {
$dbh->pg_putline("12\tMulberry");
};
ok($@, 'pg_putline fails when issued without a preceding COPY command');
$dbh->do("COPY $table FROM STDIN");
$result = $dbh->pg_putline("12\tMulberry\n");
is($result,1,'putline returned a value of 1 for success');
$result = $dbh->pg_putline("13\tStrawberry\n");
is($result,1,'putline returned a value of 1 for success');
$result = $dbh->pg_putline("14\tBlueberry\n");
is($result,1,'putline returned a value of 1 for success');
## Commands are not allowed while in a COPY IN state
eval {
$dbh->do("SELECT 'dbdpg_copytest'");
};
ok($@, 'do() fails while in a COPY IN state');
## pg_getline is not allowed as we are in a COPY_IN state
$data[0] = '';
eval {
$dbh->pg_getline($data[0], 100);
};
ok($@, 'pg_getline fails while in a COPY IN state');
$result = $dbh->pg_endcopy();
is($result,1,'pg_endcopy returned a 1');
## Make sure we can issue normal commands again
$dbh->do("SELECT 'dbdpg_copytest'");
## Make sure we are out of the COPY IN state and pg_putline no longer works
eval {
$dbh->pg_putline("16\tBlackberry");
};
ok($@, 'pg_putline fails when issued after pg_endcopy called');
## Check that our lines were inserted properly
$expected = [[12 => 'Mulberry'],[13 => 'Strawberry'],[14 => 'Blueberry']];
$result = $dbh->selectall_arrayref("SELECT id2,val2 FROM $table ORDER BY id2");
is_deeply( $result, $expected, 'putline inserted values correctly');
# pg_endcopy should not work because we are no longer in a COPY state
eval {
$dbh->pg_endcopy;
};
ok($@, 'pg_endcopy fails when called twice after COPY IN');
$dbh->commit();
#
# Test of the pg_getline method
#
SKIP: {
skip "Cannot test pg_getline with DBD::Pg compiled with pre-7.4 libraries", 12 if $pglibversion < 70400;
## pg_getline should fail unless we are in a COPY OUT state
eval {
$dbh->pg_getline($data[0], 100);
};
ok($@, 'pg_getline fails when issued without a preceding COPY command');
$dbh->do("COPY $table TO STDOUT");
my ($buffer,$badret,$badval) = ('',0,0);
$result = $dbh->pg_getline($data[0], 100);
is ($result, 1, 'pg_getline returned a 1');
## Commands are not allowed while in a COPY OUT state
eval {
$dbh->do("SELECT 'dbdpg_copytest'");
};
ok($@, 'do() fails while in a COPY OUT state');
## pg_putline is not allowed as we are in a COPY OUT state
eval {
$dbh->pg_putline("99\tBogusberry");
};
ok($@, 'pg_putline fails while in a COPY OUT state');
$data[1]=$data[2]=$data[3]='';
$result = $dbh->pg_getline($data[1], 100);
is ($result, 1, 'pg_getline returned a 1');
$result = $dbh->pg_getline($data[2], 100);
is ($result, 1, 'pg_getline returned a 1');
$result = $dbh->pg_getline($data[3], 100);
is ($result, '', 'pg_getline returns empty on final call');
$result = \@data;
$expected = ["12\tMulberry\n","13\tStrawberry\n","14\tBlueberry\n",""];
is_deeply( $result, $expected, 'getline returned all rows successfuly');
## Make sure we can issue normal commands again
$dbh->do("SELECT 'dbdpg_copytest'");
## Make sure we are out of the COPY OUT state and pg_getline no longer works
eval {
$data[5]='';
$dbh->pg_getline($data[5], 100);
};
ok($@, 'pg_getline fails when issued after pg_endcopy called');
## pg_endcopy should fail because we are no longer in a COPY state
eval {
$dbh->pg_endcopy;
};
ok($@, 'pg_endcopy fails when called twice after COPY OUT');
SKIP2: {
skip "Cannot test commit copy reset with pre-7.4 servers", 2 if $pgversion < 70400 or $pglibversion < 70400;
#
# Make sure rollback and commit reset our internal copystate tracking
#
$dbh->do("COPY $table TO STDOUT");
$dbh->commit();
eval {
$dbh->do("SELECT 'dbdpg_copytest'");
};
ok(!$@, 'commit resets COPY state');
$dbh->do("COPY $table TO STDOUT");
$dbh->rollback();
eval {
$dbh->do("SELECT 'dbdpg_copytest'");
};
ok(!$@, 'rollback resets COPY state');
} ## end SKIP2
} ## end SKIP
#
# Keep oldstyle calls around for backwards compatibility
#
$dbh->do("COPY $table FROM STDIN");
$result = $dbh->func("13\tOlive\n", 'putline');
is ($result, 1, "old-style dbh->func('text', 'putline') still works");
$dbh->pg_endcopy;
$dbh->do("COPY $table TO STDOUT");
$result = $dbh->func($data[0], 100, 'getline');
is ($result, 1, "old-style dbh->func(var, length, 'getline') still works");
1 while ($result = $dbh->func($data[0], 100, 'getline'));
$dbh->do("DROP TABLE $table");
$dbh->commit();
ok( $dbh->disconnect(), 'Disconnect from database');
|