IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 12, 2008, 11:13:41 AM (18 years ago)
Author:
jhoblitt
Message:

first attempt at supporting multiple databases

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous-Server/lib/Nebulous/Server.pm

    r20091 r20965  
    11# Copyright (c) 2004-2008  Joshua Hoblitt
    22#
    3 # $Id: Server.pm,v 1.93 2008-10-13 20:41:17 jhoblitt Exp $
     3# $Id: Server.pm,v 1.94 2008-12-12 21:13:41 jhoblitt Exp $
    44
    55package Nebulous::Server;
     
    99no warnings qw( uninitialized );
    1010
    11 our $VERSION = '0.15';
     11our $VERSION = '0.16';
    1212
    1313use base qw( Class::Accessor::Fast );
     
    1919use File::Spec;
    2020use Log::Log4perl;
     21use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
    2122use Nebulous::Server::Config;
    2223use Nebulous::Server::Log;
    2324use Nebulous::Server::SQL;
    24 use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
    2525use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF );
    2626use URI::file;
     
    3636
    3737    # let Nebulous::Server::Config validate our params
    38     my $config = Nebulous::Server::Config->init( @_ );
     38    my $config = Nebulous::Server::Config->new( @_ );
    3939
    4040    # log4perl is not avaliable until we call init()
     
    5151    $self->config($config);
    5252
    53     # ask for the db handle as a means of validating the database parameters
    54     $self->db;
    55 
    5653    $log->debug( "leaving" );
    5754   
     
    6259sub db
    6360{
    64     my $self = shift;
    65 
    66     if (@_) {
    67         $self->{db} = $_[0];
    68         return $self;
    69     }
     61    my ($self, $key) = @_;
    7062
    7163    my $log     = $self->log;
     
    7365    my $config  = $self->config;
    7466
     67    my $db_index = 0;
     68    if (defined $key) {
     69        # hash the key to select the correct database instance
     70        $db_index = unpack("%20h", sha1_hex("$key")) % $config->n_db;
     71    }
     72
     73    # lookup to see if we have a stored dbh for this database
     74    my $dbh = $self->{dbs}[$db_index];
    7575    # if the dbh is still alive, return it
    76     if (defined $self->{db} and $self->{db}->ping) {
     76    if (defined $dbh and $dbh->ping) {
    7777        $log->debug("db handle is still alive");
    78         return $self->{db};
     78        return $dbh;
    7979    }
    8080    # otherwise create a new connection
    8181    $log->debug("db handle is dead/unopened");
     82
     83    # lookup database info
     84    my $db_config = $config->db($db_index);
     85    die "can't find database configuration info for database # $db_index"
     86        unless $db_config;
    8287
    8388    # if we're running under mod_perl & Apache::DBI is loaded we want to
     
    8691    # processes and the database might have gone away on us.  Apache::DBI will
    8792    # take care of getting a valid dbh back.
    88     my $db;
    89     eval {
    90         $db = DBI->connect_cached(
    91             $config->dsn,
    92             $config->dbuser,
    93             $config->dbpasswd,
     93    eval {
     94        $dbh = DBI->connect_cached(
     95            $db_config->dsn,
     96            $db_config->dbuser,
     97            $db_config->dbpasswd,
    9498            {
    9599                RaiseError => 1,
     
    99103        );
    100104
    101         $db->do( $sql->set_transaction_model );
    102         $log->debug( "connected to database: ", sub { $db->data_sources; } );
    103         $db->commit;
     105        $dbh->do( $sql->set_transaction_model );
     106        $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
     107        $dbh->commit;
    104108        $log->debug("commit");
    105109    };
    106110    if ( $@ ) {
    107         $db->rollback if $db;
     111        $dbh->rollback if $dbh;
    108112        $log->debug("rollback");
    109113        $log->logdie( "database error: $@" );
    110114    }
    111115
    112     $self->{db} = $db;
    113 
    114     return $db;
     116    $self->{dbs}[$db_index] = $dbh;
     117
     118    return $dbh;
    115119}
    116120
     
    139143    my $log = $self->log;
    140144    my $sql = $self->sql;
    141     my $db  =$self->db;
     145    my $db  = $self->db($key);
    142146
    143147    $log->debug( "entered - @_" );
     
    150154    # to check it after parsing the key
    151155    if (defined $vol_name
    152         and not $self->_is_valid_volume_name($key->volume)) {
     156        and not $self->_is_valid_volume_name($key, $key->volume)) {
    153157        if ($key->soft_volume) {
    154158            $log->warn( "$vol_name is not a known volume name" );
     
    160164       
    161165    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    162         = $self->_get_storage_volume($vol_name, $key->soft_volume);
     166        = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
    163167
    164168    my $uri;
     
    261265    my $log = $self->log;
    262266    my $sql = $self->sql;
    263     my $db  =$self->db;
     267    my $db  = $self->db($key);
    264268
    265269    $log->debug("entered - @_");
     
    296300
    297301
    298 sub swap_objects
    299 {
    300     my $self = shift;
    301 
    302     my ($key1, $key2) = validate_pos(@_,
    303         {
    304             type        => SCALAR,
    305             callbacks   => {
    306                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
    307             },
    308         },
    309         {
    310             type        => SCALAR,
    311             callbacks   => {
    312                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
    313             },
    314         },
    315     );
    316 
    317     my $log = $self->log;
    318     my $sql = $self->sql;
    319     my $db  =$self->db;
    320 
    321     $log->debug("entered - @_");
    322 
    323     # ignore volumes
    324     $key1 = parse_neb_key($key1);
    325     $key2 = parse_neb_key($key2);
    326 
    327     # order of operations for the swap:
    328     # key1 -> key1.swap
    329     # key2 -> key1
    330     # key1.swap -> key2
    331 
    332     eval {
    333         {
    334             # key1 -> key1.swap
    335             my $query = $db->prepare_cached($sql->rename_object);
    336             # this SQL statment takes the new key name as the first param
    337             my $rows = $query->execute($key1->path . ".swap", $key1->path);
    338 
    339             # if we affected more then one row something very bad has happened.
    340             unless ($rows == 1) {
    341                 $query->finish;
    342                 $log->logdie("affected row count is $rows instead of 1");
    343             }
    344         }
    345 
    346         {
    347             # key2 -> key1
    348             my $query = $db->prepare_cached($sql->rename_object);
    349             # this SQL statment takes the new key name as the first param
    350             my $rows = $query->execute($key1->path, $key2->path);
    351 
    352             # if we affected more then one row something very bad has happened.
    353             unless ($rows == 1) {
    354                 $query->finish;
    355                 $log->logdie("affected row count is $rows instead of 1");
    356             }
    357         }
    358 
    359         {
    360             # key1.swap -> key2
    361             my $query = $db->prepare_cached($sql->rename_object);
    362             # this SQL statment takes the new key name as the first param
    363             my $rows = $query->execute($key2->path, $key1->path . ".swap");
    364 
    365             # if we affected more then one row something very bad has happened.
    366             unless ($rows == 1) {
    367                 $query->finish;
    368                 $log->logdie("affected row count is $rows instead of 1");
    369             }
    370         }
    371 
    372         $db->commit;
    373         $log->debug("commit");
    374     };
    375     if ($@) {
    376         $db->rollback;
    377         $log->debug("rollback");
    378         $log->logdie("database error: $@");
    379     }
    380 
    381     $log->debug("leaving");
    382 
    383     return 1;
    384 }
     302# sub swap_objects
     303# {
     304#     my $self = shift;
     305#
     306#     my ($key1, $key2) = validate_pos(@_,
     307#         {
     308#             type        => SCALAR,
     309#             callbacks   => {
     310#                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     311#             },
     312#         },
     313#         {
     314#             type        => SCALAR,
     315#             callbacks   => {
     316#                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     317#             },
     318#         },
     319#     );
     320#
     321#     my $log  = $self->log;
     322#     my $sql  = $self->sql;
     323#     my $dbh1 = $self->db($key1);
     324#     my $dbh2 = $self->db($key2);
     325#
     326#     $log->debug("entered - @_");
     327#
     328#     # ignore volumes
     329#     $key1 = parse_neb_key($key1);
     330#     $key2 = parse_neb_key($key2);
     331#
     332#     # order of operations for the swap with a single db is:
     333#     # key1 -> key1.swap
     334#     # key2 -> key1
     335#     # key1.swap -> key2
     336#
     337#     # XXX this cmp will only work if ->db() returns the same exact (cached) dbh
     338#     if ($dbh1 == $dbh2) {
     339#         my $dbh = $dbh1;
     340#         eval {
     341#             {
     342#                 # key1 -> key1.swap
     343#                 my $query = $dbh->prepare_cached($sql->rename_object);
     344#                 # this SQL statment takes the new key name as the first param
     345#                 my $rows = $query->execute($key1->path . ".swap", $key1->path);
     346#
     347#                 # if we affected more then one row something very bad has happened.
     348#                 unless ($rows == 1) {
     349#                     $query->finish;
     350#                     $log->logdie("affected row count is $rows instead of 1");
     351#                 }
     352#             }
     353#
     354#             {
     355#                 # key2 -> key1
     356#                 my $query = $dbh->prepare_cached($sql->rename_object);
     357#                 # this SQL statment takes the new key name as the first param
     358#                 my $rows = $query->execute($key1->path, $key2->path);
     359#
     360#                 # if we affected more then one row something very bad has happened.
     361#                 unless ($rows == 1) {
     362#                     $query->finish;
     363#                     $log->logdie("affected row count is $rows instead of 1");
     364#                 }
     365#             }
     366#
     367#             {
     368#                 # key1.swap -> key2
     369#                 my $query = $dbh->prepare_cached($sql->rename_object);
     370#                 # this SQL statment takes the new key name as the first param
     371#                 my $rows = $query->execute($key2->path, $key1->path . ".swap");
     372#
     373#                 # if we affected more then one row something very bad has happened.
     374#                 unless ($rows == 1) {
     375#                     $query->finish;
     376#                     $log->logdie("affected row count is $rows instead of 1");
     377#                 }
     378#             }
     379#
     380#             $dbn->commit;
     381#             $log->debug("commit");
     382#         };
     383#         if ($@) {
     384#             $dbh->rollback;
     385#             $log->debug("rollback");
     386#             $log->logdie("database error: $@");
     387#         }
     388#     }
     389#
     390#     # order of operations for the swap between two dbs is:
     391#     # key1 start transaction
     392#     # key1 -> read all instances
     393#     # key1 -> remove all instances
     394#     # key2 start transaction
     395#     # key2 -> read all instances
     396#     # key2 -> remove all instances
     397#     # key1 -> insert key 2 instances
     398#     # key2 -> insert key 1 instances
     399#     # key1,2 commit
     400#
     401#     eval {
     402#         {
     403#             # key1 -> read all instances
     404#             my $query = $dbh->prepare_cached($sql->rename_object);
     405#             # this SQL statment takes the new key name as the first param
     406#             my $rows = $query->execute($key1->path . ".swap", $key1->path);
     407#
     408#             # if we affected more then one row something very bad has happened.
     409#             unless ($rows == 1) {
     410#                 $query->finish;
     411#                 $log->logdie("affected row count is $rows instead of 1");
     412#             }
     413#         }
     414#
     415#         {
     416#             # key2 -> key1
     417#             my $query = $db->prepare_cached($sql->rename_object);
     418#             # this SQL statment takes the new key name as the first param
     419#             my $rows = $query->execute($key1->path, $key2->path);
     420#
     421#             # if we affected more then one row something very bad has happened.
     422#             unless ($rows == 1) {
     423#                 $query->finish;
     424#                 $log->logdie("affected row count is $rows instead of 1");
     425#             }
     426#         }
     427#
     428#         {
     429#             # key1.swap -> key2
     430#             my $query = $db->prepare_cached($sql->rename_object);
     431#             # this SQL statment takes the new key name as the first param
     432#             my $rows = $query->execute($key2->path, $key1->path . ".swap");
     433#
     434#             # if we affected more then one row something very bad has happened.
     435#             unless ($rows == 1) {
     436#                 $query->finish;
     437#                 $log->logdie("affected row count is $rows instead of 1");
     438#             }
     439#         }
     440#
     441#         $db->commit;
     442#         $log->debug("commit");
     443#     };
     444#         if ($@) {
     445#             $db->rollback;
     446#             $log->debug("rollback");
     447#             $log->logdie("database error: $@");
     448#         }
     449#
     450#
     451#     $log->debug("leaving");
     452#
     453#     return 1;
     454# }
    385455
    386456
     
    420490    my $log = $self->log;
    421491    my $sql = $self->sql;
    422     my $db  =$self->db;
     492    my $db  = $self->db($key);
    423493
    424494    $log->debug("entered - @_");
     
    429499
    430500    if (defined $vol_name
    431         and not $self->_is_valid_volume_name($key->volume)) {
     501        and not $self->_is_valid_volume_name($key, $key->volume)) {
    432502        if ($key->soft_volume) {
    433503            $log->warn( "$vol_name is not a known volume name" );
     
    441511    if (defined $vol_name) {
    442512        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    443             = $self->_get_storage_volume($vol_name);
     513            = $self->_get_storage_volume($key, $vol_name);
    444514    } else {
    445515        ($vol_id, $vol_host, $vol_path, $vol_xattr)
     
    534604    my $log = $self->log;
    535605    my $sql = $self->sql;
    536     my $db  =$self->db;
     606    my $db  = $self->db($key);
    537607
    538608    $log->debug( "entered - @_" );
     
    637707    my $log = $self->log;
    638708    my $sql = $self->sql;
    639     my $db  =$self->db;
     709    my $db  = $self->db($key);
    640710
    641711    $log->debug( "entered - @_" );
     
    749819    my $log = $self->log;
    750820    my $sql = $self->sql;
    751     my $db  =$self->db;
     821    my $db  = $self->db($key);
    752822
    753823    $log->debug("entered - @_");
     
    816886    my $log = $self->log;
    817887    my $sql = $self->sql;
    818     my $db  =$self->db;
     888    my $db  = $self->db($key);
    819889
    820890    $log->debug("entered - @_");
     
    869939    my $log = $self->log;
    870940    my $sql = $self->sql;
    871     my $db  =$self->db;
     941    my $db  = $self->db($key);
    872942
    873943    $log->debug("entered - @_");
     
    912982    my $log = $self->log;
    913983    my $sql = $self->sql;
    914     my $db  =$self->db;
     984    my $db  = $self->db($key);
    915985
    916986    $log->debug("entered - @_");
     
    9471017sub find_objects
    9481018{
    949     my $self = shift;
    950 
    951     my ( $pattern ) = validate_pos( @_,
     1019    # XXX: this will only search one db
     1020
     1021    my $self = shift;
     1022
     1023    my ($pattern) = validate_pos( @_,
    9521024        {
    9531025            type        => SCALAR,
     
    9581030    my $log = $self->log;
    9591031    my $sql = $self->sql;
    960     my $db  =$self->db;
     1032    my $db  = $self->db;
    9611033
    9621034    $log->debug( "entered - @_" );
     
    10161088    my $log = $self->log;
    10171089    my $sql = $self->sql;
    1018     my $db  =$self->db;
     1090    my $db  = $self->db($key);
    10191091
    10201092    $log->debug("entered - @_");
     
    10271099    # to check it after parsing the key
    10281100    if (defined $vol_name
    1029         and not $self->_is_valid_volume_name($key->volume)) {
     1101        and not $self->_is_valid_volume_name($key, $key->volume)) {
    10301102        if ($key->soft_volume) {
    10311103            $log->warn( "$vol_name is not a known volume name" );
     
    10871159    my $self = shift;
    10881160
    1089     my ( $uri ) = validate_pos( @_,
     1161    my ($key, $uri) = validate_pos( @_,
     1162        {
     1163            type        => SCALAR,
     1164            callbacks   => {
     1165                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     1166            },
     1167        },
    10901168        {
    10911169            type => SCALAR|SCALARREF,
     
    10951173    my $log = $self->log;
    10961174    my $sql = $self->sql;
    1097     my $db  =$self->db;
     1175    my $db  = $self->db($key);
    10981176
    10991177    $log->debug( "entered - @_" );
     
    11821260    my $log = $self->log;
    11831261    my $sql = $self->sql;
    1184     my $db  =$self->db;
     1262    my $db  = $self->db($key);
    11851263
    11861264    $log->debug("entered - @_");
     
    12111289sub mounts
    12121290{
     1291    # XXX: this will only pull the mounts from one db
    12131292    my $self = shift;
    12141293
     
    12171296    my $log = $self->log;
    12181297    my $sql = $self->sql;
    1219     my $db  =$self->db;
     1298    my $db  = $self->db;
    12201299
    12211300    $log->debug("entered - @_");
     
    12461325    my $self = shift;
    12471326
    1248     my $log = $self->log;
    1249     my $sql = $self->sql;
    1250     my $db  = $self->db;
     1327    my ($key, $name, $soft_volume) = @_;
     1328
     1329    my $log = $self->log;
     1330    my $sql = $self->sql;
     1331    my $db  = $self->db($key);
    12511332
    12521333    no warnings qw( uninitialized );
    12531334    $log->debug( "entered - @_" );
    12541335    use warnings;
    1255 
    1256     my ($name, $soft_volume) = @_;
    12571336
    12581337    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    12711350                # find it, fall back to any volume
    12721351                if ($soft_volume) {
    1273                     ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume;
     1352                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume($key);
    12741353                    return; # this just returns out of the eval not from the subroutine
    12751354                }
     
    13111390    my $self = shift;
    13121391
    1313     my $log = $self->log;
    1314     my $sql = $self->sql;
    1315     my $db  =$self->db;
     1392    my $key = shift;
     1393
     1394    my $log = $self->log;
     1395    my $sql = $self->sql;
     1396    my $db  = $self->db($key);
    13161397
    13171398    no warnings qw( uninitialized );
     
    13191400    use warnings;
    13201401
    1321     my $key = shift;
    13221402
    13231403    $key = parse_neb_key($key);
     
    13611441    my $log = $self->log;
    13621442    my $sql = $self->sql;
    1363     my $db  =$self->db;
     1443    my $db  = $self->db($key);
    13641444
    13651445    $key = parse_neb_key($key);
     
    13881468sub _is_valid_volume_name
    13891469{
    1390     my ($self, $vol_name) = @_;
    1391 
    1392     my $log = $self->log;
    1393     my $sql = $self->sql;
    1394     my $db  =$self->db;
     1470    my ($self, $key, $vol_name) = @_;
     1471
     1472    my $log = $self->log;
     1473    my $sql = $self->sql;
     1474    my $db  = $self->db($key);
    13951475
    13961476    my $volume_info = parse_neb_volume($vol_name);
     
    14291509    my $log = $self->log;
    14301510    my $sql = $self->sql;
    1431     my $db  = $self->db;
     1511    my $db  = $self->db($key);
    14321512
    14331513    my $uri;
     
    15581638    my $log = $self->log;
    15591639    my $sql = $self->sql;
    1560     my $db  =$self->db;
     1640#    my $db  = $self->db;
    15611641
    15621642    $log->debug( "entered" );
    15631643
    1564     $self->db->disconnect;       
    1565 
    1566     $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
     1644#    $self->db->disconnect;       
     1645
     1646#    $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
    15671647
    15681648    $log->debug( "leaving" );
Note: See TracChangeset for help on using the changeset viewer.