Index: /trunk/Nebulous-Server/MANIFEST
===================================================================
--- /trunk/Nebulous-Server/MANIFEST	(revision 20964)
+++ /trunk/Nebulous-Server/MANIFEST	(revision 20965)
@@ -35,4 +35,5 @@
 t/00_distribution.t 
 t/01_load.t
+t/02_config.t
 t/02_server_setup.t
 t/03_server_create_object.t
Index: /trunk/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 20964)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 20965)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004-2008  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.93 2008-10-13 20:41:17 jhoblitt Exp $
+# $Id: Server.pm,v 1.94 2008-12-12 21:13:41 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -9,5 +9,5 @@
 no warnings qw( uninitialized );
 
-our $VERSION = '0.15';
+our $VERSION = '0.16';
 
 use base qw( Class::Accessor::Fast );
@@ -19,8 +19,8 @@
 use File::Spec;
 use Log::Log4perl;
+use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
 use Nebulous::Server::Config;
 use Nebulous::Server::Log;
 use Nebulous::Server::SQL;
-use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
 use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF );
 use URI::file;
@@ -36,5 +36,5 @@
 
     # let Nebulous::Server::Config validate our params
-    my $config = Nebulous::Server::Config->init( @_ );
+    my $config = Nebulous::Server::Config->new( @_ );
 
     # log4perl is not avaliable until we call init()
@@ -51,7 +51,4 @@
     $self->config($config);
 
-    # ask for the db handle as a means of validating the database parameters
-    $self->db;
-
     $log->debug( "leaving" );
     
