| 354 | class _UninitializedOperatorsDescriptor(object): |
| 355 | |
| 356 | def __get__(self, instance, owner): |
| 357 | # If connection.operators is looked up before a connection has been |
| 358 | # created, transparently initialize connection.operators to avert an |
| 359 | # AttributeError. |
| 360 | if instance is None: |
| 361 | raise AttributeError("operators not available as class attribute") |
| 362 | # Creating a cursor will initialize the operators. |
| 363 | instance.cursor() |
| 364 | return instance.operators |
| 365 | |
| 366 | |
| 386 | _likec_operators = _standard_operators.copy() |
| 387 | _likec_operators.update({ |
| 388 | 'contains': "LIKEC %s ESCAPE '\\'", |
| 389 | 'icontains': "LIKEC UPPER(%s) ESCAPE '\\'", |
| 390 | 'startswith': "LIKEC %s ESCAPE '\\'", |
| 391 | 'endswith': "LIKEC %s ESCAPE '\\'", |
| 392 | 'istartswith': "LIKEC UPPER(%s) ESCAPE '\\'", |
| 393 | 'iendswith': "LIKEC UPPER(%s) ESCAPE '\\'", |
| 394 | }) |
| 395 | |
| 440 | |
| 441 | if 'operators' not in self.__dict__: |
| 442 | # Ticket #14149: Check whether our LIKE implementation will |
| 443 | # work for this connection or we need to fall back on LIKEC. |
| 444 | # This check is performed only once per DatabaseWrapper |
| 445 | # instance per thread, since subsequent connections will use |
| 446 | # the same settings. |
| 447 | try: |
| 448 | cursor.execute("SELECT 1 FROM DUAL WHERE DUMMY %s" |
| 449 | % self._standard_operators['contains'], |
| 450 | ['X']) |
| 451 | except utils.DatabaseError: |
| 452 | self.operators = self._likec_operators |
| 453 | else: |
| 454 | self.operators = self._standard_operators |
| 455 | |