1# dialects/mysql/json.py
2# Copyright (C) 2005-2024 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: https://www.opensource.org/licenses/mit-license.php
7
8from __future__ import absolute_import
9
10from ... import types as sqltypes
11
12
13class JSON(sqltypes.JSON):
14 """MySQL JSON type.
15
16 MySQL supports JSON as of version 5.7.
17 MariaDB supports JSON (as an alias for LONGTEXT) as of version 10.2.
18
19 :class:`_mysql.JSON` is used automatically whenever the base
20 :class:`_types.JSON` datatype is used against a MySQL or MariaDB backend.
21
22 .. seealso::
23
24 :class:`_types.JSON` - main documentation for the generic
25 cross-platform JSON datatype.
26
27 The :class:`.mysql.JSON` type supports persistence of JSON values
28 as well as the core index operations provided by :class:`_types.JSON`
29 datatype, by adapting the operations to render the ``JSON_EXTRACT``
30 function at the database level.
31
32 .. versionadded:: 1.1
33
34 """
35
36 pass
37
38
39class _FormatTypeMixin(object):
40 def _format_value(self, value):
41 raise NotImplementedError()
42
43 def bind_processor(self, dialect):
44 super_proc = self.string_bind_processor(dialect)
45
46 def process(value):
47 value = self._format_value(value)
48 if super_proc:
49 value = super_proc(value)
50 return value
51
52 return process
53
54 def literal_processor(self, dialect):
55 super_proc = self.string_literal_processor(dialect)
56
57 def process(value):
58 value = self._format_value(value)
59 if super_proc:
60 value = super_proc(value)
61 return value
62
63 return process
64
65
66class JSONIndexType(_FormatTypeMixin, sqltypes.JSON.JSONIndexType):
67 def _format_value(self, value):
68 if isinstance(value, int):
69 value = "$[%s]" % value
70 else:
71 value = '$."%s"' % value
72 return value
73
74
75class JSONPathType(_FormatTypeMixin, sqltypes.JSON.JSONPathType):
76 def _format_value(self, value):
77 return "$%s" % (
78 "".join(
79 [
80 "[%s]" % elem if isinstance(elem, int) else '."%s"' % elem
81 for elem in value
82 ]
83 )
84 )