@@ -62,10 +59,5 @@
 sub db
 {
-    my $self = shift;
-
-    if (@_) {
-        $self->{db} = $_[0];
-        return $self;
-    }
+    my ($self, $key) = @_;
 
     my $log     = $self->log;
@@ -73,11 +65,24 @@
     my $config  = $self->config;
 
+    my $db_index = 0;
+    if (defined $key) {
+        # hash the key to select the correct database instance
+        $db_index = unpack("%20h", sha1_hex("$key")) % $config->n_db;
+    }
+
+    # lookup to see if we have a stored dbh for this database
+    my $dbh = $self->{dbs}[$db_index];
     # if the dbh is still alive, return it
-    if (defined $self->{db} and $self->{db}->ping) {
+    if (defined $dbh and $dbh->ping) {
         $log->debug("db handle is still alive");
-        return $self->{db};
+        return $dbh;
     }
     # otherwise create a new connection
     $log->debug("db handle is dead/unopened");
+
+    # lookup database info
+    my $db_config = $config->db($db_index);
+    die "can't find database configuration info for database # $db_index"
+        unless $db_config;
 
     # if we're running under mod_perl & Apache::DBI is loaded we want to
@@ -86,10 +91,9 @@
     # processes and the database might have gone away on us.  Apache::DBI will
     # take care of getting a valid dbh back.
-    my $db;
-    eval {
-        $db = DBI->connect_cached(
-            $config->dsn,
-            $config->dbuser,
-            $config->dbpasswd,
+    eval {
+        $dbh = DBI->connect_cached(
+            $db_config->dsn,
+            $db_config->dbuser,
+            $db_config->dbpasswd,
             {
                 RaiseError => 1,
@@ -99,18 +103,18 @@
         );
 
-        $db->do( $sql->set_transaction_model );
-        $log->debug( "connected to database: ", sub { $db->data_sources; } );
-        $db->commit;
+        $dbh->do( $sql->set_transaction_model );
+        $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
+        $dbh->commit;
         $log->debug("commit");
     };
     if ( $@ ) {
-        $db->rollback if $db;
+        $dbh->rollback if $dbh;
         $log->debug("rollback");
         $log->logdie( "database error: $@" );
     }
 
-    $self->{db} = $db;
-
-    return $db;
+    $self->{dbs}[$db_index] = $dbh;
+
+    return $dbh;
 }
 
@@ -139,5 +143,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug( "entered - @_" );
@@ -150,5 +154,5 @@
     # to check it after parsing the key
     if (defined $vol_name
-        and not $self->_is_valid_volume_name($key->volume)) {
+        and not $self->_is_valid_volume_name($key, $key->volume)) {
         if ($key->soft_volume) {
             $log->warn( "$vol_name is not a known volume name" );
@@ -160,5 +164,5 @@
         
     my ($vol_id, $vol_host, $vol_path, $vol_xattr)
-        = $self->_get_storage_volume($vol_name, $key->soft_volume);
+        = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
 
     my $uri;
@@ -261,5 +265,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -296,91 +300,157 @@
 
 
-sub swap_objects
-{
-    my $self = shift;
-
-    my ($key1, $key2) = validate_pos(@_,
-        {
-            type        => SCALAR,
-            callbacks   => {
-                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
-            },
-        },
-        {
-            type        => SCALAR,
-            callbacks   => {
-                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
-            },
-        },
-    );
-
-    my $log = $self->log;
-    my $sql = $self->sql;
-    my $db  =$self->db;
-
-    $log->debug("entered - @_");
-
-    # ignore volumes
-    $key1 = parse_neb_key($key1);
-    $key2 = parse_neb_key($key2);
-
-    # order of operations for the swap:
-    # key1 -> key1.swap
-    # key2 -> key1
-    # key1.swap -> key2
-
-    eval {
-        {
-            # key1 -> key1.swap
-            my $query = $db->prepare_cached($sql->rename_object); 
-            # this SQL statment takes the new key name as the first param
-            my $rows = $query->execute($key1->path . ".swap", $key1->path);
-
-            # if we affected more then one row something very bad has happened.
-            unless ($rows == 1) {
-                $query->finish;
-                $log->logdie("affected row count is $rows instead of 1");
-            }
-        }
-
-        {
-            # key2 -> key1
-            my $query = $db->prepare_cached($sql->rename_object); 
-            # this SQL statment takes the new key name as the first param
-            my $rows = $query->execute($key1->path, $key2->path);
-
-            # if we affected more then one row something very bad has happened.
-            unless ($rows == 1) {
-                $query->finish;
-                $log->logdie("affected row count is $rows instead of 1");
-            }
-        }
-
-        {
-            # key1.swap -> key2
-            my $query = $db->prepare_cached($sql->rename_object); 
-            # this SQL statment takes the new key name as the first param
-            my $rows = $query->execute($key2->path, $key1->path . ".swap");
-
-            # if we affected more then one row something very bad has happened.
-            unless ($rows == 1) {
-                $query->finish;
-                $log->logdie("affected row count is $rows instead of 1");
-            }
-        }
-
-        $db->commit;
-        $log->debug("commit");
-    };
-    if ($@) {
-        $db->rollback;
-        $log->debug("rollback");
-        $log->logdie("database error: $@");
-    }
-
-    $log->debug("leaving");
-
-    return 1;
-}
+# sub swap_objects
+# {
+#     my $self = shift;
+# 
+#     my ($key1, $key2) = validate_pos(@_,
+#         {
+#             type        => SCALAR,
+#             callbacks   => {
+#                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+#             },
+#         },
+#         {
+#             type        => SCALAR,
+#             callbacks   => {
+#                 'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+#             },
+#         },
+#     );
+# 
+#     my $log  = $self->log;
+#     my $sql  = $self->sql;
+#     my $dbh1 = $self->db($key1);
+#     my $dbh2 = $self->db($key2);
+# 
+#     $log->debug("entered - @_");
+# 
+#     # ignore volumes
+#     $key1 = parse_neb_key($key1);
+#     $key2 = parse_neb_key($key2);
+# 
+#     # order of operations for the swap with a single db is:
+#     # key1 -> key1.swap
+#     # key2 -> key1
+#     # key1.swap -> key2
+# 
+#     # XXX this cmp will only work if ->db() returns the same exact (cached) dbh
+#     if ($dbh1 == $dbh2) {
+#         my $dbh = $dbh1;
+#         eval {
+#             {
+#                 # key1 -> key1.swap
+#                 my $query = $dbh->prepare_cached($sql->rename_object); 
+#                 # this SQL statment takes the new key name as the first param
+#                 my $rows = $query->execute($key1->path . ".swap", $key1->path);
+# 
+#                 # if we affected more then one row something very bad has happened.
+#                 unless ($rows == 1) {
+#                     $query->finish;
+#                     $log->logdie("affected row count is $rows instead of 1");
+#                 }
+#             }
+# 
+#             {
+#                 # key2 -> key1
+#                 my $query = $dbh->prepare_cached($sql->rename_object); 
+#                 # this SQL statment takes the new key name as the first param
+#                 my $rows = $query->execute($key1->path, $key2->path);
+# 
+#                 # if we affected more then one row something very bad has happened.
+#                 unless ($rows == 1) {
+#                     $query->finish;
+#                     $log->logdie("affected row count is $rows instead of 1");
+#                 }
+#             }
+# 
+#             {
+#                 # key1.swap -> key2
+#                 my $query = $dbh->prepare_cached($sql->rename_object); 
+#                 # this SQL statment takes the new key name as the first param
+#                 my $rows = $query->execute($key2->path, $key1->path . ".swap");
+# 
+#                 # if we affected more then one row something very bad has happened.
+#                 unless ($rows == 1) {
+#                     $query->finish;
+#                     $log->logdie("affected row count is $rows instead of 1");
+#                 }
+#             }
+# 
+#             $dbn->commit;
+#             $log->debug("commit");
+#         };
+#         if ($@) {
+#             $dbh->rollback;
+#             $log->debug("rollback");
+#             $log->logdie("database error: $@");
+#         }
+#     }
+# 
+#     # order of operations for the swap between two dbs is:
+#     # key1 start transaction
+#     # key1 -> read all instances
+#     # key1 -> remove all instances
+#     # key2 start transaction
+#     # key2 -> read all instances
+#     # key2 -> remove all instances
+#     # key1 -> insert key 2 instances
+#     # key2 -> insert key 1 instances
+#     # key1,2 commit
+# 
+#     eval {
+#         {
+#             # key1 -> read all instances
+#             my $query = $dbh->prepare_cached($sql->rename_object); 
+#             # this SQL statment takes the new key name as the first param
+#             my $rows = $query->execute($key1->path . ".swap", $key1->path);
+# 
+#             # if we affected more then one row something very bad has happened.
+#             unless ($rows == 1) {
+#                 $query->finish;
+#                 $log->logdie("affected row count is $rows instead of 1");
+#             }
+#         }
+# 
+#         {
+#             # key2 -> key1
+#             my $query = $db->prepare_cached($sql->rename_object); 
+#             # this SQL statment takes the new key name as the first param
+#             my $rows = $query->execute($key1->path, $key2->path);
+# 
+#             # if we affected more then one row something very bad has happened.
+#             unless ($rows == 1) {
+#                 $query->finish;
+#                 $log->logdie("affected row count is $rows instead of 1");
+#             }
+#         }
+# 
+#         {
+#             # key1.swap -> key2
+#             my $query = $db->prepare_cached($sql->rename_object); 
+#             # this SQL statment takes the new key name as the first param
+#             my $rows = $query->execute($key2->path, $key1->path . ".swap");
+# 
+#             # if we affected more then one row something very bad has happened.
+#             unless ($rows == 1) {
+#                 $query->finish;
+#                 $log->logdie("affected row count is $rows instead of 1");
+#             }
+#         }
+# 
+#         $db->commit;
+#         $log->debug("commit");
+#     };
+#         if ($@) {
+#             $db->rollback;
+#             $log->debug("rollback");
+#             $log->logdie("database error: $@");
+#         }
+# 
+# 
+#     $log->debug("leaving");
+# 
+#     return 1;
+# }
 
 
@@ -420,5 +490,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -429,5 +499,5 @@
 
     if (defined $vol_name
-        and not $self->_is_valid_volume_name($key->volume)) {
+        and not $self->_is_valid_volume_name($key, $key->volume)) {
         if ($key->soft_volume) {
             $log->warn( "$vol_name is not a known volume name" );
@@ -441,5 +511,5 @@
     if (defined $vol_name) {
         ($vol_id, $vol_host, $vol_path, $vol_xattr)
-            = $self->_get_storage_volume($vol_name);
+            = $self->_get_storage_volume($key, $vol_name);
     } else {
         ($vol_id, $vol_host, $vol_path, $vol_xattr)
@@ -534,5 +604,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug( "entered - @_" );
@@ -637,5 +707,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug( "entered - @_" );
@@ -749,5 +819,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -816,5 +886,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -869,5 +939,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -912,5 +982,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -947,7 +1017,9 @@
 sub find_objects
 {
-    my $self = shift;
-
-    my ( $pattern ) = validate_pos( @_,
+    # XXX: this will only search one db
+
+    my $self = shift;
+
+    my ($pattern) = validate_pos( @_,
         {
             type        => SCALAR,
@@ -958,5 +1030,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db;
 
     $log->debug( "entered - @_" );
@@ -1016,5 +1088,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -1027,5 +1099,5 @@
     # to check it after parsing the key
     if (defined $vol_name
-        and not $self->_is_valid_volume_name($key->volume)) {
+        and not $self->_is_valid_volume_name($key, $key->volume)) {
         if ($key->soft_volume) {
             $log->warn( "$vol_name is not a known volume name" );
@@ -1087,5 +1159,11 @@
     my $self = shift;
 
-    my ( $uri ) = validate_pos( @_,
+    my ($key, $uri) = validate_pos( @_,
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
+            },
+        },
         {
             type => SCALAR|SCALARREF,
@@ -1095,5 +1173,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug( "entered - @_" );
@@ -1182,5 +1260,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $log->debug("entered - @_");
@@ -1211,4 +1289,5 @@
 sub mounts
 {
+    # XXX: this will only pull the mounts from one db
     my $self = shift;
 
@@ -1217,5 +1296,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db;
 
     $log->debug("entered - @_");
@@ -1246,13 +1325,13 @@
     my $self = shift;
 
-    my $log = $self->log;
-    my $sql = $self->sql;
-    my $db  = $self->db;
+    my ($key, $name, $soft_volume) = @_;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  = $self->db($key);
 
     no warnings qw( uninitialized );
     $log->debug( "entered - @_" );
     use warnings;
-
-    my ($name, $soft_volume) = @_;
 
     my ($vol_id, $vol_host, $vol_path, $xattr);
@@ -1271,5 +1350,5 @@
                 # find it, fall back to any volume
                 if ($soft_volume) {
-                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume;
+                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume($key);
                     return; # this just returns out of the eval not from the subroutine
                 }
@@ -1311,7 +1390,9 @@
     my $self = shift;
 
-    my $log = $self->log;
-    my $sql = $self->sql;
-    my $db  =$self->db;
+    my $key = shift;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  = $self->db($key);
 
     no warnings qw( uninitialized );
@@ -1319,5 +1400,4 @@
     use warnings;
 
-    my $key = shift;
 
     $key = parse_neb_key($key);
@@ -1361,5 +1441,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+    my $db  = $self->db($key);
 
     $key = parse_neb_key($key);
@@ -1388,9 +1468,9 @@
 sub _is_valid_volume_name
 {
-    my ($self, $vol_name) = @_;
-
-    my $log = $self->log;
-    my $sql = $self->sql;
-    my $db  =$self->db;
+    my ($self, $key, $vol_name) = @_;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  = $self->db($key);
 
     my $volume_info = parse_neb_volume($vol_name);
@@ -1429,5 +1509,5 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  = $self->db;
+    my $db  = $self->db($key);
 
     my $uri;
@@ -1558,11 +1638,11 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
+#    my $db  = $self->db;
 
     $log->debug( "entered" );
 
-    $self->db->disconnect;        
-
-    $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
+#    $self->db->disconnect;        
+
+#    $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
 
     $log->debug( "leaving" );
Index: /trunk/Nebulous-Server/lib/Nebulous/Server/Config.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server/Config.pm	(revision 20964)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server/Config.pm	(revision 20965)
@@ -1,5 +1,5 @@
 # Copyright (C) 2005  Joshua Hoblitt
 #
-# $Id: Config.pm,v 1.3 2008-03-20 21:10:57 jhoblitt Exp $
+# $Id: Config.pm,v 1.4 2008-12-12 21:13:41 jhoblitt Exp $
 
 package Nebulous::Server::Config;
@@ -8,10 +8,10 @@
 use warnings FATAL => qw( all );
 
-our $VERSION = 0.02;
+our $VERSION = 0.03;
 
 use base qw( Class::Accessor::Fast );
 
 use Log::Log4perl qw( :levels );
-use Params::Validate qw( validate SCALAR );
+use Params::Validate qw( validate validate_pos SCALAR );
 
 our %LEVELS = (
@@ -25,8 +25,15 @@
 );
 
-my $new_validate = {
+my $db_validate = {
+    dbindex       => {
+        type => SCALAR,
+        regex => qr/^\d+$/,
+    },
     dsn         => { type => SCALAR },
     dbuser      => { type => SCALAR },
     dbpasswd    => { type => SCALAR },
+};
+
+my $new_validate = {
     log_level   => {
         type        => SCALAR,
@@ -39,9 +46,14 @@
         },
     },
+    dsn         => { type => SCALAR, optional => 1 },
+    dbuser      => { type => SCALAR, optional => 1 },
+    dbpasswd    => { type => SCALAR, optional => 1 },
 };
 
 __PACKAGE__->mk_ro_accessors( keys %$new_validate );
 
-sub init {
+
+sub new
+{
     my $class = shift;
 
@@ -49,13 +61,74 @@
 
     # normalize log levels to lower-case
-    $p{ log_level } = lc $p{ log_level };
-
-    my $self = \%p;
+    my $self ={ log_level => lc $p{ log_level } };
 
     bless $self, $class || ref $class;
+
+    my @dbs;
+    $self->{dbs} = \@dbs;
+
+    if (defined $p{dsn} or defined $p{dbuser} or defined $p{dbpasswd}) {
+        $self->add_db(
+            dbindex     => 0,
+            dsn         => $p{dsn},
+            dbuser      => $p{dbuser},
+            dbpasswd    => $p{dbpasswd},
+        );
+    }
 
     return $self;
 }
 
+
+sub add_db
+{
+    my $self = shift;
+    
+    my %p = validate( @_, $db_validate );
+
+    my $config_db = Nebulous::Server::Config::DB->new({
+        dsn         => $p{dsn},
+        dbuser      => $p{dbuser},
+        dbpasswd    => $p{dbpasswd},
+    });
+
+    $self->{dbs}->[$p{dbindex}] = $config_db;
+
+    return $self;
+}
+
+
+sub db 
+{
+    my $self = shift;
+
+    my ($db_index) = validate_pos( @_, { type => SCALAR, optional => 1, });
+
+    # default to 0
+    $db_index ||= 0;
+
+    return $self->{dbs}->[$db_index];
+}
+
+
+sub n_db 
+{
+    my $self = shift;
+
+    return scalar @{ $self->{dbs} };
+}
+
+
+package Nebulous::Server::Config::DB;
+
+use strict;
+use warnings FATAL => qw( all );
+
+our $VERSION = 0.01;
+
+use base qw( Class::Accessor::Fast );
+
+__PACKAGE__->mk_ro_accessors(qw( dsn dbuser dbpasswd )); 
+
 1;
 
Index: /trunk/Nebulous-Server/lib/Nebulous/Server/Log.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server/Log.pm	(revision 20964)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server/Log.pm	(revision 20965)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Log.pm,v 1.7 2008-05-07 00:02:10 jhoblitt Exp $
+# $Id: Log.pm,v 1.8 2008-12-12 21:13:41 jhoblitt Exp $
 
 package Nebulous::Server::Log;
@@ -16,7 +16,7 @@
     my ($self, $config) = @_;
 
-    my $dsn         = $config->dsn;
-    my $dbuser      = $config->dbuser;
-    my $dbpasswd    = $config->dbpasswd;
+#    my $dsn         = $config->db->dsn;
+#    my $dbuser      = $config->db->dbuser;
+#    my $dbpasswd    = $config->db->dbpasswd;
 
     my $conf = <<END;
@@ -30,9 +30,9 @@
 #   date | hostname | priority | method/sub - message\n
 
-    log4perl.appender.SQLLOG            = Log::Log4perl::Appender::DBI
-    log4perl.appender.SQLLOG.datasource = $dsn
-    log4perl.appender.SQLLOG.username   = $dbuser
-    log4perl.appender.SQLLOG.password   = $dbpasswd
-    log4perl.appender.SQLLOG.sql        = \
+#    log4perl.appender.SQLLOG            = Log::Log4perl::Appender::DBI
+#    log4perl.appender.SQLLOG.sql        = \
+#    log4perl.appender.SQLLOG.datasource = 
+#    log4perl.appender.SQLLOG.username   = 
+#    log4perl.appender.SQLLOG.password   = 
     INSERT INTO log (timestamp, hostname, level, sub, message) \
     VALUES          (%d,        %H,       %p,    %M,  %m)
Index: /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm
===================================================================
--- /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 20964)
+++ /trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 20965)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: SQL.pm,v 1.75 2008-10-15 20:45:51 jhoblitt Exp $
+# $Id: SQL.pm,v 1.76 2008-12-12 21:13:41 jhoblitt Exp $
 
 package Nebulous::Server::SQL;
@@ -8,5 +8,5 @@
 use warnings FATAL => qw( all );
 
-our $VERSION = '0.02';
+our $VERSION = '0.03';
 
 use base qw( Class::Accessor::Fast );
@@ -47,4 +47,8 @@
         (so_id, vol_id, uri)
         VALUES (?, ?, 'error')
+    },
+    get_all_instances   => qq{
+        SELECT * FROM INSTANCE
+        WHERE so_id = ?
     },
     get_object          => qq{
Index: /trunk/Nebulous-Server/t/02_config.t
===================================================================
--- /trunk/Nebulous-Server/t/02_config.t	(revision 20965)
+++ /trunk/Nebulous-Server/t/02_config.t	(revision 20965)
@@ -0,0 +1,110 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 02_config.t,v 1.1 2008-12-12 21:13:41 jhoblitt Exp $
+
+use strict;
+use warnings;
+
+use Test::More tests => 21;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Server::Config;
+
+isa_ok(Nebulous::Server::Config->new(), "Nebulous::Server::Config");
+
+{
+    my $config = Nebulous::Server::Config->new;
+
+    ok($config->add_db(
+        dbindex     => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    ), "add a db");
+
+    is($config->n_db, 1, "number of dbs");
+}
+
+
+{
+    my $config = Nebulous::Server::Config->new;
+
+    ok($config->add_db(
+        dbindex     => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    ), "add a db");
+
+    ok($config->add_db(
+        dbindex     => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    ), "add a db");
+
+    is($config->n_db, 1, "number of dbs");
+}
+
+{
+    my $config = Nebulous::Server::Config->new;
+
+    ok($config->add_db(
+        dbindex     => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    ), "add a db");
+
+    ok($config->add_db(
+        dbindex     => 1,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    ), "add a db");
+
+    is($config->n_db, 2, "number of dbs");
+}
+
+{
+    my $config = Nebulous::Server::Config->new;
+
+    $config->add_db(
+        dbindex     => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    => "boo",
+    );
+
+    $config->add_db(
+        dbindex     => 1,
+        dsn         => "DBI:mysql:database=foobar:host=localhost2",
+        dbuser      => "baz2",
+        dbpasswd    => "boo2",
+    );
+
+    # default should be 0
+    my $config_db = $config->db();
+
+    isa_ok($config_db, "Nebulous::Server::Config::DB");
+    is($config_db->dsn, "DBI:mysql:database=foobar:host=localhost", "dsn");
+    is($config_db->dbuser, "baz", "dbuser");
+    is($config_db->dbpasswd, "boo", "dbpasswd");
+
+    my $config_db0 = $config->db(0);
+
+    isa_ok($config_db0, "Nebulous::Server::Config::DB");
+    is($config_db0->dsn, "DBI:mysql:database=foobar:host=localhost", "dsn");
+    is($config_db0->dbuser, "baz", "dbuser");
+    is($config_db0->dbpasswd, "boo", "dbpasswd");
+
+    my $config_db1 = $config->db(1);
+
+    isa_ok($config_db1, "Nebulous::Server::Config::DB");
+    is($config_db1->dsn, "DBI:mysql:database=foobar:host=localhost2", "dsn");
+    is($config_db1->dbuser, "baz2", "dbuser");
+    is($config_db1->dbpasswd, "boo2", "dbpasswd");
+}
Index: /trunk/Nebulous-Server/t/02_server_setup.t
===================================================================
--- /trunk/Nebulous-Server/t/02_server_setup.t	(revision 20964)
+++ /trunk/Nebulous-Server/t/02_server_setup.t	(revision 20965)
@@ -3,10 +3,10 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 02_server_setup.t,v 1.6 2008-02-02 01:51:29 jhoblitt Exp $
+# $Id: 02_server_setup.t,v 1.7 2008-12-12 21:13:41 jhoblitt Exp $
 
 use strict;
 use warnings;
 
-use Test::More tests => 2;
+use Test::More tests => 6;
 
 use lib qw( ./t ./lib );
@@ -17,23 +17,49 @@
 Test::Nebulous->setup;
 
-isa_ok(
-    Nebulous::Server->new(
-        dsn         => $NEB_DB,
-        dbuser      => $NEB_USER,
-        dbpasswd    => $NEB_PASS,
-    ),
-    "Nebulous::Server"
-);
+isa_ok(Nebulous::Server->new(), "Nebulous::Server");
 
 Test::Nebulous->setup;
 
-eval {
-    Nebulous::Server->new(
+# ->new()
+{
+    my $neb = Nebulous::Server->new( log_level => 'off' );
+
+    ok($neb, "set log level");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Server->new(
         dsn         => "DBI:mysql:database=foobar:host=localhost",
         dbuser      => "baz",
         dbpasswd    =>"boo",
     );
-};
-like( $@, qr/DBI connect.*? failed/, "bad dsn/user/pass" );
+
+    ok($neb, "set database");
+}
+
+Test::Nebulous->setup;
+
+# add dbs after ->new()
+{
+    my $neb = Nebulous::Server->new;
+
+    ok($neb->config->add_db(
+        dbindex    => 0,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    =>"boo",
+    ), "add db");
+    
+    ok($neb->config->add_db(
+        dbindex    => 1,
+        dsn         => "DBI:mysql:database=foobar:host=localhost",
+        dbuser      => "baz",
+        dbpasswd    =>"boo",
+    ), "add dbs");
+
+    is($neb->config->n_db, 2, "n dbs")
+}
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous-Server/t/08_server_delete_instance.t
===================================================================
--- /trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 20964)
+++ /trunk/Nebulous-Server/t/08_server_delete_instance.t	(revision 20965)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 08_server_delete_instance.t,v 1.10 2008-03-20 21:10:14 jhoblitt Exp $
+# $Id: 08_server_delete_instance.t,v 1.11 2008-12-12 21:13:41 jhoblitt Exp $
 
 use strict;
@@ -24,7 +24,8 @@
 
 {
-    my $uri = $neb->create_object("foo");
+    my $key = "foo";
+    my $uri = $neb->create_object($key);
 
-    ok($neb->delete_instance($uri), "delete instance");
+    ok($neb->delete_instance($key, $uri), "delete instance");
 }
 
@@ -32,17 +33,18 @@
 
 {
-    my $uri1 = $neb->create_object("foo");
-    my $uri2 = $neb->replicate_object("foo");
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+    my $uri2 = $neb->replicate_object($key);
 
-    ok($neb->delete_instance($uri1), "delete instance");
+    ok($neb->delete_instance($key, $uri1), "delete instance");
 
-    my $locations = $neb->find_instances("foo");
+    my $locations = $neb->find_instances($key);
 
     is($locations->[0], $uri2, "instance remains");
 
-    ok($neb->delete_instance( $uri2 ), "delete instance");
+    ok($neb->delete_instance($key, $uri2), "delete instance");
 
     eval {
-        $neb->find_instances("foo");
+        $neb->find_instances($key);
     };
     like($@, qr/is valid object key/, "storage object was deleted");
@@ -52,5 +54,8 @@
 
 eval {
-    $neb->delete_instance("file:/foo");
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+
+    $neb->delete_instance($key, "file:/foo");
 };
 like($@, qr/no instance is associated with uri/, "uri does not exist");
@@ -61,12 +66,15 @@
     $neb->delete_instance();
 };
-like($@, qr/1 was expected/, "no params");
+like($@, qr/2 were expected/, "no params");
 
 Test::Nebulous->setup;
 
 eval {
-    $neb->delete_instance("foo", 2);
+    my $key = "foo";
+    my $uri1 = $neb->create_object($key);
+
+    $neb->delete_instance("foo", 2, 3);
 };
-like($@, qr/1 was expected/, "too many params");
+like($@, qr/2 were expected/, "too many params");
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t
===================================================================
--- /trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t	(revision 20964)
+++ /trunk/Nebulous-Server/t/10_server_is_valid_volume_name.t	(revision 20965)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 10_server_is_valid_volume_name.t,v 1.5 2008-03-20 21:10:14 jhoblitt Exp $
+# $Id: 10_server_is_valid_volume_name.t,v 1.6 2008-12-12 21:13:41 jhoblitt Exp $
 
 use strict;
@@ -23,13 +23,13 @@
 Test::Nebulous->setup;
 
-ok($neb->_is_valid_volume_name('node01'), "valid volume name");
+ok($neb->_is_valid_volume_name('foo', 'node01'), "valid volume name");
 
 Test::Nebulous->setup;
 
-ok($neb->_is_valid_volume_name('node02'), "valid volume name");
+ok($neb->_is_valid_volume_name('foo', 'node02'), "valid volume name");
 
 Test::Nebulous->setup;
 
-is($neb->_is_valid_volume_name('node99'), undef, "invalid volume name");
+is($neb->_is_valid_volume_name('foo', 'node99'), undef, "invalid volume name");
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous/lib/Nebulous/Client.pm
===================================================================
--- /trunk/Nebulous/lib/Nebulous/Client.pm	(revision 20964)
+++ /trunk/Nebulous/lib/Nebulous/Client.pm	(revision 20965)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004-2008  Joshua Hoblitt
 #
-# $Id: Client.pm,v 1.62 2008-10-13 21:20:33 jhoblitt Exp $
+# $Id: Client.pm,v 1.63 2008-12-12 21:13:41 jhoblitt Exp $
 
 package Nebulous::Client;
@@ -243,5 +243,5 @@
         # if the copy failed we now have a zero length instances floating
         # around that must be removed
-        unless ($self->delete_instance("$uri")) {
+        unless ($self->delete_instance($key, "$uri")) {
             $log->logdie( "can not copy instance $uri AND FAILED TO CLEANUP EMPTY INSTANCE" );
         }
@@ -256,5 +256,5 @@
 
     unless ($src_md5 eq $dst_md5) {
-        $self->delete_instance("$uri");
+        $self->delete_instance($key, "$uri");
         $log->logdie( "md5sum mismatch" );
     }
@@ -327,5 +327,5 @@
     }
 
-    my $uri = $self->delete_instance( @$locations[0] );
+    my $uri = $self->delete_instance($key, @$locations[0]);
 
     $log->debug("leaving");
@@ -813,5 +813,5 @@
     # a lock is implicitly removed when the last storage object is deleted
     foreach my $uri ( @$locations ) {
-        $self->delete_instance( $uri ) or return undef;
+        $self->delete_instance($key, $uri) or return undef;
     }
 
@@ -944,5 +944,8 @@
     my $self = shift;
 
-    my ($uri) = validate_pos(@_,
+    my ($key, $uri) = validate_pos(@_,
+        {
+            type => SCALAR,
+        },
         {
             type => SCALAR,
@@ -961,5 +964,5 @@
     $log->logdie( $@ ) if $@;
 
-    my $response = $self->{ 'server' }->delete_instance( $uri );
+    my $response = $self->{ 'server' }->delete_instance($key, $uri);
     if ( $response->fault ) {
         $self->set_err($response->faultstring);
Index: /trunk/Nebulous/nebclient/nebulous.wsdl
===================================================================
--- /trunk/Nebulous/nebclient/nebulous.wsdl	(revision 20964)
+++ /trunk/Nebulous/nebclient/nebulous.wsdl	(revision 20965)
@@ -125,4 +125,5 @@
 
     <message name="delete_instanceRequest">
+        <part name="key" type="xsd:string" />
         <part name="uri" type="xsd:string" />
     </message>
Index: /trunk/Nebulous/nebclient/src/nebclient.c
===================================================================
--- /trunk/Nebulous/nebclient/src/nebclient.c	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/nebclient.c	(revision 20965)
@@ -4,5 +4,5 @@
  * Copyright (C) 2005  Joshua Hoblitt
  *
- * $Id: nebclient.c,v 1.54 2008-10-23 22:30:44 bills Exp $
+ * $Id: nebclient.c,v 1.55 2008-12-12 21:13:41 jhoblitt Exp $
  */
 
@@ -253,5 +253,5 @@
     }
 
-    if (!nebDeleteInstance(server, locations->URI[0])) {
+    if (!nebDeleteInstance(server, key, locations->URI[0])) {
         nebObjectInstancesFree(locations);
 
@@ -539,5 +539,5 @@
 
     for (int i = 0; i < locations->n; i++) {
-        if (!nebDeleteInstance(server, locations->URI[i])) {
+        if (!nebDeleteInstance(server, key, locations->URI[i])) {
             nebSetErr(server, "can not delete instance");
             nebObjectInstancesFree(locations);
@@ -655,5 +655,5 @@
 }
 
-bool nebDeleteInstance(nebServer *server, const char *URI)
+bool nebDeleteInstance(nebServer *server, const char *key, const char *URI)
 {
     int             response;
@@ -676,5 +676,5 @@
 
     if (soap_call_ns1__delete_USCOREinstance(server->soap, server->endpoint,
-            NULL, (char *)URI, &response) != SOAP_OK) {
+            NULL, (char *)key, (char *)URI, &response) != SOAP_OK) {
         nebFree(filename);
 
Index: /trunk/Nebulous/nebclient/src/nebclient.h
===================================================================
--- /trunk/Nebulous/nebclient/src/nebclient.h	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/nebclient.h	(revision 20965)
@@ -4,5 +4,5 @@
  * Copyright (C) 2005  Joshua Hoblitt
  *
- * $Id: nebclient.h,v 1.36 2008-10-23 22:30:44 bills Exp $
+ * $Id: nebclient.h,v 1.37 2008-12-12 21:13:41 jhoblitt Exp $
  */
 
@@ -248,4 +248,5 @@
 bool nebDeleteInstance(
     nebServer *server,                  ///< nebServer object
+    const char *key,                    ///< storage object key (name)
     const char *URI                     ///< URL of instance to remove
 );
Index: /trunk/Nebulous/nebclient/src/nebulous.h
===================================================================
--- /trunk/Nebulous/nebclient/src/nebulous.h	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/nebulous.h	(revision 20965)
@@ -1,5 +1,5 @@
 /* src/nebulous.h
    Generated by wsdl2h 1.2.11 from nebulous.wsdl and typemap.dat
-   2008-10-16 23:26:37 GMT
+   2008-12-11 21:42:13 GMT
    Copyright (C) 2001-2008 Robert van Engelen, Genivia Inc. All Rights Reserved.
    This part of the software is released under one of the following licenses:
@@ -808,4 +808,5 @@
     NULL, // char *action = NULL selects default action for this operation
     // request parameters:
+    char*                               key,
     char*                               uri,
     // response parameters:
@@ -819,4 +820,5 @@
     struct soap *soap,
     // request parameters:
+    char*                               key,
     char*                               uri,
     // response parameters:
@@ -831,4 +833,5 @@
 //gsoap ns1  service method-action:	delete_USCOREinstance urn:Nebulous/Server/SOAP#delete_instance
 int ns1__delete_USCOREinstance(
+    char*                               key,	///< Request parameter
     char*                               uri,	///< Request parameter
     int                                *result	///< Response parameter
Index: /trunk/Nebulous/nebclient/src/soapC.c
===================================================================
--- /trunk/Nebulous/nebclient/src/soapC.c	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/soapC.c	(revision 20965)
@@ -12,5 +12,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapC.c ver 2.7.11 2008-10-16 23:26:39 GMT")
+SOAP_SOURCE_STAMP("@(#) soapC.c ver 2.7.11 2008-12-11 21:42:14 GMT")
 
 
@@ -1342,4 +1342,5 @@
 {
 	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_default_string(soap, &a->key);
 	soap_default_string(soap, &a->uri);
 }
@@ -1348,4 +1349,5 @@
 {
 	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_serialize_string(soap, &a->key);
 	soap_serialize_string(soap, &a->uri);
 }
@@ -1363,4 +1365,6 @@
 	if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__delete_USCOREinstance), type))
 		return soap->error;
+	if (soap_out_string(soap, "key", -1, &a->key, ""))
+		return soap->error;
 	if (soap_out_string(soap, "uri", -1, &a->uri, ""))
 		return soap->error;
@@ -1378,4 +1382,5 @@
 SOAP_FMAC3 struct ns1__delete_USCOREinstance * SOAP_FMAC4 soap_in_ns1__delete_USCOREinstance(struct soap *soap, const char *tag, struct ns1__delete_USCOREinstance *a, const char *type)
 {
+	size_t soap_flag_key = 1;
 	size_t soap_flag_uri = 1;
 	if (soap_element_begin_in(soap, tag, 0, type))
@@ -1389,4 +1394,9 @@
 		for (;;)
 		{	soap->error = SOAP_TAG_MISMATCH;
+			if (soap_flag_key && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))
+				if (soap_in_string(soap, "key", &a->key, "xsd:string"))
+				{	soap_flag_key--;
+					continue;
+				}
 			if (soap_flag_uri && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))
 				if (soap_in_string(soap, "uri", &a->uri, "xsd:string"))
Index: /trunk/Nebulous/nebclient/src/soapClient.c
===================================================================
--- /trunk/Nebulous/nebclient/src/soapClient.c	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/soapClient.c	(revision 20965)
@@ -10,5 +10,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapClient.c ver 2.7.11 2008-10-16 23:26:38 GMT")
+SOAP_SOURCE_STAMP("@(#) soapClient.c ver 2.7.11 2008-12-11 21:42:13 GMT")
 
 
@@ -700,5 +700,5 @@
 }
 
-SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__delete_USCOREinstance(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *uri, int *result)
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__delete_USCOREinstance(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, char *uri, int *result)
 {	struct ns1__delete_USCOREinstance soap_tmp_ns1__delete_USCOREinstance;
 	struct ns1__delete_USCOREinstanceResponse *soap_tmp_ns1__delete_USCOREinstanceResponse;
@@ -708,4 +708,5 @@
 		soap_action = "urn:Nebulous/Server/SOAP#delete_instance";
 	soap->encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
+	soap_tmp_ns1__delete_USCOREinstance.key = key;
 	soap_tmp_ns1__delete_USCOREinstance.uri = uri;
 	soap_begin(soap);
Index: /trunk/Nebulous/nebclient/src/soapServer.c
===================================================================
--- /trunk/Nebulous/nebclient/src/soapServer.c	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/soapServer.c	(revision 20965)
@@ -10,5 +10,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapServer.c ver 2.7.11 2008-10-16 23:26:38 GMT")
+SOAP_SOURCE_STAMP("@(#) soapServer.c ver 2.7.11 2008-12-11 21:42:13 GMT")
 
 
@@ -643,5 +643,5 @@
 	 || soap_end_recv(soap))
 		return soap->error;
-	soap->error = ns1__delete_USCOREinstance(soap, soap_tmp_ns1__delete_USCOREinstance.uri, &soap_tmp_int);
+	soap->error = ns1__delete_USCOREinstance(soap, soap_tmp_ns1__delete_USCOREinstance.key, soap_tmp_ns1__delete_USCOREinstance.uri, &soap_tmp_int);
 	if (soap->error)
 		return soap->error;
Index: /trunk/Nebulous/nebclient/src/soapStub.h
===================================================================
--- /trunk/Nebulous/nebclient/src/soapStub.h	(revision 20964)
+++ /trunk/Nebulous/nebclient/src/soapStub.h	(revision 20965)
@@ -283,4 +283,5 @@
 struct ns1__delete_USCOREinstance
 {
+	char *key;	/* optional element of type xsd:string */
 	char *uri;	/* optional element of type xsd:string */
 };
@@ -432,5 +433,5 @@
 SOAP_FMAC5 int SOAP_FMAC6 ns1__find_USCOREinstances(struct soap*, char *key, char *volume, struct ns1__find_USCOREinstancesResponse *_param_3);
 
-SOAP_FMAC5 int SOAP_FMAC6 ns1__delete_USCOREinstance(struct soap*, char *uri, int *result);
+SOAP_FMAC5 int SOAP_FMAC6 ns1__delete_USCOREinstance(struct soap*, char *key, char *uri, int *result);
 
 SOAP_FMAC5 int SOAP_FMAC6 ns1__stat_USCOREobject(struct soap*, char *key, struct ns1__stat_USCOREobjectResponse *_param_4);
@@ -467,5 +468,5 @@
 SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__find_USCOREinstances(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, char *volume, struct ns1__find_USCOREinstancesResponse *_param_3);
 
-SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__delete_USCOREinstance(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *uri, int *result);
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__delete_USCOREinstance(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, char *uri, int *result);
 
 SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__stat_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, struct ns1__stat_USCOREobjectResponse *_param_4);
Index: /trunk/Nebulous/t/62_client_delete_instance.t
===================================================================
--- /trunk/Nebulous/t/62_client_delete_instance.t	(revision 20964)
+++ /trunk/Nebulous/t/62_client_delete_instance.t	(revision 20965)
@@ -3,5 +3,5 @@
 # Copryight (C) 2004-2005  Joshua Hoblitt
 #
-# $Id: 62_client_delete_instance.t,v 1.1 2005-12-03 02:52:31 jhoblitt Exp $
+# $Id: 62_client_delete_instance.t,v 1.2 2008-12-12 21:13:41 jhoblitt Exp $
 
 use strict;
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 9;
+plan tests => 11;
 
 use lib qw( ./t ./lib );
@@ -26,9 +26,11 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->create( "foo" );
 
-    my $locations = $neb->find_instances( "foo" );
+    my $key = "foo";
+    $neb->create($key);
 
-    my $uri = $neb->delete_instance( @$locations[0] );
+    my $locations = $neb->find_instances($key);
+
+    my $uri = $neb->delete_instance($key, @$locations[0]);
 
     is( $uri, @$locations[0], "delete instance" );
@@ -43,10 +45,11 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->create( "foo" );
-    $neb->replicate( "foo" );
+    my $key = "foo";
+    $neb->create($key);
+    $neb->replicate($key);
 
     my $uri1 = $neb->find_instances( "foo" )->[0];
 
-    ok( $neb->delete_instance( $uri1 ), "delete instance" );
+    ok( $neb->delete_instance($key, $uri1), "delete instance" );
 
     my $uri2 = $neb->find_instances( "foo" )->[0];
@@ -54,10 +57,12 @@
     isnt( $uri1, $uri2, "other instance remains" );
 
-    ok( $neb->delete_instance( $uri2 ), "delete instance" );
+    ok( $neb->delete_instance($key, $uri2), "delete instance" );
 
     my $locations = $neb->find_instances( "foo" );
 
-    is( $locations, undef, "no remaning instances" );
+    is( $locations, undef, "no remaining instances" );
 }
+
+Test::Nebulous->setup;
 
 {
@@ -65,5 +70,7 @@
         proxy => "http://$hostport/nebulous",
     );
-    my $uri = $neb->delete_instance( "file:/foo" );
+    my $key = "foo";
+    $neb->create($key);
+    my $uri = $neb->delete_instance($key, "file:/foo" );
 
     is( $uri, undef, "uri does not exist" );
@@ -76,7 +83,7 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->delete_instance();
+    my $uri = $neb->delete_instance("foo", "file:/foo" );
 };
-like( $@, qr/1 was expected/, "no params" );
+like( $@, qr/is valid object key/, "bad object key" );
 
 Test::Nebulous->setup;
@@ -86,7 +93,27 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->delete_instance( "foo", 2 );
+    my $uri = $neb->delete_instance("foo");
 };
-like( $@, qr/1 was expected/, "too many params" );
+like( $@, qr/2 were expected/, "missing second param" );
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->delete_instance();
+};
+like( $@, qr/2 were expected/, "no params" );
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->delete_instance("foo", 2, 3);
+};
+like( $@, qr/2 were expected/, "too many params" );
 
 Test::Nebulous->cleanup;
