1# mysql/cymysql.py
2# Copyright (C) 2005-2016 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: http://www.opensource.org/licenses/mit-license.php
7
8"""
9
10.. dialect:: mysql+cymysql
11    :name: CyMySQL
12    :dbapi: cymysql
13    :connectstring: mysql+cymysql://<username>:<password>@<host>/<dbname>\
14[?<options>]
15    :url: https://github.com/nakagami/CyMySQL
16
17"""
18import re
19
20from .mysqldb import MySQLDialect_mysqldb
21from .base import (BIT, MySQLDialect)
22from ... import util
23
24
25class _cymysqlBIT(BIT):
26    def result_processor(self, dialect, coltype):
27        """Convert a MySQL's 64 bit, variable length binary string to a long.
28        """
29
30        def process(value):
31            if value is not None:
32                v = 0
33                for i in util.iterbytes(value):
34                    v = v << 8 | i
35                return v
36            return value
37        return process
38
39
40class MySQLDialect_cymysql(MySQLDialect_mysqldb):
41    driver = 'cymysql'
42
43    description_encoding = None
44    supports_sane_rowcount = True
45    supports_sane_multi_rowcount = False
46    supports_unicode_statements = True
47
48    colspecs = util.update_copy(
49        MySQLDialect.colspecs,
50        {
51            BIT: _cymysqlBIT,
52        }
53    )
54
55    @classmethod
56    def dbapi(cls):
57        return __import__('cymysql')
58
59    def _get_server_version_info(self, connection):
60        dbapi_con = connection.connection
61        version = []
62        r = re.compile('[.\-]')
63        for n in r.split(dbapi_con.server_version):
64            try:
65                version.append(int(n))
66            except ValueError:
67                version.append(n)
68        return tuple(version)
69
70    def _detect_charset(self, connection):
71        return connection.connection.charset
72
73    def _extract_error_code(self, exception):
74        return exception.errno
75
76    def is_disconnect(self, e, connection, cursor):
77        if isinstance(e, self.dbapi.OperationalError):
78            return self._extract_error_code(e) in \
79                (2006, 2013, 2014, 2045, 2055)
80        elif isinstance(e, self.dbapi.InterfaceError):
81            # if underlying connection is closed,
82            # this is the error you get
83            return True
84        else:
85            return False
86
87dialect = MySQLDialect_cymysql
88