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        )