summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/minipg.py
blob: b3f184abf6e69cdf325843448474c210bc5c4090 (plain)
1
2
3
4
5
6
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
115
116
117
118
# postgresql/minipg.py
# Copyright (C) 2005-2014 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""
.. dialect:: postgresql+minipg
    :name: minipg
    :dbapi: minipg
    :connectstring: postgresql+minipg://user:password@host:port/dbname\
[?key=value&key=value...]
    :url: https://github.com/nakagami/minipg


"""
import decimal
from ... import util, exc
from ... import types as sqltypes
from .base import PGDialect, PGCompiler, \
    PGExecutionContext, _DECIMAL_TYPES, _FLOAT_TYPES, _INT_TYPES
from ... import processors

class _PGNumeric(sqltypes.Numeric):
    def bind_processor(self, dialect):
        return None

    def result_processor(self, dialect, coltype):
        if self.asdecimal:
            if coltype in _FLOAT_TYPES:
                return processors.to_decimal_processor_factory(
                    decimal.Decimal,
                    self._effective_decimal_return_scale)
            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                # minipg returns Decimal natively for 1700
                return None
            else:
                raise exc.InvalidRequestError(
                    "Unknown PG numeric type: %d" % coltype)
        else:
            if coltype in _FLOAT_TYPES:
                # minipg returns float natively for 701
                return None
            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                return processors.to_float
            else:
                raise exc.InvalidRequestError(
                    "Unknown PG numeric type: %d" % coltype)



class PGCompiler_minipg(PGCompiler):
    def visit_match_op_binary(self, binary, operator, **kw):
        v = __import__('minipg').escape_parameter(binary.right)
        return "%s=%s" % (self.process(binary.left, **kw), v)

class PGDialect_minipg(PGDialect):
    driver = 'minipg'

    default_paramstyle = 'format'
    supports_sane_multi_rowcount = True
    supports_unicode_statements = True
    supports_unicode_binds = True
    description_encoding = 'use_encoding'
    statement_compiler = PGCompiler_minipg

    colspecs = util.update_copy(
        PGDialect.colspecs,
        {
            sqltypes.Numeric: _PGNumeric,
        }
    )

    @classmethod
    def dbapi(cls):
        return __import__('minipg')

    def create_connect_args(self, url):
        opts = url.translate_connect_args(username='user')
        if 'port' in opts:
            opts['port'] = int(opts['port'])
        else:
            opts['port'] = 5432
        opts.update(url.query)
        return ([], opts)

    def is_disconnect(self, e, connection, cursor):
        if not connection:
            return False
        return not connection.is_connect()

    def set_isolation_level(self, connection, level):
        level = level.replace('_', ' ')

        # adjust for ConnectionFairy possibly being present
        if hasattr(connection, 'connection'):
            connection = connection.connection

        if level == 'AUTOCOMMIT':
            connection.autocommit = True
        elif level in self._isolation_lookup:
            connection.autocommit = False
            cursor = connection.cursor()
            cursor.execute(
                "SET SESSION CHARACTERISTICS AS TRANSACTION "
                "ISOLATION LEVEL %s" % level)
            cursor.execute("COMMIT")
            cursor.close()
        else:
            raise exc.ArgumentError(
                "Invalid value '%s' for isolation_level. "
                "Valid isolation levels for %s are %s or AUTOCOMMIT" %
                (level, self.name, ", ".join(self._isolation_lookup))
            )


dialect = PGDialect_minipg