Fixes trailing spaces handling
authorSofia Papagiannaki <papagian@gmail.com>
Tue, 25 Oct 2011 10:24:51 +0000 (13:24 +0300)
committerSofia Papagiannaki <papagian@gmail.com>
Tue, 25 Oct 2011 10:24:51 +0000 (13:24 +0300)
Fixes #1553

pithos/backends/lib/sqlalchemy/node.py
tools/store
tools/test

index a48d4de..ba42f1e 100644 (file)
 
 from time import time
 from sqlalchemy import Table, Integer, BigInteger, DECIMAL, Column, String, MetaData, ForeignKey
+from sqlalchemy.types import Text
 from sqlalchemy.schema import Index, Sequence
-from sqlalchemy.sql import func, and_, or_, null, select, bindparam
+from sqlalchemy.sql import func, and_, or_, null, select, bindparam, text
 from sqlalchemy.ext.compiler import compiles
+#from sqlalchemy.dialects.mysql import VARBINARY
+from sqlalchemy.engine.reflection import Inspector
 
 from dbworker import DBWorker
 
@@ -114,10 +117,12 @@ class Node(DBWorker):
                                          ondelete='CASCADE',
                                          onupdate='CASCADE'),
                               autoincrement=False))
-        columns.append(Column('path', String(2048), default='', nullable=False))
+        path_length = 2048
+        path_length_in_bytes = path_length * 4
+        columns.append(Column('path', Text(path_length_in_bytes), default='', nullable=False))
         self.nodes = Table('nodes', metadata, *columns, mysql_engine='InnoDB')
         # place an index on path
-        Index('idx_nodes_path', self.nodes.c.path)
+        #Index('idx_nodes_path', self.nodes.c.path)
         
         #create policy table
         columns=[]
@@ -174,6 +179,15 @@ class Node(DBWorker):
         
         metadata.create_all(self.engine)
         
+        # the following code creates an index of specific length
+        # this can be accompliced in sqlalchemy >= 0.7.3
+        # providing mysql_length option during index creation
+        insp = Inspector.from_engine(self.engine)
+        indexes = [elem['name'] for elem in insp.get_indexes('nodes')]
+        if 'idx_nodes_path' not in indexes:
+            s = text('CREATE INDEX idx_nodes_path ON nodes (path(%s))' %path_length_in_bytes)
+            self.conn.execute(s).close()
+        
         s = self.nodes.select().where(and_(self.nodes.c.node == ROOTNODE,
                                            self.nodes.c.parent == ROOTNODE))
         rp = self.conn.execute(s)
@@ -199,7 +213,7 @@ class Node(DBWorker):
            Return None if the path is not found.
         """
         
-        s = select([self.nodes.c.node], self.nodes.c.path == path)
+        s = select([self.nodes.c.node], self.nodes.c.path.like(path))
         r = self.conn.execute(s)
         row = r.fetchone()
         r.close()
index 9e3ab27..54288d6 100755 (executable)
@@ -747,7 +747,7 @@ def print_versions(data, f=stdout):
         return
     f.write('versions:\n')
     for id, t in data['versions']:
-        f.write('%s @ %s\n' % (str(id).rjust(30), datetime.fromtimestamp(t)))
+        f.write('%s @ %s\n' % (str(id).rjust(30), datetime.fromtimestamp(float(t))))
 
 def main():
     try:
index fa26fc6..dee45d1 100755 (executable)
@@ -629,15 +629,6 @@ class ContainerGet(BaseTestCase):
         self.assert_extended(objects, 'xml', 'object')
         node_name = objects.getElementsByTagName('name')[0]
         self.assertEqual(node_name.firstChild.data, '/objectname')
-        
-        #objects = self.client.list_objects('test', prefix='/')
-        #self.assertEqual(objects, ['/objectname'])
-        #
-        #objects = self.client.list_objects('test', path='/')
-        #self.assertEqual(objects, ['/objectname'])
-        #
-        #objects = self.client.list_objects('test', prefix='/', delimiter='n')
-        #self.assertEqual(objects, ['/object'])
 
     def test_list_objects_with_limit_marker(self):
         objects = self.client.list_objects(self.container[0], limit=2)
@@ -937,6 +928,25 @@ class ObjectGet(BaseTestCase):
                                         self.objects[0]['meta'])
         self.assertEqual(o, self.objects[0]['data'])
     
+    def test_objects_with_trailing_spaces(self):
+        self.client.create_container('test')
+        #create 'a' object
+        self.upload_random_data('test', 'a')
+        #look for 'a ' object
+        self.assert_raises_fault(404, self.client.retrieve_object,
+                                 'test', 'a ')
+        
+        #delete 'a' object
+        self.client.delete_object('test', 'a')
+        self.assert_raises_fault(404, self.client.retrieve_object,
+                                 'test', 'a')
+        
+        #create 'a ' object
+        self.upload_random_data('test', 'a ')
+        #look for 'a' object
+        self.assert_raises_fault(404, self.client.retrieve_object,
+                                 'test', 'a')
+    
     def test_get_invalid(self):
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  self.containers[0], self.objects[0]['name'])