1from ... import types as sqltypes
2
3
4class JSON(sqltypes.JSON):
5 """SQLite JSON type.
6
7 SQLite supports JSON as of version 3.9 through its JSON1_ extension. Note
8 that JSON1_ is a
9 `loadable extension <https://www.sqlite.org/loadext.html>`_ and as such
10 may not be available, or may require run-time loading.
11
12 The :class:`_sqlite.JSON` type supports persistence of JSON values
13 as well as the core index operations provided by :class:`_types.JSON`
14 datatype, by adapting the operations to render the ``JSON_EXTRACT``
15 function wrapped in the ``JSON_QUOTE`` function at the database level.
16 Extracted values are quoted in order to ensure that the results are
17 always JSON string values.
18
19 .. versionadded:: 1.3
20
21 .. seealso::
22
23 JSON1_
24
25 .. _JSON1: https://www.sqlite.org/json1.html
26
27 """
28
29
30# Note: these objects currently match exactly those of MySQL, however since
31# these are not generalizable to all JSON implementations, remain separately
32# implemented for each dialect.
33class _FormatTypeMixin(object):
34 def _format_value(self, value):
35 raise NotImplementedError()
36
37 def bind_processor(self, dialect):
38 super_proc = self.string_bind_processor(dialect)
39
40 def process(value):
41 value = self._format_value(value)
42 if super_proc:
43 value = super_proc(value)
44 return value
45
46 return process
47
48 def literal_processor(self, dialect):
49 super_proc = self.string_literal_processor(dialect)
50
51 def process(value):
52 value = self._format_value(value)
53 if super_proc:
54 value = super_proc(value)
55 return value
56
57 return process
58
59
60class JSONIndexType(_FormatTypeMixin, sqltypes.JSON.JSONIndexType):
61 def _format_value(self, value):
62 if isinstance(value, int):
63 value = "$[%s]" % value
64 else:
65 value = '$."%s"' % value
66 return value
67
68
69class JSONPathType(_FormatTypeMixin, sqltypes.JSON.JSONPathType):
70 def _format_value(self, value):
71 return "$%s" % (
72 "".join(
73 [
74 "[%s]" % elem if isinstance(elem, int) else '."%s"' % elem
75 for elem in value
76 ]
77 )
78 )