Code

Fix some tests.
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 24 Mar 2004 04:57:25 +0000 (04:57 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 24 Mar 2004 04:57:25 +0000 (04:57 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2170 57a73879-2fb5-44c3-a270-3262357dd7e2

doc/upgrading.txt
roundup/backends/rdbms_common.py
roundup/date.py
test/db_test_base.py
test/test_actions.py

index b53a457e08760c879c12b1511cb8ea6c87581d35..33b381cdc2be98601c1b8cfd06eafd75ca24723e 100644 (file)
@@ -11,6 +11,17 @@ accordingly. Note that there is information about upgrade procedures in the
 Migrating from 0.6 to 0.7
 =========================
 
+0.7.0 Typed columns in MySQL backend
+------------------------------------
+
+The MySQL (and Postgresql for that matter) backend now creates tables with
+appropriate column datatypes (not just varchar).
+
+Your database will be automatically migrated to use the new schemas, but
+it will take time. It's probably a good idea to make sure you do this as
+part of the upgrade when users are not expected to be using the system.
+
+
 0.7.0 Permission setup
 ----------------------
 
@@ -51,6 +62,7 @@ add::
         p = db.security.getPermission('View', cl)
         db.security.addPermissionToRole('User', p)
 
+
 0.7.0 New "actor" property
 --------------------------
 
@@ -58,6 +70,8 @@ Roundup's database has a new per-item property "actor" which reflects the
 user performing the last "actvitiy". See the classic template for ways to
 integrate this new property into your interface.
 
+The property will be automatically added to your existing database.
+
 
 0.7.0 Extending the cgi interface
 ---------------------------------
index 07b0257591d9164a5d974315b1c2348847c62d0c..435b99ce55301532d2050a31f5945219d336a3e3 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: rdbms_common.py,v 1.85 2004-03-24 03:07:52 richard Exp $
+# $Id: rdbms_common.py,v 1.86 2004-03-24 04:57:25 richard Exp $
 ''' Relational database (SQL) backend common code.
 
 Basics:
@@ -607,7 +607,7 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database):
 
     hyperdb_to_sql_value = {
         hyperdb.String : str,
-        hyperdb.Date   : lambda x: x.formal(sep=' ', sec='%f'),
+        hyperdb.Date   : lambda x: x.formal(sep=' ', sec='%.3f'),
         hyperdb.Link   : int,
         hyperdb.Interval  : lambda x: x.serialise(),
         hyperdb.Password  : str,
index 6b9a807e40f792ad3233a496efd225c3c8f444e8..a8d6ef3b09817ea0963c0663e806a09eb0dfa5f5 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: date.py,v 1.62 2004-03-24 03:07:51 richard Exp $
+# $Id: date.py,v 1.63 2004-03-24 04:57:25 richard Exp $
 
 """Date, time and time interval handling.
 """
@@ -300,16 +300,20 @@ class Date:
         d = diff/(24*60*60)
         return Interval((0, 0, d, H, M, S), sign=sign)
 
-    def __cmp__(self, other):
+    def __cmp__(self, other, int_seconds=0):
         """Compare this date to another date."""
         if other is None:
             return 1
-        for attr in ('year', 'month', 'day', 'hour', 'minute', 'second'):
+        for attr in ('year', 'month', 'day', 'hour', 'minute'):
             if not hasattr(other, attr):
                 return 1
             r = cmp(getattr(self, attr), getattr(other, attr))
             if r: return r
-        return 0
+        if not hasattr(other, 'second'):
+            return 1
+        if int_seconds:
+            return cmp(int(self.second), int(other.second))
+        return cmp(self.second, other.second)
 
     def __str__(self):
         """Return this date as a string in the yyyy-mm-dd.hh:mm:ss format."""
@@ -334,7 +338,7 @@ class Date:
         return str
 
     def __repr__(self):
-        return '<Date %s>'%self.__str__()
+        return '<Date %s>'%self.formal(sec='%f')
 
     def local(self, offset):
         """ Return this date as yyyy-mm-dd.hh:mm:ss in a local time zone.
index 3acc05b7b555088960014bff6e9161b6d1b47c9f..14a9e38e4514a003675967123bb0f58e26033482 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: db_test_base.py,v 1.19 2004-03-22 07:45:40 richard Exp $ 
+# $Id: db_test_base.py,v 1.20 2004-03-24 04:57:25 richard Exp $ 
 
 import unittest, os, shutil, errno, imp, sys, time, pprint
 
@@ -939,6 +939,7 @@ class DBTest(MyTestCase):
         # compare with snapshot of the database
         for cn, items in orig.items():
             klass = self.db.classes[cn]
+            propdefs = klass.getprops(1)
             # ensure retired items are retired :)
             l = items.keys(); l.sort()
             m = klass.list(); m.sort()
@@ -949,7 +950,13 @@ class DBTest(MyTestCase):
                     if isinstance(value, type([])):
                         value.sort()
                         l.sort()
-                    ae(l, value)
+                    try:
+                        ae(l, value)
+                    except AssertionError:
+                        if not isinstance(propdefs[name], Date):
+                            raise
+                        # don't get hung up on rounding errors
+                        assert not l.__cmp__(value, int_seconds=1)
 
         # make sure the retired items are actually imported
         ae(self.db.user.get('4', 'username'), 'blop')
index 2e33429e15b4b99aced31d8bc0b4bae8a619eb75..2a0c2f83fa0daf9fda7b73631e0562556103b98e 100755 (executable)
@@ -158,6 +158,8 @@ class CollisionDetectionTestCase(ActionTestCase):
         ActionTestCase.setUp(self)\r
         self.action = EditItemAction(self.client)\r
         self.now = Date('.')\r
+        # round off for testing\r
+        self.now.seconds = int(self.now.seconds)\r
 \r
     def testLastUserActivity(self):\r
         self.assertEqual(self.action.lastUserActivity(), None)\r