Index: trunk/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 13071)
+++ trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 13087)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.26 2007-04-28 00:44:38 jhoblitt Exp $
+# $Id: Server.pm,v 1.27 2007-05-01 02:00:07 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -614,4 +614,207 @@
 
 
+sub setxattr_object
+{
+    my $self = shift;
+
+    my ($key, $name, $value, $flags) = validate_pos(@_,
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => SCALAR,
+            callbacks   => {
+                'is read or write' => sub { $_[0] =~ /^(?:create|replace)$/i },
+            },
+        },
+    );
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    $log->debug("entered - @_");
+
+    eval {
+        my $query;
+
+        if ($flags eq 'create') {
+            $query = $db->prepare_cached( $sql->new_object_xattr );
+        } else {
+            # replace
+            $query = $db->prepare_cached( $sql->replace_object_xattr );
+        }
+
+        # name, value, ext_id
+        my $rows = $query->execute($name, $value, $key);
+
+        # if we affected more then one row something very bad has happened.
+        if ($flags eq 'create') {
+            unless ($rows == 1) {
+                $log->logdie( "affected row count is $rows instead of 1" );
+            }
+        } else {
+            unless ($rows == 2) {
+                $log->logdie( "affected row count is $rows instead of 2" );
+            }
+        }
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    eval { 
+        $db->commit;
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    $log->debug("leaving");
+
+    return 1;
+}
+
+
+sub getxattr_object
+{
+    my $self = shift;
+
+    my ($key, $name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => SCALAR,
+        },
+    );
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    $log->debug("entered - @_");
+
+    my $query;
+    eval {
+        $query = $db->prepare_cached( $sql->get_object_xattr );
+        # ext_id, name
+        my $rows = $query->execute($key, $name);
+
+        # if we affected more then one row something very bad has happened.
+        unless ($rows == 1) {
+            $log->logdie( "affected row count is $rows instead of 1" );
+        }
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    my $row = $query->fetchrow_hashref;
+    my $value = $row->{ 'value' };
+    $query->finish;
+
+    $log->debug("leaving");
+
+    return $value;
+}
+
+
+sub listxattr_object
+{
+    my $self = shift;
+
+    my ($key) = validate_pos(@_,
+        {
+            type        => SCALAR,
+        },
+    );
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    $log->debug("entered - @_");
+
+    my $query;
+    eval {
+        $query = $db->prepare_cached( $sql->list_object_xattr );
+        # ext_id
+        my $rows = $query->execute($key);
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    my @xattrs;
+    while (my $row = $query->fetchrow_hashref) {
+        push @xattrs, $row->{ 'name' };
+    }
+
+    $log->debug("leaving");
+
+    return @xattrs;
+}
+
+
+sub removexattr_object
+{
+    my $self = shift;
+
+    my ($key, $name) = validate_pos(@_,
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => SCALAR,
+        },
+    );
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    $log->debug("entered - @_");
+
+    my $query;
+    eval {
+        $query = $db->prepare_cached( $sql->remove_object_xattr );
+        # ext_id, name
+        my $rows = $query->execute($key, $name);
+
+        # if we affected more then one row something very bad has happened.
+        unless ($rows == 1) {
+            $log->logdie( "affected row count is $rows instead of 1" );
+        }
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    eval { 
+        $db->commit;
+    };
+    if ($@) {
+        $db->rollback;
+        $log->logdie("database error: $@");
+    }
+
+    $log->debug("leaving");
+
+    return 1;
+}
+
+
 sub find_objects {
     my $self = shift;
