summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 05bc99f)
raw | patch | inline | side by side (parent: 05bc99f)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Fri, 5 Mar 2004 00:08:09 +0000 (00:08 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Fri, 5 Mar 2004 00:08:09 +0000 (00:08 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2143 57a73879-2fb5-44c3-a270-3262357dd7e2
diff --git a/CHANGES.txt b/CHANGES.txt
index 4348098f3ef4b54cbe6675dbd04c1402d5c8d4d4..4152d2f9b1d977ccba16b6cb0117713e836d8785 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
- all RDBMS backends now have indexes on several columns
- change nosymessage and send_message to accept msgid=None (RFE #707235).
- handle Resent-From: headers (sf bug 841151)
-- existing trackers (ie. live ones) may be used as templates for new
- trackers - the TEMPLATE-INFO.txt name entry has the tracker's dir name
- appended (so the demo tracker's template name is "classic-demo")
- always sort MultilinkHTMLProperty in the correct order, usually
alphabetically (sf feature 790512).
- added script for copying user(s) from tracker to tracker (sf patch
* form_parser.py - parsePropsFromForm & extractFormList in a FormParser class
-2004-??-?? 0.6.7
+2004-??-?? 0.6.8
+Fixed:
+- existing trackers (ie. live ones) may be used as templates for new
+ trackers - the TEMPLATE-INFO.txt name entry has the tracker's dir name
+ appended (so the demo tracker's template name is "classic-demo")
+
+
+2004-03-01 0.6.7
Fixed:
+- be more backward-compatible when asking for EMAIL_CHARSET
- made error on create consistent with edit when user enters invalid data
for Multilink and Link form fields (sf bug 904072)
- made errors from bad input in the quick "Show issue:" form more
index 8d8ea34af8fee75838dc0653f9365d0902db6740..c9ebfd69ad92f57e99dc17d2ec5ab8fb2a5c82b9 100644 (file)
self.sql("SET AUTOCOMMIT=0")
self.sql("BEGIN")
try:
- self.database_schema = self.load_dbschema()
+ self.load_dbschema()
except MySQLdb.OperationalError, message:
if message[0] != ER.NO_DB_ERROR:
raise
# http://www.mysql.com/doc/en/CREATE_TABLE.html
self.sql("CREATE TABLE ids (name varchar(255), num INT) TYPE=%s"%
self.mysql_backend)
- self.sql("CREATE INDEX ids_name_idx on ids(name)")
+ self.sql("CREATE INDEX ids_name_idx ON ids(name)")
+ self.create_version_2_tables()
+
+ def create_version_2_tables(self):
+ self.cursor.execute('CREATE TABLE otks (key VARCHAR(255), '
+ 'value VARCHAR(255), __time FLOAT(20))')
+ self.cursor.execute('CREATE INDEX otks_key_idx ON otks(key)')
+ self.cursor.execute('CREATE TABLE sessions (key VARCHAR(255), '
+ 'last_use FLOAT(20), user VARCHAR(255))')
+ self.cursor.execute('CREATE INDEX sessions_key_idx ON sessions(key)')
def __repr__(self):
return '<myroundsql 0x%x>'%id(self)
s = repr(self.database_schema)
self.sql('INSERT INTO schema VALUES (%s)', (s,))
- def load_dbschema(self):
- self.cursor.execute('SELECT schema FROM schema')
- schema = self.cursor.fetchone()
- if schema:
- return eval(schema[0])
- return None
-
def save_journal(self, classname, cols, nodeid, journaldate,
journaltag, action, params):
params = repr(params)
index 13f2e2f04c1c38c0a0eda7e55b380956772b05ce..147cb83f1b6960298f1bd58301ec0edcdc9fb83a 100644 (file)
self.cursor = self.conn.cursor()
try:
- self.database_schema = self.load_dbschema()
+ self.load_dbschema()
except:
self.rollback()
self.database_schema = {}
self.sql("CREATE TABLE schema (schema TEXT)")
self.sql("CREATE TABLE ids (name VARCHAR(255), num INT4)")
+ self.sql("CREATE INDEX ids_name_idx ON ids(name)")
+ self.create_version_2_tables()
+
+ def create_version_2_tables(self):
+ self.cursor.execute('CREATE TABLE otks (key VARCHAR(255), '
+ 'value VARCHAR(255), __time NUMERIC)')
+ self.cursor.execute('CREATE INDEX otks_key_idx ON otks(key)')
+ self.cursor.execute('CREATE TABLE sessions (key VARCHAR(255), '
+ 'last_use NUMERIC, user VARCHAR(255))')
+ self.cursor.execute('CREATE INDEX sessions_key_idx ON sessions(key)')
def __repr__(self):
return '<roundpsycopgsql 0x%x>' % id(self)
index c17235dc75bf2a720b5eaf96b9887c186b0696ff..6d28cea8d53d32bedc76ed5bc104ee9cb806bdd3 100644 (file)
-# $Id: back_sqlite.py,v 1.13 2004-02-11 23:55:09 richard Exp $
+# $Id: back_sqlite.py,v 1.14 2004-03-05 00:08:09 richard Exp $
'''Implements a backend for SQLite.
See https://pysqlite.sourceforge.net/ for pysqlite info
self.conn = sqlite.connect(db=db)
self.cursor = self.conn.cursor()
try:
- self.database_schema = self.load_dbschema()
+ self.load_dbschema()
except sqlite.DatabaseError, error:
if str(error) != 'no such table: schema':
raise
self.cursor.execute('create table schema (schema varchar)')
self.cursor.execute('create table ids (name varchar, num integer)')
self.cursor.execute('create index ids_name_idx on ids(name)')
+ self.create_version_2_tables()
+
+ def create_version_2_tables(self):
+ self.cursor.execute('create table otks (key varchar, '
+ 'value varchar, __time varchar)')
+ self.cursor.execute('create index otks_key_idx on otks(key)')
+ self.cursor.execute('create table sessions (key varchar, '
+ 'last_use varchar, user varchar)')
+ self.cursor.execute('create index sessions_key_idx on sessions(key)')
def sql_close(self):
''' Squash any error caused by us already having closed the
index e7d141c64c516dbfb1b49cb5c05b374140bdbf57..16392c68aba7f229095fb0044a34bb525f5a0c03 100644 (file)
-# $Id: rdbms_common.py,v 1.75 2004-02-11 23:55:09 richard Exp $
+# $Id: rdbms_common.py,v 1.76 2004-03-05 00:08:09 richard Exp $
''' Relational database (SQL) backend common code.
Basics:
probably a bit of work to be done if a database is used that actually
honors column typing, since the initial databases don't (sqlite stores
everything as a string.)
+
+The schema of the hyperdb being mapped to the database is stored in the
+database itself as a repr()'ed dictionary of information about each Class
+that maps to a table. If that information differs from the hyperdb schema,
+then we update it. We also store in the schema dict a __version__ which
+allows us to upgrade the database schema when necessary. See upgrade_db().
'''
__docformat__ = 'restructuredtext'
self.cache_lru = []
def sql_open_connection(self):
- ''' Open a connection to the database, creating it if necessary
+ ''' Open a connection to the database, creating it if necessary.
+
+ Must call self.load_dbschema()
'''
raise NotImplemented
'''
return re.sub("'", "''", str(value))
+ def load_dbschema(self):
+ ''' Load the schema definition that the database currently implements
+ '''
+ self.cursor.execute('select schema from schema')
+ self.database_schema = eval(self.cursor.fetchone()[0])
+
def save_dbschema(self, schema):
''' Save the schema definition that the database currently implements
'''
s = repr(self.database_schema)
self.sql('insert into schema values (%s)', (s,))
- def load_dbschema(self):
- ''' Load the schema definition that the database currently implements
- '''
- self.cursor.execute('select schema from schema')
- return eval(self.cursor.fetchone()[0])
-
def post_init(self):
''' Called once the schema initialisation has finished.
We should now confirm that the schema defined by our "classes"
attribute actually matches the schema in the database.
'''
+ self.upgrade_db()
+
# now detect changes in the schema
save = 0
for classname, spec in self.classes.items():
# commit
self.conn.commit()
+ # update this number when we need to make changes to the SQL structure
+ # of the backen database
+ current_db_version = 2
+ def upgrade_db(self):
+ ''' Update the SQL database to reflect changes in the backend code.
+ '''
+ version = self.database_schema.get('__version', 1)
+ if version == 1:
+ # version 1 doesn't have the OTK, session and indexing in the
+ # database
+ self.create_version_2_tables()
+
+ self.database_schema['__version'] = self.current_db_version
+
+
def refresh_database(self):
self.post_init()
diff --git a/roundup/rcsv.py b/roundup/rcsv.py
index 91a8125dc7a2482ee75871823307945ea470cef7..08798d028a0d05602c46af28e0c0193b453faebd 100644 (file)
--- a/roundup/rcsv.py
+++ b/roundup/rcsv.py
from roundup.i18n import _
from cStringIO import StringIO
-error = """Sorry, you need a module compatible with the csv module.
-Either upgrade your Python to 2.3 or later, or get and install
-the csv module from:
+error = """
+Sorry, you need a csv module. Either upgrade your Python to 2.3 or later,
+or get and install the csv module from:
http://www.object-craft.com.au/projects/csv/
-
-These two csv modules are different but Roundup can use either.
"""
try:
import csv
diff --git a/roundup/roundupdb.py b/roundup/roundupdb.py
index ddaf4dd2979b3ca4a3b0770a38213e600648a0d8..0a39ee3116f12d9cbf418ca7c45c3dbfdc1fc995 100644 (file)
--- a/roundup/roundupdb.py
+++ b/roundup/roundupdb.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: roundupdb.py,v 1.99 2004-02-29 00:35:55 richard Exp $
+# $Id: roundupdb.py,v 1.100 2004-03-05 00:08:09 richard Exp $
"""Extending hyperdb with types specific to issue-tracking.
"""
if address:
sendto.append(address)
recipients.append(userid)
-
+
def good_recipient(userid):
# Make sure we don't send mail to either the anonymous
# user or a user who has already seen the message.
return (userid and
(self.db.user.get(userid, 'username') != 'anonymous') and
not seen_message.has_key(userid))
-
+
# possibly send the message to the author, as long as they aren't
# anonymous
if (good_recipient(authid) and