|
@@ -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
|