summaryrefslogtreecommitdiff
path: root/Mailman/database/dbcontext.py
diff options
context:
space:
mode:
authorbwarsaw2007-01-18 06:29:42 +0000
committerbwarsaw2007-01-18 06:29:42 +0000
commit372d4c2fdf072f6bfedca5fc84a2d5bb427418e6 (patch)
tree594db647158d8156f51ea6d05aba093f29ae061e /Mailman/database/dbcontext.py
parent1e63bc4a3b6d9197e66f57e11f4b6733a3b324dd (diff)
downloadmailman-372d4c2fdf072f6bfedca5fc84a2d5bb427418e6.tar.gz
mailman-372d4c2fdf072f6bfedca5fc84a2d5bb427418e6.tar.zst
mailman-372d4c2fdf072f6bfedca5fc84a2d5bb427418e6.zip
Rework MailList.available_languages so that we don't need to use a PickleType
column in the database for this list of strings. We use SQLAlchemy's many-to-many relationship, however because of this, you cannot simply append new unicodes to .available_languages. You need to wrap the language code in a Language instance and append that instance to the list. In order to handle this, I added a property MailList.language_codes which returns a list of the code strings (not Language instances). Also new are MailList.set_languages() for setting (i.e. overriding) the set of available languages for the list; and add_language() which takes a single language code, wraps it, and appends it. The code does not and should not use .available_languages directory any more. MailList.GetAvailableLanguages() is removed. The 'available_languages' column is removed from the Listdata table. Add a getValue() to Mailman.Gui.Language in order to unwrap the language codes stored in the database's association table. Modify _setValue() to do the wrapping. In dbcontext.py, don't import * from the sqlalchemy package. It contains a 'logging' name which is not the standard Python logging package. I also added essentially a bag of attributes class called Tables which will hold references to all the SA tables that are created. Update the make_table() API to take an instance of Tables. Added a close() method to DBContext. This is needed for the updated unit test suite. Changed bin/import.py so that when available_languages is being set, it calls MailList.set_languages() instead of trying to set that attribute directly. Updated some language idioms while I was at it. More eradication of mm_cfg in favor of the config object and the Defaults module. In testall.py, call initialize() instead of loginit.initialize(). Promote MAX_RESTARTS into a Defaults.py.in variable. This is because the unit tests will knock that value down to something not so annoying should one of the qrunner-required tests traceback. Several other important changes to the unit test suite (which now completely succeeds again!): - Set the uid and gid of the temporary mailman.cfg and tmp*.db files to the Mailman user and group as specified in the config object. - Make sure that all of the tests point to a SQLite database file that was created with the tempfile module. This way we don't pollute our main database with data that is getting created during the unit tests. - In the TestBase.setUp() method, be sure to close the existing dbcontext, clear out the mappers, and then reconnect the dbcontext with the new SQLALCHEMY_ENGINE_URL pointing to the tempfile. However, we don't need to reload the MailList instance any more. - Make all tests work, except for the tests that require crypt. That upgrade path will not be available in this version of Mailman.
Diffstat (limited to 'Mailman/database/dbcontext.py')
-rw-r--r--Mailman/database/dbcontext.py34
1 files changed, 21 insertions, 13 deletions
diff --git a/Mailman/database/dbcontext.py b/Mailman/database/dbcontext.py
index b2b1fb826..66c021447 100644
--- a/Mailman/database/dbcontext.py
+++ b/Mailman/database/dbcontext.py
@@ -16,15 +16,17 @@
# USA.
import os
+import logging
import weakref
-from sqlalchemy import *
+from sqlalchemy import BoundMetaData, create_session
from string import Template
from urlparse import urlparse
from Mailman import Version
from Mailman.configuration import config
from Mailman.database import address
+from Mailman.database import languages
from Mailman.database import listdata
from Mailman.database import version
from Mailman.database.txnsupport import txn
@@ -37,10 +39,17 @@ class MlistRef(weakref.ref):
self.fqdn_listname = mlist.fqdn_listname
+class Tables(object):
+ def bind(self, table, attrname=None):
+ if attrname is None:
+ attrname = table.name.lower()
+ setattr(self, attrname, table)
+
+
class DBContext(object):
def __init__(self):
- self.tables = {}
+ self.tables = Tables()
self.metadata = None
self.session = None
# Special transaction used only for MailList.Lock() .Save() and
@@ -69,21 +78,17 @@ class DBContext(object):
self.metadata = BoundMetaData(url)
self.metadata.engine.echo = config.SQLALCHEMY_ECHO
# Create all the table objects, and then let SA conditionally create
- # them if they don't yet exist.
- version_table = None
- for module in (address, listdata, version):
- table = module.make_table(self.metadata)
- self.tables[table.name] = table
- if module is version:
- version_table = table
+ # them if they don't yet exist. NOTE: this order matters!
+ for module in (languages, address, listdata, version):
+ module.make_table(self.metadata, self.tables)
self.metadata.create_all()
# Validate schema version, updating if necessary (XXX)
- from Mailman.interact import interact
- r = version_table.select(version_table.c.component=='schema').execute()
+ r = self.tables.version.select(
+ self.tables.version.c.component=='schema').execute()
row = r.fetchone()
if row is None:
# Database has not yet been initialized
- version_table.insert().execute(
+ self.tables.version.insert().execute(
component='schema',
version=Version.DATABASE_SCHEMA_VERSION)
elif row.version <> Version.DATABASE_SCHEMA_VERSION:
@@ -91,6 +96,9 @@ class DBContext(object):
raise SchemaVersionMismatchError(row.version)
self.session = create_session()
+ def close(self):
+ self.session.close()
+
def _touch(self, url):
parts = urlparse(url)
# XXX Python 2.5; use parts.scheme and parts.path
@@ -176,7 +184,7 @@ class DBContext(object):
@txn
def api_get_list_names(self):
- table = self.tables['Listdata']
+ table = self.tables.listdata
results = table.select().execute()
return [(row[table.c.list_name], row[table.c.host_name])
for row in results.fetchall()]