Code

relaxed CVS importing (sf feature 693277)
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 6 Mar 2003 07:33:29 +0000 (07:33 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 6 Mar 2003 07:33:29 +0000 (07:33 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1573 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
roundup/admin.py
roundup/backends/back_anydbm.py
roundup/backends/back_metakit.py
roundup/backends/rdbms_common.py

index c4c3d4a85a1d6046650839ffbb9375f33a0521d8..6dd8699c0fa68ea3774aa9cb0a86459e765b6ee7 100644 (file)
@@ -40,6 +40,7 @@ Feature:
   file serving
 - added Node.get() method
 - nicer page titles (sf feature 65197)
+- relaxed CVS importing (sf feature 693277)
 
 
 Fixed:
index f96ccb937ccdceddf2470b040b06d97b5fed88a6..1f2e4d00b5afe4932e905b4979e25b0246ce1c92 100644 (file)
@@ -16,7 +16,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: admin.py,v 1.41 2003-03-06 06:06:49 richard Exp $
+# $Id: admin.py,v 1.42 2003-03-06 07:33:29 richard Exp $
 
 '''Administration commands for maintaining Roundup trackers.
 '''
@@ -921,7 +921,9 @@ Command help:
             properties = cl.getprops()
             propnames = properties.keys()
             propnames.sort()
-            print >> f, p.join(propnames)
+            l = propnames[:]
+            l.append('is retired')
+            print >> f, p.join(l)
 
             # all nodes for this class (not using list() 'cos it doesn't
             # include retired nodes)
@@ -965,14 +967,16 @@ Command help:
             cl = self.get_class(classname)
             p = csv.parser(field_sep=':')
             file_props = p.parse(f.readline())
-            properties = cl.getprops()
-            propnames = properties.keys()
-            propnames.sort()
-            m = file_props[:]
-            m.sort()
-            if m != propnames:
-                raise UsageError, _('Import file doesn\'t define the same '
-                    'properties as "%(arg0)s".')%{'arg0': args[0]}
+
+# XXX we don't _really_ need to do this...
+#            properties = cl.getprops()
+#            propnames = properties.keys()
+#            propnames.sort()
+#            m = file_props[:]
+#            m.sort()
+#            if m != propnames:
+#                raise UsageError, _('Import file doesn\'t define the same '
+#                    'properties as "%(arg0)s".')%{'arg0': args[0]}
 
             # loop through the file and create a node for each entry
             maxid = 1
@@ -989,7 +993,7 @@ Command help:
                         raise ValueError, "Unexpected EOF during CSV parse"
 
                 # do the import and figure the current highest nodeid
-                maxid = max(maxid, int(cl.import_list(propnames, l)))
+                maxid = max(maxid, int(cl.import_list(file_props, l)))
 
             print 'setting', classname, maxid+1
             self.db.setid(classname, str(maxid+1))
index df10104c4df459b96aaa39f062af060b75a81aab..3297e2f52f885187003b8b7463e5cc3ce16c7f90 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_anydbm.py,v 1.108 2003-03-03 21:05:17 richard Exp $
+#$Id: back_anydbm.py,v 1.109 2003-03-06 07:33:29 richard Exp $
 '''
 This module defines a backend that saves the hyperdatabase in a database
 chosen by anydbm. It is guaranteed to always be available in python
@@ -920,22 +920,29 @@ class Class(hyperdb.Class):
 
         # make the new node's property map
         d = {}
+        newid = None
         for i in range(len(propnames)):
-            # Use eval to reverse the repr() used to output the CSV
-            value = eval(proplist[i])
-
             # Figure the property for this column
             propname = propnames[i]
-            prop = properties[propname]
+
+            # Use eval to reverse the repr() used to output the CSV
+            value = eval(proplist[i])
 
             # "unmarshal" where necessary
             if propname == 'id':
                 newid = value
                 continue
+            elif propname == 'is retired':
+                # is the item retired?
+                if int(value):
+                    d[self.db.RETIRED_FLAG] = 1
+                continue
             elif value is None:
                 # don't set Nones
                 continue
-            elif isinstance(prop, hyperdb.Date):
+
+            prop = properties[propname]
+            if isinstance(prop, hyperdb.Date):
                 value = date.Date(value)
             elif isinstance(prop, hyperdb.Interval):
                 value = date.Interval(value)
@@ -945,9 +952,9 @@ class Class(hyperdb.Class):
                 value = pwd
             d[propname] = value
 
-        # check retired flag
-        if int(proplist[-1]):
-            d[self.db.RETIRED_FLAG] = 1
+        # get a new id if necessary
+        if newid is None:
+            newid = self.db.newid(self.classname)
 
         # add the node and journal
         self.db.addnode(self.classname, newid, d)
index fd88d21df44dcdaf6de67fcb566a3e9265a8f327..d8adbee4198c346131b50994d5a26224c339c28b 100755 (executable)
@@ -1106,11 +1106,18 @@ class Class:
             value = eval(proplist[i])
             if not value:
                 continue
+
             propname = propnames[i]
-            prop = properties[propname]
             if propname == 'id':
                 newid = value = int(value)
-            elif isinstance(prop, hyperdb.Date):
+            elif propname == 'is retired':
+                # is the item retired?
+                if int(value):
+                    d['_isdel'] = 1
+                continue
+
+            prop = properties[propname]
+            if isinstance(prop, hyperdb.Date):
                 value = int(calendar.timegm(value))
             elif isinstance(prop, hyperdb.Interval):
                 value = str(date.Interval(value))
@@ -1124,16 +1131,23 @@ class Class:
                 # we handle multilinks separately
                 continue
             d[propname] = value
-        # is the item retired?
-        if int(proplist[-1]):
-            d['_isdel'] = 1
+
+        # possibly make a new node
+        if not d.has_key('id'):
+            d['id'] = newid = self.maxid
+            self.maxid += 1
+
+        # save off the node
         view.append(d)
 
+        # fix up multilinks
         ndx = view.find(id=newid)
         row = view[ndx]
         for i in range(len(propnames)):
             value = eval(proplist[i])
             propname = propnames[i]
+            if propname == 'is retired':
+                continue
             prop = properties[propname]
             if not isinstance(prop, hyperdb.Multilink):
                 continue
index 7388dbcb88d6807e35712e3ef049e3b441d04b9e..6d0fc1e7acb21090a0828ef9d4541cc4ad958b69 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: rdbms_common.py,v 1.39 2003-03-06 06:03:51 richard Exp $
+# $Id: rdbms_common.py,v 1.40 2003-03-06 07:33:29 richard Exp $
 ''' Relational database (SQL) backend common code.
 
 Basics:
@@ -450,8 +450,10 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database):
 
         # default the non-multilink columns
         for col, prop in cl.properties.items():
-            if not isinstance(col, Multilink):
-                if not node.has_key(col):
+            if not node.has_key(col):
+                if isinstance(prop, Multilink):
+                    node[col] = []
+                else:
                     node[col] = None
 
         # clear this node out of the cache if it's in there
@@ -1100,19 +1102,27 @@ class Class(hyperdb.Class):
 
         # make the new node's property map
         d = {}
+        retire = 0
+        newid = None
         for i in range(len(propnames)):
             # Use eval to reverse the repr() used to output the CSV
             value = eval(proplist[i])
 
             # Figure the property for this column
             propname = propnames[i]
-            prop = properties[propname]
 
             # "unmarshal" where necessary
             if propname == 'id':
                 newid = value
                 continue
-            elif value is None:
+            elif propname == 'is retired':
+                # is the item retired?
+                if int(value):
+                    retire = 1
+                continue
+
+            prop = properties[propname]
+            if value is None:
                 # don't set Nones
                 continue
             elif isinstance(prop, hyperdb.Date):
@@ -1125,8 +1135,12 @@ class Class(hyperdb.Class):
                 value = pwd
             d[propname] = value
 
+        # get a new id if necessary
+        if newid is None:
+            newid = self.db.newid(self.classname)
+
         # retire?
-        if int(proplist[-1]):
+        if retire:
             # use the arg for __retired__ to cope with any odd database type
             # conversion (hello, sqlite)
             sql = 'update _%s set __retired__=%s where id=%s'%(self.classname,