1
0
mirror of https://github.com/django/django.git synced 2025-06-08 21:19:13 +00:00

Refs #36085 -- Moved compile_json_path to BaseDatabaseOperations.

This commit is contained in:
hesham942 2025-05-13 13:37:02 +02:00 committed by Sarah Boyce
parent 6e36f7f784
commit a8716f3c4c
2 changed files with 27 additions and 23 deletions

View File

@ -792,3 +792,18 @@ class BaseDatabaseOperations:
def format_debug_sql(self, sql):
# Hook for backends (e.g. NoSQL) to customize formatting.
return sqlparse.format(sql, reindent=True, keyword_case="upper")
def compile_json_path(self, key_transforms, include_root=True):
"""
Hook for backends to customize all aspects of JSON path construction.
"""
path = ["$"] if include_root else []
for key_transform in key_transforms:
try:
num = int(key_transform)
except ValueError: # Non-integer.
path.append(".")
path.append(json.dumps(key_transform))
else:
path.append("[%s]" % num)
return "".join(path)

View File

@ -148,19 +148,6 @@ class JSONField(CheckFieldDefaultMixin, Field):
)
def compile_json_path(key_transforms, include_root=True):
path = ["$"] if include_root else []
for key_transform in key_transforms:
try:
num = int(key_transform)
except ValueError: # non-integer
path.append(".")
path.append(json.dumps(key_transform))
else:
path.append("[%s]" % num)
return "".join(path)
class DataContains(FieldGetDbPrepValueMixin, PostgresOperatorLookup):
lookup_name = "contains"
postgres_operator = "@>"
@ -194,7 +181,7 @@ class ContainedBy(FieldGetDbPrepValueMixin, PostgresOperatorLookup):
class HasKeyLookup(PostgresOperatorLookup):
logical_operator = None
def compile_json_path_final_key(self, key_transform):
def compile_json_path_final_key(self, connection, key_transform):
# Compile the final key without interpreting ints as array elements.
return ".%s" % json.dumps(key_transform)
@ -204,7 +191,7 @@ class HasKeyLookup(PostgresOperatorLookup):
lhs_sql, lhs_params, lhs_key_transforms = self.lhs.preprocess_lhs(
compiler, connection
)
lhs_json_path = compile_json_path(lhs_key_transforms)
lhs_json_path = connection.ops.compile_json_path(lhs_key_transforms)
else:
lhs_sql, lhs_params = self.process_lhs(compiler, connection)
lhs_json_path = "$"
@ -218,8 +205,10 @@ class HasKeyLookup(PostgresOperatorLookup):
else:
rhs_key_transforms = [key]
*rhs_key_transforms, final_key = rhs_key_transforms
rhs_json_path = compile_json_path(rhs_key_transforms, include_root=False)
rhs_json_path += self.compile_json_path_final_key(final_key)
rhs_json_path = connection.ops.compile_json_path(
rhs_key_transforms, include_root=False
)
rhs_json_path += self.compile_json_path_final_key(connection, final_key)
yield lhs_sql, lhs_params, lhs_json_path + rhs_json_path
def _combine_sql_parts(self, parts):
@ -296,8 +285,8 @@ class HasAnyKeys(HasKeys):
class HasKeyOrArrayIndex(HasKey):
def compile_json_path_final_key(self, key_transform):
return compile_json_path([key_transform], include_root=False)
def compile_json_path_final_key(self, connection, key_transform):
return connection.ops.compile_json_path([key_transform], include_root=False)
class CaseInsensitiveMixin:
@ -378,12 +367,12 @@ class KeyTransform(Transform):
def as_mysql(self, compiler, connection):
lhs, params, key_transforms = self.preprocess_lhs(compiler, connection)
json_path = compile_json_path(key_transforms)
json_path = connection.ops.compile_json_path(key_transforms)
return "JSON_EXTRACT(%s, %%s)" % lhs, (*params, json_path)
def as_oracle(self, compiler, connection):
lhs, params, key_transforms = self.preprocess_lhs(compiler, connection)
json_path = compile_json_path(key_transforms)
json_path = connection.ops.compile_json_path(key_transforms)
if connection.features.supports_primitives_in_json_field:
sql = (
"COALESCE("
@ -419,7 +408,7 @@ class KeyTransform(Transform):
def as_sqlite(self, compiler, connection):
lhs, params, key_transforms = self.preprocess_lhs(compiler, connection)
json_path = compile_json_path(key_transforms)
json_path = connection.ops.compile_json_path(key_transforms)
datatype_values = ",".join(
[repr(datatype) for datatype in connection.ops.jsonfield_datatype_values]
)
@ -441,7 +430,7 @@ class KeyTextTransform(KeyTransform):
return "JSON_UNQUOTE(%s)" % sql, params
else:
lhs, params, key_transforms = self.preprocess_lhs(compiler, connection)
json_path = compile_json_path(key_transforms)
json_path = connection.ops.compile_json_path(key_transforms)
return "(%s ->> %%s)" % lhs, (*params, json_path)
@classmethod