Index: trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm
===================================================================
--- trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 23699)
+++ trunk/Nebulous-Server/lib/Nebulous/Server/SQL.pm	(revision 23932)
@@ -8,5 +8,5 @@
 use warnings FATAL => qw( all );
 
-our $VERSION = '0.02';
+our $VERSION = '0.04';
 
 use base qw( Class::Accessor::Fast );
@@ -26,6 +26,6 @@
     new_object          => qq{
         INSERT INTO storage_object
-        (so_id, ext_id, type)
-        VALUES (?, ?, 'REG_FILE')
+        (so_id, ext_id, ext_id_basename, type, dir_id)
+        VALUES (?, ?, ?, 'REG_FILE', ?)
     },
     new_object_attr  => qq{
@@ -60,4 +60,16 @@
         USING (so_id)
         WHERE ext_id = ?
+    },
+    get_directory       => qq{
+        SELECT
+            dir_id
+        FROM directory
+        WHERE parent_id = ?
+            AND dirname = ?
+    },
+    new_directory       => qq{
+        INSERT INTO directory
+        (dirname, parent_id)
+        VALUES (?, ?)
     },
     check_object_name => qq{
@@ -297,12 +309,17 @@
             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 = ?
+    },
+    find_object_by_dir_id => qq{
+        SELECT ext_id, ext_id_basename
+        FROM storage_object
+        WHERE dir_id = ?
     },
     rename_object => qq{
         UPDATE storage_object
-        SET ext_id = ?
+        SET ext_id = ?, ext_id_basename = ?, dir_id = ?
         WHERE ext_id = ?
     },
@@ -330,4 +347,27 @@
         GROUP BY so_id
         HAVING available_instances < instances OR instances < copies
+    },
+    find_objects_with_extra_instances_by_xattr => qq{
+        SELECT
+            so.so_id,
+            so.ext_id,
+            count(ins_id) as instances,
+            mv.name as volume_name,
+            mv.host as volume_host,
+            count(mv.vol_id) as available_instances,
+            xattr.value as copies
+        FROM storage_object AS so
+        JOIN storage_object_xattr as xattr
+            ON so.so_id = xattr.so_id
+            AND xattr.name = 'user.copies'
+        JOIN instance AS i
+            ON so.so_id = i.so_id
+        JOIN mountedvol AS mv
+            USING(vol_id)
+        WHERE
+            mv.available = 1
+        GROUP BY so_id
+        HAVING available_instances > copies
+        limit 5;
     },
     find_objects_with_extra_instances => qq{
@@ -387,4 +427,5 @@
 DROP TABLE IF EXISTS log;
 DROP TABLE IF EXISTS mountedvol;
+DROP TABLE IF EXISTS directory;
 DROP PROCEDURE IF EXISTS getmountedvol;
 SET FOREIGN_KEY_CHECKS=1
@@ -408,7 +449,25 @@
 
 __DATA__
+CREATE TABLE directory (
+    dir_id BIGINT NOT NULL AUTO_INCREMENT,
+    dirname CHAR(255) NOT NULL,
+    parent_id BIGINT NOT NULL,
+    FOREIGN KEY(parent_id) REFERENCES directory(dir_id),
+    PRIMARY KEY(dir_id),
+    KEY(parent_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+###
+
+INSERT INTO directory (dir_id, dirname, parent_id) VALUES (1, '/', 1);
+
+###
+
 CREATE TABLE storage_object (
     so_id BIGINT NOT NULL AUTO_INCREMENT,
     ext_id VARCHAR(255) NOT NULL UNIQUE,
+    ext_id_basename VARCHAR(255) NOT NULL,
+    dir_id BIGINT NOT NULL,
+    FOREIGN KEY(dir_id) REFERENCES directory(dir_id),
     type enum('REG_FILE'),
     PRIMARY KEY(so_id),
