diff options
| author | Russ Allbery <rra@stanford.edu> | 2013-03-27 15:19:46 -0700 | 
|---|---|---|
| committer | Russ Allbery <rra@stanford.edu> | 2013-03-27 15:19:46 -0700 | 
| commit | 6871bae8e26beadaff5035de56b4f70a78961dc9 (patch) | |
| tree | 366943055e3db5c26a9415d1d2ea1486054e8177 /perl/Wallet/Schema.pm | |
| parent | 61c348a8cc08e90c73993e09dc175b44c5a65681 (diff) | |
| parent | 06c44c9eb5efb00bb9368ed3709106c91b0b36b5 (diff) | |
Imported Upstream version 1.0
Diffstat (limited to 'perl/Wallet/Schema.pm')
| -rw-r--r-- | perl/Wallet/Schema.pm | 234 | 
1 files changed, 70 insertions, 164 deletions
diff --git a/perl/Wallet/Schema.pm b/perl/Wallet/Schema.pm index 25d48cf..fc63447 100644 --- a/perl/Wallet/Schema.pm +++ b/perl/Wallet/Schema.pm @@ -1,207 +1,97 @@ -# Wallet::Schema -- Database schema for the wallet system. +# Database schema and connector for the wallet system.  # -# Written by Russ Allbery <rra@stanford.edu> -# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University +# Written by Jon Robertson <jonrober@stanford.edu> +# Copyright 2012, 2013 +#     The Board of Trustees of the Leland Stanford Junior University  #  # See LICENSE for licensing terms. -############################################################################## -# Modules and declarations -############################################################################## -  package Wallet::Schema; -require 5.006;  use strict; -use vars qw(@SQL @TABLES $VERSION); +use warnings; -use DBI; +use Wallet::Config; + +use base 'DBIx::Class::Schema';  # This version should be increased on any code change to this module.  Always  # use two digits for the minor version with a leading zero if necessary so  # that it will sort properly. -$VERSION = '0.06'; +our $VERSION = '0.08'; + +__PACKAGE__->load_namespaces; +__PACKAGE__->load_components (qw/Schema::Versioned/);  ############################################################################## -# Data manipulation +# Core overrides  ############################################################################## -# Create a new Wallet::Schema object, parse the SQL out of the documentation, -# 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 { +# Override DBI::connect to supply our own connect string, username, and +# password and to set some standard options.  Takes no arguments other than +# the implicit class argument. +sub connect {      my ($class) = @_; -    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; +    unless ($Wallet::Config::DB_DRIVER +            and (defined ($Wallet::Config::DB_INFO) +                 or defined ($Wallet::Config::DB_NAME))) { +        die "database connection information not configured\n";      } -    my $self = { sql => [ @SQL ] }; -    bless ($self, $class); -    return $self; -} - -# Returns the SQL as a list of commands. -sub sql { -    my ($self) = @_; -    return @{ $self->{sql} }; -} - -############################################################################## -# Initialization and cleanup -############################################################################## - -# Given a database handle, try to create our database by running the SQL.  Do -# this in a transaction regardless of the database settings and throw an -# exception if this fails.  We have to do a bit of fiddling to get syntax that -# works with both MySQL and SQLite. -sub create { -    my ($self, $dbh) = @_; -    my $driver = $dbh->{Driver}->{Name}; -    eval { -        $dbh->begin_work if $dbh->{AutoCommit}; -        my @sql = @{ $self->{sql} }; -        for my $sql (@sql) { -            if ($driver eq 'SQLite') { -                $sql =~ s{auto_increment primary key} -                         {primary key autoincrement}; -            } elsif ($driver eq 'mysql' and $sql =~ /^\s*create\s+table\s/) { -                $sql =~ s/;$/ engine=InnoDB;/; -            } -            $dbh->do ($sql, { RaiseError => 1, PrintError => 0 }); -        } -        $dbh->commit; -    }; -    if ($@) { -        $dbh->rollback; -        die "$@\n"; +    my $dsn = "DBI:$Wallet::Config::DB_DRIVER:"; +    if (defined $Wallet::Config::DB_INFO) { +        $dsn .= $Wallet::Config::DB_INFO; +    } else { +        $dsn .= "database=$Wallet::Config::DB_NAME"; +        $dsn .= ";host=$Wallet::Config::DB_HOST" if $Wallet::Config::DB_HOST; +        $dsn .= ";port=$Wallet::Config::DB_PORT" if $Wallet::Config::DB_PORT;      } -} - -# 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; -    }; +    my $user = $Wallet::Config::DB_USER; +    my $pass = $Wallet::Config::DB_PASSWORD; +    my %attrs = (PrintError => 0, RaiseError => 1); +    my $schema = eval { $class->SUPER::connect ($dsn, $user, $pass, \%attrs) };      if ($@) { -        $dbh->rollback; -        die "$@\n"; +        die "cannot connect to database: $@\n";      } +    return $schema;  } +__END__ + +1; +  ############################################################################## -# Schema +# Documentation  ############################################################################## -# The following POD is also parsed by the code to extract SQL blocks.  Don't -# add any verbatim blocks to this documentation in the SCHEMA section that -# aren't intended to be SQL. - -1; -__DATA__ +=for stopwords +RaiseError PrintError AutoCommit ACL verifier API APIs enums keytab backend +enctypes DBI Allbery  =head1 NAME -Wallet::Schema - Database schema for the wallet system - -=for stopwords -SQL ACL API APIs enums Enums Keytab Backend keytab backend enctypes -enctype Allbery +Wallet::Schema - Database schema and connector for the wallet system  =head1 SYNOPSIS      use Wallet::Schema; -    my $schema = Wallet::Schema->new; -    my @sql = $schema->sql; -    $schema->create ($dbh); +    my $schema = Wallet::Schema->connect;  =head1 DESCRIPTION  This class encapsulates the database schema for the wallet system.  The -documentation you're reading explains and comments the schema.  The Perl -object extracts the schema from the documentation and can either return it -as a list of SQL commands to run or run those commands given a connected -database handle. - -This schema attempts to be portable SQL, but it is designed for use with -MySQL and may require some modifications for other databases. +documentation you're reading explains and comments the schema.  The +class runs using the DBIx::Class module. -=head1 METHODS - -=over 4 - -=item new() - -Instantiates a new Wallet::Schema object.  This parses the documentation -and extracts the schema, but otherwise doesn't do anything. - -=item create(DBH) - -Given a connected database handle, runs the SQL commands necessary to -create the wallet database in an otherwise empty database.  This method -will not 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 of SQL commands to run to create the wallet database in an otherwise -empty database. - -=back +connect() will obtain the database connection information from the wallet +configuration; see L<Wallet::Config> for more details.  It will also +automatically set the RaiseError attribute to true and the PrintError and +AutoCommit attributes to false, matching the assumptions made by the +wallet database code.  =head1 SCHEMA  =head2 Normalization Tables -The following are normalization tables used to constrain the values in -other tables. - -Holds the supported flag names: - -  create table flag_names -     (fn_name             varchar(32) primary key); -  insert into flag_names (fn_name) values ('locked'); -  insert into flag_names (fn_name) values ('unchanging'); -  Holds the supported object types and their corresponding Perl classes:    create table types @@ -222,6 +112,8 @@ Holds the supported ACL schemes and their corresponding Perl classes:    insert into acl_schemes (as_name, as_class)        values ('krb5-regex', 'Wallet::ACL::Krb5::Regex');    insert into acl_schemes (as_name, as_class) +      values ('ldap-attr', 'Wallet::ACL::LDAP::Attribute'); +  insert into acl_schemes (as_name, as_class)        values ('netdb', 'Wallet::ACL::NetDB');    insert into acl_schemes (as_name, as_class)        values ('netdb-root', 'Wallet::ACL::NetDB::Root'); @@ -314,6 +206,7 @@ table:        ob_downloaded_by    varchar(255) default null,        ob_downloaded_from  varchar(255) default null,        ob_downloaded_on    datetime default null, +      ob_comment          varchar(255) default null,        primary key (ob_name, ob_type));    create index ob_owner on objects (ob_owner);    create index ob_expires on objects (ob_expires); @@ -332,8 +225,8 @@ object may have zero or more flags associated with it:            not null references objects(ob_type),        fl_name             varchar(255)            not null references objects(ob_name), -      fl_flag             varchar(32) -          not null references flag_names(fn_name), +      fl_flag             enum('locked', 'unchanging') +          not null,        primary key (fl_type, fl_name, fl_flag));    create index fl_object on flags (fl_type, fl_name); @@ -419,9 +312,22 @@ To use this functionality, you will need to populate the enctypes table  with the enctypes that a keytab may be restricted to.  Currently, there is  no automated mechanism to do this. +=head1 CLASS METHODS + +=over 4 + +=item connect() + +Opens a new database connection and returns the database object.  On any +failure, throws an exception.  Unlike the DBI method, connect() takes no +arguments; all database connection information is derived from the wallet +configuration. + +=back +  =head1 SEE ALSO -wallet-backend(8) +wallet-backend(8), Wallet::Config(3)  This module is part of the wallet system.  The current version is  available from L<http://www.eyrie.org/~eagle/software/wallet/>.  | 
