Esempio n. 1
0
 def _create_index_name(self, model, column_names, suffix=""):
     """
     Generates a unique name for an index/unique constraint.
     """
     # If there is just one column in the index, use a default algorithm from Django
     if len(column_names) == 1 and not suffix:
         return truncate_name(
             '%s_%s' %
             (model._meta.db_table, self._digest(column_names[0])),
             self.connection.ops.max_name_length())
     # Else generate the name for the index using a different algorithm
     table_name = model._meta.db_table.replace('"', '').replace('.', '_')
     index_unique_name = '_%s' % self._digest(table_name, *column_names)
     max_length = self.connection.ops.max_name_length() or 200
     # If the index name is too long, truncate it
     index_name = ('%s_%s%s%s' % (
         table_name,
         column_names[0],
         index_unique_name,
         suffix,
     )).replace('"', '').replace('.', '_')
     if len(index_name) > max_length:
         part = ('_%s%s%s' % (column_names[0], index_unique_name, suffix))
         index_name = '%s%s' % (table_name[:(max_length - len(part))], part)
     # It shouldn't start with an underscore (Oracle hates this)
     if index_name[0] == "_":
         index_name = index_name[1:]
     # If it's STILL too long, just hash it down
     if len(index_name) > max_length:
         index_name = hashlib.md5(
             force_bytes(index_name)).hexdigest()[:max_length]
     # It can't start with a number on Oracle, so prepend D if we need to
     if index_name[0].isdigit():
         index_name = "D%s" % index_name[:-1]
     return index_name
Esempio n. 2
0
    def get(self, key, default=None, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)
        db = router.db_for_read(self.cache_model_class)
        connection = connections[db]
        table = connection.ops.quote_name(self._table)

        with connection.cursor() as cursor:
            cursor.execute(
                "SELECT cache_key, value, expires FROM %s "
                "WHERE cache_key = %%s" % table, [key])
            row = cursor.fetchone()
        if row is None:
            return default

        expires = row[2]
        expression = models.Expression(output_field=models.DateTimeField())
        for converter in (connection.ops.get_db_converters(expression) +
                          expression.get_db_converters(connection)):
            expires = converter(expires, expression, connection, {})

        if expires < timezone.now():
            db = router.db_for_write(self.cache_model_class)
            connection = connections[db]
            with connection.cursor() as cursor:
                cursor.execute(
                    "DELETE FROM %s "
                    "WHERE cache_key = %%s" % table, [key])
            return default

        value = connection.ops.process_clob(row[1])
        return pickle.loads(base64.b64decode(force_bytes(value)))
Esempio n. 3
0
def truncate_name(name, length=None, hash_len=4):
    """Shortens a string to a repeatable mangled version with the given length.
    """
    if length is None or len(name) <= length:
        return name

    hsh = hashlib.md5(force_bytes(name)).hexdigest()[:hash_len]
    return '%s%s' % (name[:length - hash_len], hsh)
Esempio n. 4
0
 def __init__(self, content, name=None):
     if six.PY3:
         stream_class = StringIO if isinstance(content,
                                               six.text_type) else BytesIO
     else:
         stream_class = BytesIO
         content = force_bytes(content)
     super(ContentFile, self).__init__(stream_class(content), name=name)
     self.size = len(content)
Esempio n. 5
0
 def _digest(cls, *args):
     """
     Generates a 32-bit digest of a set of arguments that can be used to
     shorten identifying names.
     """
     h = hashlib.md5()
     for arg in args:
         h.update(force_bytes(arg))
     return h.hexdigest()[:8]
Esempio n. 6
0
def urlsafe_base64_decode(s):
    """
    Decodes a base64 encoded string, adding back any trailing equal signs that
    might have been stripped.
    """
    s = force_bytes(s)
    try:
        return base64.urlsafe_b64decode(s.ljust(len(s) + len(s) % 4, b'='))
    except (LookupError, BinasciiError) as e:
        raise ValueError(e)
Esempio n. 7
0
 def _key_to_file(self, key, version=None):
     """
     Convert a key into a cache file path. Basically this is the
     root cache path joined with the md5sum of the key and a suffix.
     """
     key = self.make_key(key, version=version)
     self.validate_key(key)
     return os.path.join(
         self._dir, ''.join(
             [hashlib.md5(force_bytes(key)).hexdigest(),
              self.cache_suffix]))
Esempio n. 8
0
    def __init__(self, param, cursor, strings_only=False):
        # With raw SQL queries, datetimes can reach this function
        # without being converted by DateTimeField.get_db_prep_value.
        if settings.USE_TZ and (isinstance(param, datetime.datetime) and
                                not isinstance(param, Oracle_datetime)):
            if timezone.is_aware(param):
                warnings.warn(
                    "The Oracle database adapter received an aware datetime (%s), "
                    "probably from cursor.execute(). Update your code to pass a "
                    "naive datetime in the database connection's time zone (UTC by "
                    "default).", RemovedInDjango20Warning)
                param = param.astimezone(timezone.utc).replace(tzinfo=None)
            param = Oracle_datetime.from_datetime(param)

        if isinstance(param, datetime.timedelta):
            param = duration_string(param)
            if ' ' not in param:
                param = '0 ' + param

        string_size = 0
        # Oracle doesn't recognize True and False correctly in Python 3.
        # The conversion done below works both in 2 and 3.
        if param is True:
            param = 1
        elif param is False:
            param = 0
        if hasattr(param, 'bind_parameter'):
            self.force_bytes = param.bind_parameter(cursor)
        elif isinstance(param, Database.Binary):
            self.force_bytes = param
        else:
            # To transmit to the database, we need Unicode if supported
            # To get size right, we must consider bytes.
            self.force_bytes = convert_unicode(param, cursor.charset, strings_only)
            if isinstance(self.force_bytes, six.string_types):
                # We could optimize by only converting up to 4000 bytes here
                string_size = len(force_bytes(param, cursor.charset, strings_only))
        if hasattr(param, 'input_size'):
            # If parameter has `input_size` attribute, use that.
            self.input_size = param.input_size
        elif string_size > 4000:
            # Mark any string param greater than 4000 characters as a CLOB.
            self.input_size = Database.CLOB
        else:
            self.input_size = None
Esempio n. 9
0
def make_template_fragment_key(fragment_name, vary_on=None):
    if vary_on is None:
        vary_on = ()
    key = ':'.join(urlquote(var) for var in vary_on)
    args = hashlib.md5(force_bytes(key))
    return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, args.hexdigest())
Esempio n. 10
0
 def convert_binaryfield_value(self, value, expression, connection, context):
     if isinstance(value, Database.LOB):
         value = force_bytes(value.read())
     return value