Index: /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server.pm	(revision 23771)
+++ /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server.pm	(revision 23772)
@@ -24,5 +24,5 @@
 use Nebulous::Server::Log;
 use Nebulous::Server::SQL;
-use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF );
+use Params::Validate qw( validate validate_pos SCALAR SCALARREF UNDEF BOOLEAN );
 use URI::file;
 
@@ -210,5 +210,5 @@
         = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
 
-    my $parent_id = $self->_resolve_dir_parent_id($key);
+    my $parent_id = $self->_resolve_dir_parent_id(key => $key, create => 1);
 
     my $uri;
@@ -300,9 +300,18 @@
     my $self = shift;
 
-    my ($key) = validate_pos(@_,
-        {
-            isa => 'Nebulous::Key',
-        },
+    my %p = validate(@_,
+        {
+            key     => {
+                isa         => 'Nebulous::Key',
+            },
+            create  => {
+                type        => BOOLEAN,
+                optional    => 1,
+                default     => undef,
+            },
+        }
     );
+
+    my $key = $p{key};
 
     my $log = $self->log;
@@ -342,4 +351,11 @@
                 }
 
+                # else dir doesn't exist
+                unless ($p{create}) {
+                    # resolution failed
+                    $parent_id = undef;
+                    last;
+                }
+
                 {
                     # dir doesn't exist, create it
@@ -421,5 +437,5 @@
             my $query = $db->prepare_cached($sql->rename_object); 
             # this SQL statment takes the new key name as the first param
-            my $rows = $query->execute($newkey->path, basename($newkey->path), $self->_resolve_dir_parent_id($newkey), $key->path);
+            my $rows = $query->execute($newkey->path, basename($newkey->path), $self->_resolve_dir_parent_id(key => $newkey, create => 1), $key->path);
 
             # if we affected more then one row something very bad has happened.
@@ -513,5 +529,5 @@
               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, basename($key1->path), $self->_resolve_dir_parent_id($key1), $key2->path);
+              my $rows = $query->execute($key1->path, basename($key1->path), $self->_resolve_dir_parent_id(key => $key1, create => 1), $key2->path);
 
               # if we affected more then one row something very bad has happened.
@@ -526,5 +542,5 @@
               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, basename($key2->path), $self->_resolve_dir_parent_id($key2), $key1->path . ".swap");
+              my $rows = $query->execute($key2->path, basename($key2->path), $self->_resolve_dir_parent_id(key => $key2, create => 1), $key1->path . ".swap");
 
               # if we affected more then one row something very bad has happened.
@@ -1178,16 +1194,14 @@
     );
 
-    my $log = $self->log;
-    my $sql = $self->sql;
+    $pattern = parse_neb_key($pattern);
+
+    my $log = $self->log;
 
     $log->debug( "entered - @_" );
 
-    unless ($pattern) {
+    unless (defined $pattern) {
         $log->debug( "leaving" );
         $log->logdie("no keys found");
     }
-
-    # attempt to strip off neb:// if it exists
-    $pattern =~ s|^neb:||;
 
     my @keys = ();
@@ -1208,16 +1222,34 @@
 {
 
-    my $self = shift;
-    my $index = shift;
-    my $pattern = shift;
+    my $self    = shift;
+    my $index   = shift;
+    my $key     = shift;
 
     my $log = $self->log;
     my $sql = $self->sql;
     my $db  = $self->_db_for_index($index);
+
+    # first check to see if the key is an exact match
+    eval {
+        my $query = $db->prepare_cached( $sql->find_object_by_ext_id );
+        $query->execute( $key );
+        if ($query->rows) {
+            return [$query->fetchrow_hashref->{'ext_id'}];
+        }
+
+        my $parent_id = $self->_resolve_dir_parent_id(key => $key);
+
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    # else, assume it's a directory
 
     my @keys;
     eval {
-        my $query = $db->prepare_cached( $sql->find_objects );
-        $query->execute( $pattern );
+        my $query = $db->prepare_cached( $sql->find_object_by_ext_id );
+        $query->execute( $key );
 
         while ( my $row = $query->fetchrow_hashref ) {
@@ -1230,4 +1262,5 @@
     return \@keys;
 }
+
 
 sub find_instances
Index: /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/SQL.pm
===================================================================
--- /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 23771)
+++ /branches/neb_distrib_20081210/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 23772)
@@ -309,8 +309,8 @@
             USING(vol_id)
     },
-    find_objects => qq{
-        SELECT *
-        FROM storage_object
-        WHERE ext_id REGEXP ?
+    find_object_by_ext_id => qq{
+        SELECT ext_id, ext_id_basename
+        FROM storage_object
+        WHERE ext_id = ?
     },
     rename_object => qq{
