summaryrefslogtreecommitdiff
path: root/src/mailman/database/types.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/database/types.py')
-rw-r--r--src/mailman/database/types.py69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/mailman/database/types.py b/src/mailman/database/types.py
index ba3d92df4..1984b08b5 100644
--- a/src/mailman/database/types.py
+++ b/src/mailman/database/types.py
@@ -23,43 +23,70 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Enum',
+ 'UUID',
]
+import uuid
-from storm.properties import SimpleProperty
-from storm.variables import Variable
+from sqlalchemy import Integer
+from sqlalchemy.dialects import postgresql
+from sqlalchemy.types import TypeDecorator, CHAR
-class _EnumVariable(Variable):
- """Storm variable for supporting enum types.
+class Enum(TypeDecorator):
+ """Handle Python 3.4 style enums.
- To use this, make the database column a INTEGER.
+ Stores an integer-based Enum as an integer in the database, and
+ converts it on-the-fly.
"""
+ impl = Integer
- def __init__(self, *args, **kws):
- self._enum = kws.pop('enum')
- super(_EnumVariable, self).__init__(*args, **kws)
+ def __init__(self, enum, *args, **kw):
+ self.enum = enum
+ super(Enum, self).__init__(*args, **kw)
- def parse_set(self, value, from_db):
+ def process_bind_param(self, value, dialect):
if value is None:
return None
- if not from_db:
- return value
- return self._enum(value)
+ return value.value
- def parse_get(self, value, to_db):
+ def process_result_value(self, value, dialect):
if value is None:
return None
- if not to_db:
- return value
- return value.value
+ return self.enum(value)
-class Enum(SimpleProperty):
- """Custom type for Storm supporting enums."""
+
+class UUID(TypeDecorator):
+ """Platform-independent GUID type.
+
+ Uses Postgresql's UUID type, otherwise uses
+ CHAR(32), storing as stringified hex values.
- variable_class = _EnumVariable
+ """
+ impl = CHAR
- def __init__(self, enum=None):
- super(Enum, self).__init__(enum=enum)
+ def load_dialect_impl(self, dialect):
+ if dialect.name == 'postgresql':
+ return dialect.type_descriptor(postgresql.UUID())
+ else:
+ return dialect.type_descriptor(CHAR(32))
+
+ def process_bind_param(self, value, dialect):
+ if value is None:
+ return value
+ elif dialect.name == 'postgresql':
+ return str(value)
+ else:
+ if not isinstance(value, uuid.UUID):
+ return "%.32x" % uuid.UUID(value)
+ else:
+ # hexstring
+ return "%.32x" % value
+
+ def process_result_value(self, value, dialect):
+ if value is None:
+ return value
+ else:
+ return uuid.UUID(value)