Beispiel #1
0
 def test_split_identifier(self):
     self.assertEqual(split_identifier('some_table'), ('', 'some_table'))
     self.assertEqual(split_identifier('"some_table"'), ('', 'some_table'))
     self.assertEqual(split_identifier('namespace"."some_table'),
                      ('namespace', 'some_table'))
     self.assertEqual(split_identifier('"namespace"."some_table"'),
                      ('namespace', 'some_table'))
Beispiel #2
0
 def test_split_identifier(self):
     self.assertEqual(split_identifier("some_table"), ("", "some_table"))
     self.assertEqual(split_identifier('"some_table"'), ("", "some_table"))
     self.assertEqual(
         split_identifier('namespace"."some_table'), ("namespace", "some_table")
     )
     self.assertEqual(
         split_identifier('"namespace"."some_table"'), ("namespace", "some_table")
     )
Beispiel #3
0
    def _create_index_name(self, table_name, column_names, suffix=""):
        """
        Generate a unique name for an index/unique constraint.

        The name is divided into 3 parts: the table name, the column names,
        and a unique digest and suffix.
        """
        _, table_name = split_identifier(table_name)
        hash_suffix_part = '%s%s' % (self._digest(table_name, *column_names), suffix)
        max_length = self.connection.ops.max_name_length() or 200
        # If everything fits into max_length, use that name.
        index_name = '%s_%s_%s' % (table_name, '_'.join(column_names), hash_suffix_part)
        if len(index_name) <= max_length:
            return index_name
        # Shorten a long suffix.
        if len(hash_suffix_part) > max_length / 3:
            hash_suffix_part = hash_suffix_part[:max_length // 3]
        other_length = (max_length - len(hash_suffix_part)) // 2 - 1
        index_name = '%s_%s_%s' % (
            table_name[:other_length],
            '_'.join(column_names)[:other_length],
            hash_suffix_part,
        )
        # Prepend D if needed to prevent the name from starting with an
        # underscore or a number (not permitted on Oracle).
        if index_name[0] == "_" or index_name[0].isdigit():
            index_name = "D%s" % index_name[:-1]
        return index_name
Beispiel #4
0
    def _create_index_name(self, table_name, column_names, suffix=""):
        """
        Generate a unique name for an index/unique constraint.

        The name is divided into 3 parts: the table name, the column names,
        and a unique digest and suffix.
        """
        _, table_name = split_identifier(table_name)
        hash_suffix_part = '%s%s' % (self._digest(table_name, *column_names), suffix)
        max_length = self.connection.ops.max_name_length() or 200
        # If everything fits into max_length, use that name.
        index_name = '%s_%s_%s' % (table_name, '_'.join(column_names), hash_suffix_part)
        if len(index_name) <= max_length:
            return index_name
        # Shorten a long suffix.
        if len(hash_suffix_part) > max_length / 3:
            hash_suffix_part = hash_suffix_part[:max_length // 3]
        other_length = (max_length - len(hash_suffix_part)) // 2 - 1
        index_name = '%s_%s_%s' % (
            table_name[:other_length],
            '_'.join(column_names)[:other_length],
            hash_suffix_part,
        )
        # Prepend D if needed to prevent the name from starting with an
        # underscore or a number (not permitted on Oracle).
        if index_name[0] == "_" or index_name[0].isdigit():
            index_name = "D%s" % index_name[:-1]
        return index_name
Beispiel #5
0
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [model._meta.get_field(field_name).column for field_name, order in self.fields_orders]
        column_names_with_order = [
            (('-%s' if order else '%s') % column_name)
            for column_name, (field_name, order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = '%s_%s_%s' % (
            table_name[:11],
            column_names[0][:7],
            '%s_%s' % (names_digest(*hash_data, length=6), self.suffix),
        )
        assert len(self.name) <= self.max_name_length, (
            'Index too long for multiple database support. Is self.suffix '
            'longer than 3 characters?'
        )
        self.check_name()
Beispiel #6
0
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [model._meta.get_field(field_name).column for field_name, order in self.fields_orders]
        column_names_with_order = [
            (('-%s' if order else '%s') % column_name)
            for column_name, (field_name, order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = '%s_%s_%s' % (
            table_name[:11],
            column_names[0][:7],
            '%s_%s' % (names_digest(*hash_data, length=6), self.suffix),
        )
        if len(self.name) > self.max_name_length:
            raise ValueError(
                'Index too long for multiple database support. Is self.suffix '
                'longer than 3 characters?'
            )
        if self.name[0] == '_' or self.name[0].isdigit():
            self.name = 'D%s' % self.name[1:]
Beispiel #7
0
    def set_name_with_model(self, model):
        """
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        """
        _, table_name = split_identifier(model._meta.db_table)
        column_names = [
            model._meta.get_field(field_name).column
            for field_name, order in self.fields_orders
        ]
        column_names_with_order = [
            (("-%s" if order else "%s") % column_name)
            for column_name, (field_name,
                              order) in zip(column_names, self.fields_orders)
        ]
        # The length of the parts of the name is based on the default max
        # length of 30 characters.
        hash_data = [table_name] + column_names_with_order + [self.suffix]
        self.name = "%s_%s_%s" % (
            table_name[:11],
            column_names[0][:7],
            "%s_%s" % (names_digest(*hash_data, length=6), self.suffix),
        )
        assert len(self.name) <= self.max_name_length, (
            "Index too long for multiple database support. Is self.suffix "
            "longer than 3 characters?")
        self.check_name()
Beispiel #8
0
def split_table_identifiers(db_table, format='') -> TableIdentifiers:
    namespace, table = split_identifier(db_table)

    groupdict = dict(
        namespace=namespace,
        table=table,
        table_name=table,
    )

    if format:
        _, table_format = split_identifier(format)

        result = parse(table_format, table)
        if result:
            groupdict.update(result.named)

    return TableIdentifiers(**groupdict)
    def _fk_constraint_name(self, model, field, suffix):
        def create_fk_name(*args, **kwargs):
            return self.quote_name(self._create_index_name(*args, **kwargs))

        return ForeignKeyName(
            model._meta.db_table.split('[')[-1],
            [field.column],
            split_identifier(field.target_field.model._meta.db_table.split('[')[-1])[1],
            [field.target_field.column],
            suffix,
            create_fk_name,
        )
Beispiel #10
0
def normalize_table(db_table: str, format: str, exclude=[]):
    # Ignore excluded formats
    for fmt in exclude:
        result = parse(fmt, db_table)
        if result:
            return db_table

    namespace, table_name = split_identifier(db_table)
    namespace_format, table_format = split_identifier(format)

    # Add namespace from format when specified, but not included in db_table
    if namespace_format and not namespace:
        result = parse(table_format, table_name)
        formatted = table_name
        if not result:
            formatted = table_format.format(table_name=table_name)
        return '"{}"."{}"'.format(namespace_format, formatted)

    pattern = compile(format)
    result = pattern.parse(db_table)
    if not result:
        return format.format(table_name=db_table)

    return db_table
Beispiel #11
0
    def _create_fk_sql(self, model, field, suffix):
        from_table = model._meta.db_table
        from_column = field.column
        _, to_table = split_identifier(field.target_field.model._meta.db_table)
        to_column = field.target_field.column

        def create_fk_name(*args, **kwargs):
            return self.quote_name(self._create_index_name(*args, **kwargs))

        return Statement(
            self.sql_create_fk,
            table=Table(from_table, self.quote_name),
            name=ForeignKeyName(from_table, [from_column], to_table, [to_column], suffix, create_fk_name),
            column=Columns(from_table, [from_column], self.quote_name),
            to_table=Table(field.target_field.model._meta.db_table, self.quote_name),
            to_column=Columns(field.target_field.model._meta.db_table, [to_column], self.quote_name),
            deferrable=self.connection.ops.deferrable_sql(),
        )
Beispiel #12
0
    def _create_fk_sql(self, model, field, suffix):
        from_table = model._meta.db_table
        from_column = field.column
        _, to_table = split_identifier(field.target_field.model._meta.db_table)
        to_column = field.target_field.column
        suffix = suffix % {
            "to_table": to_table,
            "to_column": to_column,
        }

        return self.sql_create_fk % {
            "table": self.quote_name(from_table),
            "name": self.quote_name(self._create_index_name(model, [from_column], suffix=suffix)),
            "column": self.quote_name(from_column),
            "to_table": self.quote_name(field.target_field.model._meta.db_table),
            "to_column": self.quote_name(to_column),
            "deferrable": self.connection.ops.deferrable_sql(),
        }
Beispiel #13
0
    def _create_fk_sql(self, model, field, suffix):
        from_table = model._meta.db_table
        from_column = field.column
        _, to_table = split_identifier(field.target_field.model._meta.db_table)
        to_column = field.target_field.column

        def create_fk_name(*args, **kwargs):
            return self.quote_name(self._create_index_name(*args, **kwargs))

        return Statement(
            self.sql_create_fk,
            table=Table(from_table, self.quote_name),
            name=ForeignKeyName(from_table, [from_column], to_table, [to_column], suffix, create_fk_name),
            column=Columns(from_table, [from_column], self.quote_name),
            to_table=Table(field.target_field.model._meta.db_table, self.quote_name),
            to_column=Columns(field.target_field.model._meta.db_table, [to_column], self.quote_name),
            deferrable=self.connection.ops.deferrable_sql(),
        )
Beispiel #14
0
    def _create_fk_sql(self, model, field, suffix):
        def create_fk_name(*args, **kwargs):
            return self.quote_name(self._create_index_name(*args, **kwargs))

        table = Table(model._meta.db_table, self.quote_name)
        name = ForeignKeyName(
            model._meta.db_table,
            [field.column],
            split_identifier(field.target_field.model._meta.db_table)[1],
            [field.target_field.column],
            suffix,
            create_fk_name,
        )
        column = Columns(model._meta.db_table, [field.column], self.quote_name)
        to_table = Table(field.target_field.model._meta.db_table,
                         self.quote_name)
        to_column = Columns(field.target_field.model._meta.db_table,
                            [field.target_field.column], self.quote_name)
        deferrable = self.connection.ops.deferrable_sql()
        table_name = model._meta.db_table
        to_table_name = field.target_field.model._meta.db_table
        if (table_name == to_table_name):
            return Statement(
                self.sql_create_fk,
                table=table,
                name=name,
                column=column,
                to_table=to_table,
                to_column=to_column,
                on_update="",
                deferrable=deferrable,
            )
        else:
            return Statement(
                self.sql_create_fk,
                table=table,
                name=name,
                column=column,
                to_table=to_table,
                to_column=to_column,
                on_update="ON UPDATE CASCADE",
                deferrable=deferrable,
            )
Beispiel #15
0
 def set_name_with_model(self, model):
     self.fields_orders = [(model._meta.pk.name, '')]
     _, table_name = split_identifier(model._meta.db_table)
     digest = names_digest(table_name, *self.fields, length=6)
     self.name = f"{table_name[:19]}_{digest}_{self.suffix}"
Beispiel #16
0
 def trigger_name(self, model, trigger_type, prefix="tr"):
     table_name = split_identifier(model._meta.db_table)[1]
     return truncate_name("{}_{}_{}".format(prefix, table_name,
                                            trigger_type.name.lower()))
Beispiel #17
0
 def test_split_identifier(self):
     self.assertEqual(split_identifier('some_table'), ('', 'some_table'))
     self.assertEqual(split_identifier('"some_table"'), ('', 'some_table'))
     self.assertEqual(split_identifier('namespace"."some_table'), ('namespace', 'some_table'))
     self.assertEqual(split_identifier('"namespace"."some_table"'), ('namespace', 'some_table'))