summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4fa1ad2)
raw | patch | inline | side by side (parent: 4fa1ad2)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 16 Sep 2002 08:04:46 +0000 (08:04 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 16 Sep 2002 08:04:46 +0000 (08:04 +0000) |
(though only one at a time at present)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1180 57a73879-2fb5-44c3-a270-3262357dd7e2
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1180 57a73879-2fb5-44c3-a270-3262357dd7e2
diff --git a/CHANGES.txt b/CHANGES.txt
index adbc1e27508bd883e75acb7d10dedf0ac7f7990a..d177817176134df3ac0dcdefce2a7343c7b077c8 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
. handling of journal values in export/import
. password edit now has a confirmation field
. registration error punts back to register page
+ . gadfly backend now handles changes to the schema - but only one property
+ at a time
2002-09-13 0.5.0 beta2
diff --git a/TODO.txt b/TODO.txt
index 2a6865cfe5f1463274fbeaf58c07a97e4e769fa7..6122bfee1cf35885083dfa864089102aad7bfda0 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
bug web request.url is incorrect in cgi-bin environments
bug web do something about file.newitem
+bug mailgw some f*ked mailers QUOTE their Re; "Re: "[issue1] bla blah""
+bug docs need to mention somewhere how sorting works
======= ========= =============================================================
diff --git a/doc/customizing.txt b/doc/customizing.txt
index 34015c204a39306327856837f609353e6562aa1e..ae9bfc47446d8ef6bb5b16e8e6e1e2229c580022 100644 (file)
--- a/doc/customizing.txt
+++ b/doc/customizing.txt
Customising Roundup
===================
-:Version: $Revision: 1.41 $
+:Version: $Revision: 1.42 $
.. This document borrows from the ZopeBook section on ZPT. The original is at:
http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
<input type="hidden" name=":action" value="page1submit">
<strong>Category:</strong>
- <span tal:replace="structure context/category/menu" />
+ <tal:block tal:replace="structure context/category/menu" />
<input type="submit" value="Continue">
</form>
index 225f341a5c6365037ab8a78805cb4a186d7f1105..d9a108181169bd0978d403933bf6e00bd2527a68 100644 (file)
-# $Id: back_gadfly.py,v 1.20 2002-09-15 23:06:20 richard Exp $
+# $Id: back_gadfly.py,v 1.21 2002-09-16 08:04:46 richard Exp $
__doc__ = '''
About Gadfly
============
klass.index(nodeid)
self.indexer.save_index()
- def determine_columns(self, spec):
+ def determine_columns(self, properties):
''' Figure the column names and multilink properties from the spec
+
+ "properties" is a list of (name, prop) where prop may be an
+ instance of a hyperdb "type" _or_ a string repr of that type.
'''
cols = []
mls = []
# add the multilinks separately
- for col, prop in spec.properties.items():
+ for col, prop in properties:
if isinstance(prop, Multilink):
mls.append(col)
+ elif isinstance(prop, type('')) and prop.find('Multilink') != -1:
+ mls.append(col)
else:
cols.append('_'+col)
cols.sort()
def update_class(self, spec, dbspec):
''' Determine the differences between the current spec and the
database version of the spec, and update where necessary
-
- NOTE that this doesn't work for adding/deleting properties!
- ... until gadfly grows an ALTER TABLE command, it's not going to!
'''
spec_schema = spec.schema()
if spec_schema == dbspec:
# now compare
for propname in spec_propnames:
prop = spec_props[propname]
- if __debug__:
- print >>hyperdb.DEBUG, 'update_class ...', `prop`
if dbspec_props.has_key(propname) and prop==dbspec_props[propname]:
continue
if __debug__:
- print >>hyperdb.DEBUG, 'update_class', `prop`
+ print >>hyperdb.DEBUG, 'update_class ADD', (propname, prop)
if not dbspec_props.has_key(propname):
# add the property
if isinstance(prop, Multilink):
- sql = 'create table %s_%s (linkid varchar, nodeid '\
- 'varchar)'%(spec.classname, prop)
- if __debug__:
- print >>hyperdb.DEBUG, 'update_class', (self, sql)
- cursor.execute(sql)
- else:
- # XXX gadfly doesn't have an ALTER TABLE command
- raise NotImplementedError
- sql = 'alter table _%s add column (_%s varchar)'%(
- spec.classname, propname)
- if __debug__:
- print >>hyperdb.DEBUG, 'update_class', (self, sql)
- cursor.execute(sql)
+ # all we have to do here is create a new table, easy!
+ self.create_multilink_table(cursor, spec, propname)
+ continue
+
+ # no ALTER TABLE, so we:
+ # 1. pull out the data, including an extra None column
+ oldcols, x = self.determine_columns(dbspec[1])
+ oldcols.append('id')
+ oldcols.append('__retired__')
+ cn = spec.classname
+ sql = 'select %s,? from _%s'%(','.join(oldcols), cn)
+ if __debug__:
+ print >>hyperdb.DEBUG, 'update_class', (self, sql, None)
+ cursor.execute(sql, (None,))
+ olddata = cursor.fetchall()
+
+ # 2. drop the old table
+ cursor.execute('drop table _%s'%cn)
+
+ # 3. create the new table
+ cols, mls = self.create_class_table(cursor, spec)
+ # ensure the new column is last
+ cols.remove('_'+propname)
+ assert oldcols == cols, "Column lists don't match!"
+ cols.append('_'+propname)
+
+ # 4. populate with the data from step one
+ s = ','.join(['?' for x in cols])
+ scols = ','.join(cols)
+ sql = 'insert into _%s (%s) values (%s)'%(cn, scols, s)
+
+ # GAH, nothing had better go wrong from here on in... but
+ # we have to commit the drop...
+ self.conn.commit()
+
+ # we're safe to insert now
+ if __debug__:
+ print >>hyperdb.DEBUG, 'update_class', (self, sql, olddata)
+ cursor.execute(sql, olddata)
+
else:
# modify the property
if __debug__:
if spec_props.has_key(propname):
continue
if __debug__:
- print >>hyperdb.DEBUG, 'update_class', `prop`
+ print >>hyperdb.DEBUG, 'update_class REMOVE', `prop`
# delete the property
if isinstance(prop, Multilink):
print >>hyperdb.DEBUG, 'update_class', (self, sql)
cursor.execute(sql)
else:
- # XXX gadfly doesn't have an ALTER TABLE command
- raise NotImplementedError
- sql = 'alter table _%s delete column _%s'%(spec.classname,
- propname)
- if __debug__:
- print >>hyperdb.DEBUG, 'update_class', (self, sql)
- cursor.execute(sql)
-
- def create_class(self, spec):
- ''' Create a database table according to the given spec.
- '''
- cols, mls = self.determine_columns(spec)
+ # no ALTER TABLE, so we:
+ # 1. pull out the data, excluding the removed column
+ oldcols, x = self.determine_columns(spec.properties.items())
+ oldcols.append('id')
+ oldcols.append('__retired__')
+ # remove the missing column
+ oldcols.remove('_'+propname)
+ cn = spec.classname
+ sql = 'select %s from _%s'%(','.join(oldcols), cn)
+ cursor.execute(sql, (None,))
+ olddata = sql.fetchall()
+
+ # 2. drop the old table
+ cursor.execute('drop table _%s'%cn)
+
+ # 3. create the new table
+ cols, mls = self.create_class_table(self, cursor, spec)
+ assert oldcols != cols, "Column lists don't match!"
+
+ # 4. populate with the data from step one
+ qs = ','.join(['?' for x in cols])
+ sql = 'insert into _%s values (%s)'%(cn, s)
+ cursor.execute(sql, olddata)
+
+ def create_class_table(self, cursor, spec):
+ ''' create the class table for the given spec
+ '''
+ cols, mls = self.determine_columns(spec.properties.items())
# add on our special columns
cols.append('id')
cols.append('__retired__')
- cursor = self.conn.cursor()
-
# create the base table
- cols = ','.join(['%s varchar'%x for x in cols])
- sql = 'create table _%s (%s)'%(spec.classname, cols)
+ scols = ','.join(['%s varchar'%x for x in cols])
+ sql = 'create table _%s (%s)'%(spec.classname, scols)
if __debug__:
print >>hyperdb.DEBUG, 'create_class', (self, sql)
cursor.execute(sql)
+ return cols, mls
+
+ def create_journal_table(self, cursor, spec):
+ ''' create the journal table for a class given the spec and
+ already-determined cols
+ '''
# journal table
cols = ','.join(['%s varchar'%x
for x in 'nodeid date tag action params'.split()])
print >>hyperdb.DEBUG, 'create_class', (self, sql)
cursor.execute(sql)
+ def create_multilink_table(self, cursor, spec, ml):
+ ''' Create a multilink table for the "ml" property of the class
+ given by the spec
+ '''
+ sql = 'create table %s_%s (linkid varchar, nodeid varchar)'%(
+ spec.classname, ml)
+ if __debug__:
+ print >>hyperdb.DEBUG, 'create_class', (self, sql)
+ cursor.execute(sql)
+
+ def create_class(self, spec):
+ ''' Create a database table according to the given spec.
+ '''
+ cursor = self.conn.cursor()
+ cols, mls = self.create_class_table(cursor, spec)
+ self.create_journal_table(cursor, spec)
+
# now create the multilink tables
for ml in mls:
- sql = 'create table %s_%s (linkid varchar, nodeid varchar)'%(
- spec.classname, ml)
- if __debug__:
- print >>hyperdb.DEBUG, 'create_class', (self, sql)
- cursor.execute(sql)
+ self.create_multilink_table(cursor, spec, ml)
# ID counter
sql = 'insert into ids (name, num) values (?,?)'
print >>hyperdb.DEBUG, 'addnode', (self, classname, nodeid, node)
# gadfly requires values for all non-multilink columns
cl = self.classes[classname]
- cols, mls = self.determine_columns(cl)
+ cols, mls = self.determine_columns(cl.properties.items())
# default the non-multilink columns
for col, prop in cl.properties.items():
print >>hyperdb.DEBUG, 'getnode', (self, classname, nodeid)
# figure the columns we're fetching
cl = self.classes[classname]
- cols, mls = self.determine_columns(cl)
+ cols, mls = self.determine_columns(cl.properties.items())
scols = ','.join(cols)
# perform the basic property fetch
diff --git a/test/test_db.py b/test/test_db.py
index ed5d718e9b201b11f31ad589c0562c912a90f667..6790db937feba6111c70cde901f4a43b9ce421b3 100644 (file)
--- a/test/test_db.py
+++ b/test/test_db.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_db.py,v 1.46 2002-09-13 08:20:13 richard Exp $
+# $Id: test_db.py,v 1.47 2002-09-16 08:04:46 richard Exp $
import unittest, os, shutil, time
id2 = self.db.issue.create(title="eggs", status='2')
self.assertNotEqual(id1, id2)
- def testNewProperty(self):
- # gadfly doesn't have an ALTER TABLE command :(
- pass
-
class gadflyReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
def setUp(self):
from roundup.backends import gadfly