mirror of
https://github.com/django/django.git
synced 2025-09-08 19:50:48 +00:00
Refs #28643 -- Added Ord, Chr, Left, and Right database functions.
This commit is contained in:
parent
c412926a2e
commit
f82de6bfb1
8 changed files with 262 additions and 6 deletions
|
@ -1,7 +1,23 @@
|
|||
from django.db.models import Func, Transform, Value, fields
|
||||
from django.db.models import Func, IntegerField, Transform, Value, fields
|
||||
from django.db.models.functions import Coalesce
|
||||
|
||||
|
||||
class Chr(Transform):
|
||||
function = 'CHR'
|
||||
lookup_name = 'chr'
|
||||
|
||||
def as_mysql(self, compiler, connection):
|
||||
return super().as_sql(
|
||||
compiler, connection, function='CHAR', template='%(function)s(%(expressions)s USING utf16)'
|
||||
)
|
||||
|
||||
def as_oracle(self, compiler, connection):
|
||||
return super().as_sql(compiler, connection, template='%(function)s(%(expressions)s USING NCHAR_CS)')
|
||||
|
||||
def as_sqlite(self, compiler, connection, **extra_context):
|
||||
return super().as_sql(compiler, connection, function='CHAR', **extra_context)
|
||||
|
||||
|
||||
class ConcatPair(Func):
|
||||
"""
|
||||
Concatenate two arguments together. This is used by `Concat` because not
|
||||
|
@ -55,6 +71,30 @@ class Concat(Func):
|
|||
return ConcatPair(expressions[0], self._paired(expressions[1:]))
|
||||
|
||||
|
||||
class Left(Func):
|
||||
function = 'LEFT'
|
||||
arity = 2
|
||||
|
||||
def __init__(self, expression, length, **extra):
|
||||
"""
|
||||
expression: the name of a field, or an expression returning a string
|
||||
length: the number of characters to return from the start of the string
|
||||
"""
|
||||
if not hasattr(length, 'resolve_expression'):
|
||||
if length < 1:
|
||||
raise ValueError("'length' must be greater than 0.")
|
||||
super().__init__(expression, length, **extra)
|
||||
|
||||
def get_substr(self):
|
||||
return Substr(self.source_expressions[0], Value(1), self.source_expressions[1])
|
||||
|
||||
def use_substr(self, compiler, connection, **extra_context):
|
||||
return self.get_substr().as_oracle(compiler, connection, **extra_context)
|
||||
|
||||
as_oracle = use_substr
|
||||
as_sqlite = use_substr
|
||||
|
||||
|
||||
class Length(Transform):
|
||||
"""Return the number of characters in the expression."""
|
||||
function = 'LENGTH'
|
||||
|
@ -70,6 +110,18 @@ class Lower(Transform):
|
|||
lookup_name = 'lower'
|
||||
|
||||
|
||||
class Ord(Transform):
|
||||
function = 'ASCII'
|
||||
lookup_name = 'ord'
|
||||
output_field = IntegerField()
|
||||
|
||||
def as_mysql(self, compiler, connection, **extra_context):
|
||||
return super().as_sql(compiler, connection, function='ORD', **extra_context)
|
||||
|
||||
def as_sqlite(self, compiler, connection, **extra_context):
|
||||
return super().as_sql(compiler, connection, function='UNICODE', **extra_context)
|
||||
|
||||
|
||||
class Replace(Func):
|
||||
function = 'REPLACE'
|
||||
|
||||
|
@ -77,6 +129,13 @@ class Replace(Func):
|
|||
super().__init__(expression, text, replacement, **extra)
|
||||
|
||||
|
||||
class Right(Left):
|
||||
function = 'RIGHT'
|
||||
|
||||
def get_substr(self):
|
||||
return Substr(self.source_expressions[0], self.source_expressions[1] * Value(-1))
|
||||
|
||||
|
||||
class StrIndex(Func):
|
||||
"""
|
||||
Return a positive integer corresponding to the 1-indexed position of the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue