types.py 2.89 KB
Newer Older
Gerion Entrup's avatar
Gerion Entrup committed
1
2
3
4
5
# Copyright (C) 2013 Lukas Lalinsky
# Distributed under the MIT license, see the LICENSE file for details.

import re
from sqlalchemy.ext.compiler import compiles
6
from sqlalchemy.dialects.postgresql import UUID
Gerion Entrup's avatar
Gerion Entrup committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from sqlalchemy.types import UserDefinedType
from sqlalchemy.sql.expression import ClauseElement, TextClause


@compiles(UUID, 'sqlite')
def visit_uuid_sqlite(element, compiler, **kwargs):
    return 'CHAR(32)'


class regexp(ClauseElement):
    def __init__(self, column, pattern):
        self.column = column
        self.pattern = TextClause(pattern)


@compiles(regexp)
def visit_regexp(element, compiler, **kwargs):
    return '{0} REGEXP {1}'.format(
        compiler.process(element.column),
        compiler.process(element.pattern))


@compiles(regexp, 'postgresql')
def visit_regexp_postgresql(element, compiler, **kwargs):
    return '{0} ~ {1}'.format(
        compiler.process(element.column),
        compiler.process(element.pattern))


class PartialDate(object):

    __slots__ = ('year', 'month', 'day')

    def __init__(self, year=None, month=None, day=None):
        self.year = year
        self.month = month
        self.day = day

    def __composite_values__(self):
        return self.year, self.month, self.day

    def __iter__(self):
        yield self.year
        yield self.month
        yield self.day

    def __repr__(self):
        return "{0.__class__.__name__}(year={0.year}, month={0.month}, day={0.day})".format(self)

    def __eq__(self, other):
        return isinstance(other, PartialDate) and \
            other.year == self.year and \
            other.month == self.month and \
            other.day == self.day

    def __ne__(self, other):
        return not self.__eq__(other)

    def __bool__(self):
        return bool(self.year or self.month or self.day)


class Point(UserDefinedType):

    # pylint: disable=W0223
    # pylint: disable=R0201

    def get_col_spec(self):
        return 'POINT'

    def bind_processor(self, dialect):
        def process(value):
            if value is None:
                return None
            return '({0},{1})'.format(value[0], value[1])
        return process

    def result_processor(self, dialect, coltype):
        def process(value):
            if value is None:
                return None
            match = re.match(r'\((-?[0-9.]+),(-?[0-9.]+)\)', value)
            return tuple([float(x) for x in match.groups()])
        return process


class Cube(UserDefinedType):

    # pylint: disable=W0223
    # pylint: disable=R0201

    def get_col_spec(self):
        return 'CUBE'

    def bind_processor(self, dialect):
        def process(value):
            if value is None:
                return None
            return value
        return process

    def result_processor(self, dialect, coltype):
        def process(value):
            if value is None:
                return None
            return value
        return process