1
1
"""
2
2
Specialized has_any and has_all query lookups for flag enumerations.
3
3
"""
4
+ #from django.core.exceptions import FieldError
4
5
from django .db .models .lookups import Exact
5
6
7
+ #from django_enum.utils import get_set_bits
8
+
6
9
7
10
class HasAllFlagsLookup (Exact ): # pylint: disable=W0223
8
11
"""
@@ -17,15 +20,57 @@ def process_lhs(self, compiler, connection, lhs=None):
17
20
lhs_sql , lhs_params = super ().process_lhs (compiler , connection , lhs )
18
21
rhs_sql , rhs_params = super ().process_rhs (compiler , connection )
19
22
if self .rhs :
20
- return ' & ' .join (
21
- (lhs_sql , rhs_sql )
22
- ), [* lhs_params , * rhs_params ]
23
+ return (
24
+ 'BITAND(%s, %s)'
25
+ if connection .vendor == 'oracle'
26
+ else '%s & %s'
27
+ ) % (lhs_sql , rhs_sql ), [* lhs_params , * rhs_params ]
23
28
return lhs_sql , lhs_params
24
29
25
30
def get_rhs_op (self , connection , rhs ):
26
31
return connection .operators ['exact' ] % rhs
27
32
28
33
34
+ # class ExtraBigFlagMixin:
35
+ #
36
+ # def get_prep_lookup(self):
37
+ # return self.lhs.output_field.to_python(super().get_prep_lookup())
38
+ #
39
+ # def get_rhs_op(self, connection, rhs):
40
+ # if connection.vendor == 'postgresql':
41
+ # return connection.operators['exact'] % '1'
42
+ # raise FieldError(
43
+ # f'{connection.vendor} does not support {self.lookup_name} on '
44
+ # f'ExtraBigIntegerFlagFields.'
45
+ # )
46
+
47
+
48
+ # class HasAllFlagsExtraBigLookup(
49
+ # ExtraBigFlagMixin,
50
+ # HasAllFlagsLookup
51
+ # ): # pylint: disable=W0223
52
+ # """
53
+ # Support for bitwise has_all lookup on extra big integers (>64 bits) stored
54
+ # as binary columns.
55
+ #
56
+ # get_bit(, 0) AND get_bit(, 7) = 1;
57
+ # """
58
+ #
59
+ # def process_lhs(self, compiler, connection, lhs=None):
60
+ # lhs_sql, lhs_params = Exact.process_lhs(self, compiler, connection, lhs)
61
+ # rhs_sql, rhs_params = Exact.process_rhs(self, compiler, connection)
62
+ # bits = get_set_bits(rhs_params[0])
63
+ # if self.rhs:
64
+ # ret = ' AND '.join(
65
+ # [
66
+ # f'get_bit({lhs_sql}, %s)' for _ in range(len(bits))
67
+ # ]
68
+ # ), bits
69
+ # print(ret)
70
+ # return ret
71
+ # return lhs_sql, lhs_params
72
+
73
+
29
74
class HasAnyFlagsLookup (HasAllFlagsLookup ): # pylint: disable=W0223
30
75
"""
31
76
Extend Exact lookup to support lookup on has any flags. This bitwise ANDs
@@ -42,3 +87,32 @@ def process_rhs(self, compiler, connection):
42
87
43
88
def get_rhs_op (self , connection , rhs ):
44
89
return connection .operators ['gt' if self .rhs else 'exact' ] % rhs
90
+
91
+
92
+ # class HasAnyFlagsExtraBigLookup(
93
+ # ExtraBigFlagMixin,
94
+ # HasAnyFlagsLookup
95
+ # ): # pylint: disable=W0223
96
+ # """
97
+ # Support for bitwise has_any lookup on extra big integers (>64 bits) stored
98
+ # as binary columns.
99
+ # """
100
+ #
101
+ # def process_lhs(self, compiler, connection, lhs=None):
102
+ # lhs_sql, lhs_params = Exact.process_lhs(self, compiler, connection, lhs)
103
+ # rhs_sql, rhs_params = Exact.process_rhs(self, compiler, connection)
104
+ # bits = get_set_bits(rhs_params[0])
105
+ # if self.rhs:
106
+ # ret = ' OR '.join(
107
+ # [
108
+ # f'get_bit({lhs_sql}, %s)' for _ in range(len(bits))
109
+ # ]
110
+ # ), [*bits, 1]
111
+ # print(ret)
112
+ # return ret
113
+ # return lhs_sql, lhs_params
114
+ #
115
+ # def process_rhs(self, compiler, connection):
116
+ # rhs_sql, rhs_params = Exact.process_rhs(self, compiler, connection)
117
+ # rhs_params[0] = 0
118
+ # return rhs_sql, rhs_params
0 commit comments