Permalink
Browse files

Add support for {ReadOnly}, with tests and docs.

Bump version to 2.9.0
Other minor fixes.
  • Loading branch information...
1 parent e2c65b0 commit 6418b9da7b9b69995251694c79f6b538f7a9e9ef Greg Sabino Mullane committed Jul 27, 2008
Showing with 132 additions and 23 deletions.
  1. +1 −1 .perlcriticrc
  2. +6 −2 Changes
  3. +3 −3 META.yml
  4. +1 −1 Makefile.PL
  5. +11 −3 Pg.pm
  6. +3 −3 README
  7. +3 −3 README.dev
  8. +38 −1 dbdimp.c
  9. +1 −0 dbdimp.h
  10. +1 −1 lib/Bundle/DBD/Pg.pm
  11. +54 −5 t/02attribs.t
  12. +10 −0 t/99_spellcheck.t
View
@@ -2,7 +2,7 @@ verbose = 9
profile-strictness = quiet
[Documentation::PodSpelling]
-stop_words = ActiveKids AutoCommit boolean Bunce CachedKids ChildHandles ChopBlanks CompatMode CursorName DBD DBI Datatype dbdpg enum ErrCount FetchHashKeyName HandleError HandleSetErr InactiveDestroy LongReadLen LongTruncOk Mergl Momjian Mullane NULLABLE OID ParamValues ParamTypes PgBouncer pgend pglibpq pglogin pgprefix pgquote pgstart PGSERVICE PGSYSCONFDIR perl Postgres PostgreSQL PrintError PrintWarn README RaiseError RowCache RowCacheSize RowsInCache SQL SQLSTATE SSL STDIN STDERR STDOUT Sabino Savepoints ShowErrorStatement TaintIn TaintOut TraceLevel UTF Username afterwards arrayrefs attr autocommit backend bitmask bytea cancelled datatype dbd dbh errstr fd filename getfd getline hashref largeobject len libpq lseg pgbuiltin pgsql runtime savepoint savepoints schemas sslmode tablename tablespace tablespaces tuple typename username varchar undef Perlish arrayref datatypes bool func PID dr
+stop_words = ActiveKids AutoCommit boolean Bunce CachedKids ChildHandles ChopBlanks CompatMode CursorName DBD DBI Datatype dbdpg enum ErrCount FetchHashKeyName HandleError HandleSetErr InactiveDestroy LongReadLen LongTruncOk Mergl Momjian Mullane NULLABLE OID ParamValues ParamTypes PgBouncer pgend pglibpq pglogin pgprefix pgquote pgstart PGSERVICE PGSYSCONFDIR perl Postgres PostgreSQL PrintError PrintWarn README RaiseError RowCache RowCacheSize RowsInCache SQL SQLSTATE SSL STDIN STDERR STDOUT Sabino Savepoints ShowErrorStatement TaintIn TaintOut TraceLevel UTF Username afterwards arrayrefs attr autocommit backend bitmask bytea cancelled datatype dbd dbh errstr fd filename getfd getline hashref largeobject len libpq lseg pgbuiltin pgsql runtime savepoint savepoints schemas sslmode tablename tablespace tablespaces tuple typename username varchar undef Perlish arrayref datatypes bool func PID dr ReadOnly
[-Bangs::ProhibitCommentedOutCode]
[-Bangs::ProhibitFlagComments]
View
@@ -1,10 +1,14 @@
('GSM' is Greg Sabino Mullane, greg@turnstep.com)
-2.8.8
+2.9.0
+ - Add support for database handle attribute "ReadOnly". This allows
+ use of $dbh->{ReadOnly} = 1 to enforce read only mode at
+ the server level. [GSM]
- Move PQexec structures to statement handle, to prevent
excessive malloc and free within execute function. [GSM]
- - More testing tweaks.
+ - Add more attribute tests, improve testing system.
+ - Many documentation improvements.
2.8.7 Released July 24, 2008 (subversion r11582)
View
@@ -1,6 +1,6 @@
--- #YAML:1.0
name : DBD-Pg
-version : 2.8.8
+version : 2.9.0
abstract : DBI PostgreSQL interface
author:
- Greg Sabino Mullane <greg@turnstep.com>
@@ -38,10 +38,10 @@ configure_requires:
provides:
DBD::Pg:
file : Pg.pm
- version : 2.8.8
+ version : 2.9.0
Bundle::DBD::Pg:
file : lib/Bundle/DBD/Pg.pm
- version : 2.8.8
+ version : 2.9.0
keywords:
- Postgres
View
@@ -7,7 +7,7 @@ use warnings;
use 5.006001;
## No version.pm for this one, as the prereqs are not loaded yet.
-my $VERSION = '2.8.8';
+my $VERSION = '2.9.0';
my $lib;
BEGIN {
View
14 Pg.pm
@@ -17,7 +17,7 @@ use 5.006001;
{
package DBD::Pg;
- use version; our $VERSION = qv('2.8.8');
+ use version; our $VERSION = qv('2.9.0');
use DBI ();
use DynaLoader ();
@@ -1696,7 +1696,7 @@ DBD::Pg - PostgreSQL database driver for the DBI module
=head1 VERSION
-This documents version 2.8.8 of the DBD::Pg module
+This documents version 2.9.0 of the DBD::Pg module
=head1 DESCRIPTION
@@ -1831,7 +1831,7 @@ an alternate port and host:
@data_sources = $dbh->data_sources('port=5824;host=example.com');
-=head1 METHODS COMMON TO ALL HANDLES
+=head2 Methods Common To All Handles
For all of the methods below, B<$h> can be either a database handle (B<$dbh>)
or a statement handle (B<$sth>). Note that I<$dbh> and I<$sth> can be replaced with
@@ -3008,6 +3008,14 @@ elsewhere in this document.
DBD::Pg specific attribute. If true, boolean values will be returned
as the characters 't' and 'f' instead of '1' and '0'.
+=head3 B<ReadOnly> (boolean)
+
+$dbh->{ReadOnly} = 1;
+
+Specifies if the current database connection should be in read-only mode or not.
+In this mode, changes that change the database are not allowed and will throw
+an error. Note: this method will B<not> work if L</AutoCommit> is true.
+
=head3 B<Name> (string, read-only)
Returns the name of the current database.
View
6 README
@@ -6,7 +6,7 @@ DBD::Pg -- the DBI PostgreSQL interface for Perl
DESCRIPTION:
------------
-This is version 2.8.8 of DBD::Pg, the Perl interface to Postgres using DBI.
+This is version 2.9.0 of DBD::Pg, the Perl interface to Postgres using DBI.
The web site for this interface, and the latest version, can be found at:
http://search.cpan.org/dist/DBD-Pg/
@@ -62,7 +62,7 @@ REQUIREMENTS:
DBD::Pg needs to know where to find the libpq libraries: this is usually done
by checking the output of the pg_config executable. If pg_config is not available,
then you may need to install the development package for PostgreSQL. To do this
-on Debian and ubuntu, use: apt-get install postgresql-dev; on RedHat and CentOS,
+on Debian and Ubuntu, use: apt-get install postgresql-dev; on RedHat and CentOS,
use: yum install postgresql-devel. Note that the development libraries are needed
even if you already have PostgreSQL up and running.
@@ -95,7 +95,7 @@ If the script cannot find the pg_config information itself, it will
ask you for the path to it. Enter the complete path to the pg_config
file here, including the name of the file itself.
-yTESTING:
+TESTING:
--------
The tests rely on being able to connect to a valid Postgres database.
View
@@ -77,7 +77,7 @@ SIGNATURE - Checksum verification via PGP, generated by Module::Signature.
Makefile.PL - The main file that starts everything off. Used by ExtUtils::MakeMaker
to create the "Makefile". This file contains a version number.
-Makefile - Generated automatically by Makefile.PL. Not part of the dsitribution.
+Makefile - Generated automatically by Makefile.PL. Not part of the distribution.
META.yml - YAML description file. Updated by hand and contains a version number in three places.
@@ -386,7 +386,7 @@ dprofpp
Another nice Perl-level profiler. To use:
-perl -d:NTYProf testfile.pl
+perl -d:NYTProf testfile.pl
Then run:
@@ -589,7 +589,7 @@ http://search.cpan.org/dist/DBD-Pg/
* Completely update the Changes file
The best way to do this (other than doing it as you go along) is to check the subversion logs,
-by running a diff against the last-releaed version.
+by running a diff against the last-released version.
* Update the documentation
View
@@ -222,6 +222,7 @@ int dbd_db_login (SV * dbh, imp_dbh_t * imp_dbh, char * dbname, char * uid, char
imp_dbh->done_begin = DBDPG_FALSE;
imp_dbh->dollaronly = DBDPG_FALSE;
imp_dbh->expand_array = DBDPG_TRUE;
+ imp_dbh->txn_read_only = DBDPG_FALSE;
imp_dbh->pid_number = getpid();
imp_dbh->prepare_number = 1;
imp_dbh->copystate = 0;
@@ -771,10 +772,21 @@ int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV * keysv, SV * valuesv
unsigned int newval = SvTRUE(valuesv);
int retval = 0;
- if (TSTART) TRC(DBILOGFP, "%sBegin dbd_db_STORE (key: %s newval: %d)\n", THEADER, key, newval);
+ if (TSTART) TRC(DBILOGFP, "%sBegin dbd_db_STORE (key: %s newval: %d kl:%d)\n", THEADER, key, newval);
switch (kl) {
+ case 8: /* ReadOnly */
+
+ if (strEQ("ReadOnly", key)) {
+ if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
+ warn("Setting ReadOnly in AutoCommit mode has no effect");
+ }
+ imp_dbh->txn_read_only = newval ? DBDPG_TRUE : DBDPG_FALSE;
+ retval = 1;
+ }
+ break;
+
case 10: /* AutoCommit pg_bool_tf */
if (strEQ("AutoCommit", key)) {
@@ -2624,8 +2636,23 @@ int pg_quickexec (SV * dbh, const char * sql, const int asyncflag)
return -2;
}
imp_dbh->done_begin = DBDPG_TRUE;
+ /* If read-only mode, make it so */
+ if (imp_dbh->txn_read_only) {
+ status = _result(aTHX_ imp_dbh, "set transaction read only");
+ if (PGRES_COMMAND_OK != status) {
+ TRACE_PQERRORMESSAGE;
+ pg_error(aTHX_ dbh, status, PQerrorMessage(imp_dbh->conn));
+ if (TEND) TRC(DBILOGFP, "%sEnd pg_quickexec (error: set transaction read only failed)\n", THEADER);
+ return -2;
+ }
+ }
}
+ /*
+ We want txn mode if AutoCommit
+ */
+
+
/* Asynchronous commands get kicked off and return undef */
if (asyncflag & PG_ASYNC) {
if (TRACE4) TRC(DBILOGFP, "%sGoing asychronous with do()\n", THEADER);
@@ -2788,6 +2815,16 @@ int dbd_st_execute (SV * sth, imp_sth_t * imp_sth)
return -2;
}
imp_dbh->done_begin = DBDPG_TRUE;
+ /* If read-only mode, make it so */
+ if (imp_dbh->txn_read_only) {
+ status = _result(aTHX_ imp_dbh, "set transaction read only");
+ if (PGRES_COMMAND_OK != status) {
+ TRACE_PQERRORMESSAGE;
+ pg_error(aTHX_ sth, status, PQerrorMessage(imp_dbh->conn));
+ if (TEND) TRC(DBILOGFP, "%sEnd pg_quickexec (error: set transaction read only failed)\n", THEADER);
+ return -2;
+ }
+ }
}
/* clear old result (if any) */
View
@@ -24,6 +24,7 @@ struct imp_dbh_st {
bool done_begin; /* have we done a begin? (e.g. are we in a transaction?) */
bool dollaronly; /* only consider $1, $2 ... as valid placeholders */
bool expand_array; /* transform arrays from the db into Perl arrays? Default is 1 */
+ bool txn_read_only; /* are we in read-only mode? Set with $dbh->{ReadOnly} */
int pg_protocol; /* value of PQprotocolVersion, usually 3 (could also be 0) */
int pg_server_version; /* server version e.g. 80100 */
View
@@ -4,7 +4,7 @@ package Bundle::DBD::Pg;
use strict;
use warnings;
-$VERSION = '2.8.8';
+$VERSION = '2.9.0';
1;
View
@@ -18,7 +18,7 @@ my ($helpconnect,$connerror,$dbh) = connect_database();
if (! defined $dbh) {
plan skip_all => 'Connection to database failed, cannot continue testing';
}
-plan tests => 164;
+plan tests => 171;
isnt ($dbh, undef, 'Connect to database for handle attributes testing');
@@ -99,6 +99,7 @@ a TaintIn
a TaintOut
a Taint
a Profile (not tested)
+a ReadOnly
d InactiveDestroy (must be the last one tested)
@@ -964,9 +965,9 @@ if ($client_level ne 'error') {
};
eval {$sth = $dbh->last_insert_id('cat', 'schema', 'table', 'col', ['notahashref']); };
## Changing the state does not work yet.
- like($@, qr{ERRSTR}, $t);
- is ($dbh->errstr, "ERRSTR", $t);
- is ($dbh->err, "42", $t);
+ like ($@, qr{ERRSTR}, $t);
+ is ($dbh->errstr, 'ERRSTR', $t);
+ is ($dbh->err, '42', $t);
$dbh->{HandleSetErr} = 0;
$dbh->rollback();
@@ -1023,7 +1024,7 @@ eval {
};
$t='Database handle attribute "ShowErrorStatement" adds statement and placeholders to errors';
like ($@, qr{with ParamValues: 1='123', 2='456'}, $t);
-$dbh->rollback();
+$dbh->commit();
#
# Test of the handle attribute TraceLevel
@@ -1160,6 +1161,54 @@ is ($attrib, 1, $t);
#
#
+# Test of the database handle attribute "ReadOnly"
+#
+
+$t='Database handle attribute "ReadOnly" starts out unefined';
+$dbh->commit();
+$dbh4 = connect_database();
+$dbh4->trace(0);
+is ($dbh4->{ReadOnly}, undef, $t);
+
+$t='Database handle attribute "ReadOnly" sets transactions to readonly mode';
+$dbh4->{ReadOnly} = 1;
+
+$t='Database handle attribute "ReadOnly" allows SELECT queries to work when on';
+$result = $dbh4->selectall_arrayref('SELECT 12345')->[0][0];
+is ($result, 12345, $t);
+
+$t='Database handle attribute "ReadOnly" prevents INSERT queries from working when on';
+$SQL = 'INSERT INTO dbd_pg_test (id) VALUES (50)';
+eval { $dbh4->do($SQL); };
+like ($@, qr{transaction is read-only}, $t);
+$dbh4->rollback();
+
+$sth = $dbh4->prepare($SQL);
+eval { $sth->execute(); };
+like ($@, qr{transaction is read-only}, $t);
+$dbh4->rollback();
+
+$t='Database handle attribute "ReadOnly" allows INSERT queries when switched off';
+$dbh4->{ReadOnly} = 0;
+eval { $dbh4->do($SQL); };
+is ($@, q{}, $t);
+$dbh4->rollback();
+
+$dbh4->{ReadOnly} = 1;
+$dbh4->{AutoCommit} = 1;
+$t='Database handle attribute "ReadOnly" has no effect if AutoCommit is on';
+eval { $dbh4->do($SQL); };
+is ($@, q{}, $t);
+
+my $delete = 'DELETE FROM dbd_pg_test WHERE id = 50';
+$dbh4->do($delete);
+$sth = $dbh4->prepare($SQL);
+eval { $sth->execute(); };
+is ($@, q{}, $t);
+
+$dbh4->disconnect();
+
+#
# Test of the database handle attribute InactiveDestroy
# This one must be the last test performed!
#
View
@@ -405,6 +405,7 @@ qw
RaiseError
RDBMS
README
+ReadOnly
realclean
RedHat
relcheck
@@ -554,6 +555,13 @@ struct
## README.dev:
+DProf
+NYTProf
+dprofpp
+nytprofhtml
+profiler
+spellcheck
+testfile
leaktester
mak
mathinline
@@ -562,11 +570,13 @@ nServer
## README:
BOOTCHECK
+CentOS
DynaLoader
Eisentraut
Gcc
Landgren
Lauterbach
+Ubuntu
cabrion
conf
danla

0 comments on commit 6418b9d

Please sign in to comment.