Example #1
0
    def test_get_columns_using_enumerator(self,
                                          database: PostgresqlExtDatabase,
                                          database_table: Tuple[str, str]):
        enum_name = TEST_ENUM_NAME

        enumerators.create_enumerator(enum_name)

        columns = enumerators.get_columns_used_by_enumerator(enum_name)
        assert len(columns) == 0

        schema_name = database_table[0]
        table_name = database_table[1]
        column_name = "test_column"

        sql_add_column = f"ALTER TABLE {schema_name}.{table_name} ADD COLUMN {column_name} {enum_name}"
        database.execute_sql(sql_add_column)

        columns = enumerators.get_columns_used_by_enumerator(enum_name)

        assert len(columns) == 1
        expected_data = {
            "schema_name": schema_name,
            "table_name": table_name,
            "column_name": column_name
        }
        assert columns[0] == expected_data

        assert enumerators.is_enumerator_used_by_any_column(enum_name) is True
Example #2
0
    def test_create_and_drop_enumerator(self, database: PostgresqlExtDatabase):
        enum_name = TEST_ENUM_NAME

        enumerators.create_enumerator(enum_name)

        enumerators.drop_enumerator(enum_name)

        sql_select = self.build_select_enum_sql(enum_name)
        cursor = database.execute_sql(sql_select)

        rows = cursor.fetchall()
        assert len(rows) == 0
Example #3
0
    def test_create_enumerator_duplicate(self,
                                         database: PostgresqlExtDatabase):
        enum_name = TEST_ENUM_NAME

        enumerators.create_enumerator(enum_name)

        with pytest.raises(peewee.ProgrammingError):
            enumerators.create_enumerator(enum_name)

        sql_select = self.build_select_enum_sql(enum_name)
        cursor = database.execute_sql(sql_select)

        rows = cursor.fetchall()
        assert len(rows) == 1
Example #4
0
    def test_create_enumerator_string_values(self,
                                             database: PostgresqlExtDatabase):
        enum_name = TEST_ENUM_NAME
        enum_values = ("v1", "v2", "v3")

        enumerators.create_enumerator(enum_name, enum_values)

        sql_select = self.build_select_enum_sql(enum_name)
        cursor = database.execute_sql(sql_select)

        rows = cursor.fetchall()
        assert len(rows) == 1

        actual_values = self.get_enum_values(database, enum_name)

        assert actual_values == enum_values
Example #5
0
    def test_drop_enumerator_which_is_used_by_columns(
            self, database: PostgresqlExtDatabase, database_table: Tuple[str,
                                                                         str]):
        enum_name = TEST_ENUM_NAME

        enumerators.create_enumerator(enum_name)

        schema_name = database_table[0]
        table_name = database_table[1]
        column_name = "test_column"

        sql_add_column = f"ALTER TABLE {schema_name}.{table_name} ADD COLUMN {column_name} {enum_name}"
        database.execute_sql(sql_add_column)

        with pytest.raises(peewee.InternalError):
            enumerators.drop_enumerator(enum_name)
Example #6
0
    def test_is_enumerator_used_by_any_column(self,
                                              database: PostgresqlExtDatabase,
                                              database_table: Tuple[str, str]):
        enum_name = TEST_ENUM_NAME

        enumerators.create_enumerator(enum_name)

        assert enumerators.is_enumerator_used_by_any_column(enum_name) is False

        schema_name = database_table[0]
        table_name = database_table[1]
        column_name = "test_column"

        sql_add_column = f"ALTER TABLE {schema_name}.{table_name} ADD COLUMN {column_name} {enum_name}"
        database.execute_sql(sql_add_column)

        assert enumerators.is_enumerator_used_by_any_column(enum_name) is True
Example #7
0
    def add_dict_column(self, column_name: str, values: List[Any] = None):
        if self.column_exists(column_name):
            raise ValueError("column exists")

        values = [] or values

        if not Dict.dict_values_length_valid(values):
            raise ValueError('dict value must be 63 characters or less')

        with self.db.atomic():
            enumerator_name = f"{column_name}_{uuid.uuid4()}"
            enumerator_name = enumerator_name.replace("-", "_")
            enumerators.create_enumerator(enumerator_name, values)

            sql = SQL("ALTER TABLE {} ADD COLUMN {} {};").format(
                Identifier(self.name), Identifier(column_name),
                SQL(enumerator_name))

            Dict.create(layer_id=self.lid,
                        column_name=column_name,
                        enumerator_name=enumerator_name)

            self.execute(sql)
Example #8
0
    def set_values(self, values: List[Any]):
        cloud = get_cloud()
        table_name = cloud.unhash_name(self.layer_id)

        current_values = set(enumerators.get_values_of_enumerator(self.enumerator_name))

        values_to_be_removed = current_values - set(values)

        sql_set_type_to_text = psysql.SQL("ALTER TABLE {} ALTER COLUMN {} TYPE TEXT").format(
            psysql.Identifier(table_name), psysql.Identifier(self.column_name)
        )

        values_to_be_removed_sql = [psysql.Literal(str(value)) for value in values_to_be_removed]

        sql_set_null = psysql.SQL("UPDATE {table_name} SET {column_name} = NULL WHERE {column_name} IN ({values})").format(
            table_name=psysql.Identifier(table_name),
            column_name=psysql.Identifier(self.column_name),
            values=psysql.SQL(",").join(values_to_be_removed_sql)
        )
        sql_drop_old_enumerator = psysql.SQL("DROP TYPE {}").format(psysql.Identifier(self.enumerator_name))
        sql_set_type_to_enumerator = psysql.SQL("""ALTER TABLE {table_name} ALTER COLUMN {column_name} 
                                     TYPE {enumerator_name} USING {column_name}::{enumerator_name}""").format(
            table_name=psysql.Identifier(table_name), column_name=psysql.Identifier(self.column_name),
            enumerator_name=psysql.Identifier(self.enumerator_name)
        )

        db = self._meta.database
        with db.atomic():
            db.execute_sql(sql_set_type_to_text)
            db.execute_sql(sql_drop_old_enumerator)

            if len(values_to_be_removed) > 0:
                db.execute_sql(sql_set_null)

            enumerators.create_enumerator(self.enumerator_name, values)
            db.execute_sql(sql_set_type_to_enumerator)