diff options
Diffstat (limited to 'perl/Wallet')
-rw-r--r-- | perl/Wallet/ACL.pm | 10 | ||||
-rw-r--r-- | perl/Wallet/Object/Base.pm | 11 | ||||
-rw-r--r-- | perl/Wallet/Object/Keytab.pm | 4 | ||||
-rw-r--r-- | perl/Wallet/Schema.pm | 72 | ||||
-rw-r--r-- | perl/Wallet/Server.pm | 21 |
5 files changed, 99 insertions, 19 deletions
diff --git a/perl/Wallet/ACL.pm b/perl/Wallet/ACL.pm index 6a07366..f04217e 100644 --- a/perl/Wallet/ACL.pm +++ b/perl/Wallet/ACL.pm @@ -50,8 +50,12 @@ sub new { } else { $sql = 'select ac_id, ac_name from acls where ac_name = ?'; } - ($data, $name) = eval { $dbh->selectrow_array ($sql, undef, $id) }; + eval { + ($data, $name) = $dbh->selectrow_array ($sql, undef, $id); + $dbh->commit; + }; if ($@) { + $dbh->rollback; die "cannot search for ACL $id: $@\n"; } elsif (not defined $data) { die "ACL $id not found\n"; @@ -271,9 +275,11 @@ sub list { while (defined ($entry = $sth->fetchrow_arrayref)) { push (@entries, [ @$entry ]); } + $self->{dbh}->commit; }; if ($@) { $self->error ("cannot retrieve ACL $self->{id}: $@"); + $self->{dbh}->rollback; return; } else { return @entries; @@ -320,9 +326,11 @@ sub history { } $output .= "\n by $data[3] from $data[4]\n"; } + $self->{dbh}->commit; }; if ($@) { $self->error ("cannot read history for $self->{id}: $@"); + $self->{dbh}->rollback; return undef; } return $output; diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm index ada211c..1371f7f 100644 --- a/perl/Wallet/Object/Base.pm +++ b/perl/Wallet/Object/Base.pm @@ -41,6 +41,7 @@ sub new { $dbh->{PrintError} = 0; my $sql = 'select ob_name from objects where ob_type = ? and ob_name = ?'; my $data = $dbh->selectrow_array ($sql, undef, $type, $name); + $dbh->commit; die "cannot find ${type}:${name}\n" unless ($data and $data eq $name); my $self = { dbh => $dbh, @@ -240,9 +241,11 @@ sub _get_internal { my $sql = "select $attr from objects where ob_type = ? and ob_name = ?"; $value = $self->{dbh}->selectrow_array ($sql, undef, $type, $name); + $self->{dbh}->commit; }; if ($@) { $self->error ($@); + $self->{dbh}->rollback; return; } return $value; @@ -345,9 +348,11 @@ sub flag_check { my $sql = 'select fl_flag from flags where fl_type = ? and fl_name = ? and fl_flag = ?'; $value = $dbh->selectrow_array ($sql, undef, $type, $name, $flag); + $dbh->commit; }; if ($@) { $self->error ("cannot check flag $flag for ${type}:${name}: $@"); + $dbh->rollback; return; } elsif ($value) { return 1; @@ -401,10 +406,12 @@ sub flag_list { while (defined ($flag = $sth->fetchrow_array)) { push (@flags, $flag); } + $self->{dbh}->commit; }; if ($@) { my $id = $self->{type} . ':' . $self->{name}; $self->error ("cannot retrieve flags for $id: $@"); + $self->{dbh}->rollback; return; } else { return @flags; @@ -490,10 +497,12 @@ sub history { } $output .= "\n by $data[5] from $data[6]\n"; } + $self->{dbh}->commit; }; if ($@) { my $id = $self->{type} . ':' . $self->{name}; $self->error ("cannot read history for $id: $@"); + $self->{dbh}->rollback; return undef; } return $output; @@ -550,9 +559,11 @@ sub show { my $sql = "select $fields from objects where ob_type = ? and ob_name = ?"; @data = $self->{dbh}->selectrow_array ($sql, undef, $type, $name); + $self->{dbh}->commit; }; if ($@) { $self->error ("cannot retrieve data for ${type}:${name}: $@"); + $self->{dbh}->rollback; return undef; } my $output = ''; diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm index f91abff..025c9e1 100644 --- a/perl/Wallet/Object/Keytab.pm +++ b/perl/Wallet/Object/Keytab.pm @@ -467,9 +467,11 @@ sub enctypes_list { while (defined ($entry = $sth->fetchrow_arrayref)) { push (@enctypes, @$entry); } + $self->{dbh}->commit; }; if ($@) { $self->error ($@); + $self->{dbh}->rollback; return; } return @enctypes; @@ -562,9 +564,11 @@ sub attr { while (defined ($target = $sth->fetchrow_array)) { push (@targets, $target); } + $self->{dbh}->commit; }; if ($@) { $self->error ($@); + $self->{dbh}->rollback; return; } return @targets; diff --git a/perl/Wallet/Schema.pm b/perl/Wallet/Schema.pm index ec690e1..030905e 100644 --- a/perl/Wallet/Schema.pm +++ b/perl/Wallet/Schema.pm @@ -14,7 +14,7 @@ package Wallet::Schema; require 5.006; use strict; -use vars qw(@TABLES $VERSION); +use vars qw(@SQL @TABLES $VERSION); use DBI; @@ -28,28 +28,31 @@ $VERSION = '0.02'; ############################################################################## # Create a new Wallet::Schema object, parse the SQL out of the documentation, -# and store it in the object. +# and store it in the object. We have to store the SQL in a static variable, +# since we can't read DATA multiple times. sub new { my ($class) = @_; - local $_; - my ($found, @sql); - my $command = ''; - while (<DATA>) { - if (not $found and /^=head1 SCHEMA/) { - $found = 1; - } elsif ($found and /^=head1 /) { - last; - } elsif ($found and /^ /) { - s/^ //; - $command .= $_; - if (/;$/) { - push (@sql, $command); - $command = ''; + unless (@SQL) { + local $_; + my $found; + my $command = ''; + while (<DATA>) { + if (not $found and /^=head1 SCHEMA/) { + $found = 1; + } elsif ($found and /^=head1 /) { + last; + } elsif ($found and /^ /) { + s/^ //; + $command .= $_; + if (/;$/) { + push (@SQL, $command); + $command = ''; + } } } + close DATA; } - close DATA; - my $self = { sql => [ @sql ] }; + my $self = { sql => [ @SQL ] }; bless ($self, $class); return $self; } @@ -84,6 +87,31 @@ sub create { } } +# Given a database handle, try to remove the wallet database tables by +# reversing the SQL. Do this in a transaction regardless of the database +# settings and throw an exception if this fails. +sub drop { + my ($self, $dbh) = @_; + my @drop = map { + if (/^\s*create\s+table\s+(\S+)/i) { + "drop table if exists $1;"; + } else { + (); + } + } reverse @{ $self->{sql} }; + eval { + $dbh->begin_work if $dbh->{AutoCommit}; + for my $sql (@drop) { + $dbh->do ($sql, { RaiseError => 1, PrintError => 0 }); + } + $dbh->commit; + }; + if ($@) { + $dbh->rollback; + die "$@\n"; + } +} + ############################################################################## # Schema ############################################################################## @@ -134,6 +162,14 @@ drop any existing tables and will therefore fail if a wallet database has already been created. On any error, this method will throw a database exception. +=item drop(DBH) + +Given a connected database handle, drop all of the wallet tables from that +database if any of those tables exist. This method will only remove tables +that are part of the current schema or one of the previous known schema and +won't remove other tables. On any error, this method will throw a database +exception. + =item sql() Returns the schema and the population of the normalization tables as a list diff --git a/perl/Wallet/Server.pm b/perl/Wallet/Server.pm index 429b3fb..04e8fd9 100644 --- a/perl/Wallet/Server.pm +++ b/perl/Wallet/Server.pm @@ -85,6 +85,18 @@ sub initialize { return $class->new ($user, 'localhost'); } +# The same as initialize, but also drops any existing tables first before +# creating the schema. Takes the same arguments and throws an exception on +# failure. +sub reinitialize { + my ($class, $user) = @_; + my $dbh = $class->_open_db; + my $schema = Wallet::Schema->new; + $schema->drop ($dbh); + $dbh->disconnect; + return $class->initialize ($user); +} + # Create a new wallet server object. A new server should be created for each # user who is making changes to the wallet. Takes the principal and host who # are sending wallet requests. Opens a connection to the database that will @@ -752,6 +764,15 @@ privileged operations. On any error, this method throws an exception. +=item reinitialize(PRINCIPAL) + +Performs the same actions as initialize(), but first drops any existing +wallet database tables from the database, allowing this function to be +called on a prior wallet database. All data stored in the database will be +deleted and a fresh set of wallet database tables will be created. + +On any error, this method throws an exception. + =back =head1 INSTANCE METHODS |