content=u'not a name'
            )
        ]
        self.session.add_all(self.items)
        self.session.commit()

    def teardown_method(self, method):
        TestCase.teardown_method(self, method)
        search_manager.options['regconfig'] = 'pg_catalog.english'

    def test_uses_global_regconfig_as_fallback(self):
        query = search(self.session.query(self.TextItem.id), 'the')
        assert query.count() == 1


create_test_cases(SearchQueryMixinTestCase)


class TestSearchableInheritance(TestCase):
    def setup_method(self, method):
        TestCase.setup_method(self, method)
        self.session.add(self.Article(name=u'index', content=u'some content'))
        self.session.add(self.Article(name=u'admin', content=u'admin content'))
        self.session.add(
            self.Article(name=u'home', content=u'this is the home page')
        )
        self.session.commit()

    def test_supports_inheritance(self):
        assert (
            self.TextItemQuery(self.Article, self.session)
Esempio n. 2
0
        Article.primary_tags = sa.orm.relationship(
            Tag,
            primaryjoin=sa.and_(Tag.article_id == Article.id,
                                Tag.category == u'primary'),
        )

        Article.secondary_tags = sa.orm.relationship(
            Tag,
            primaryjoin=sa.and_(Tag.article_id == Article.id,
                                Tag.category == u'secondary'),
        )

        self.Article = Article
        self.Tag = Tag

    def test_relationship_condition_reflection(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        article.primary_tags.append(
            self.Tag(name=u'tag #1', category=u'primary'))
        article.secondary_tags.append(
            self.Tag(name=u'tag #2', category=u'secondary'))
        self.session.add(article)
        self.session.commit()
        assert article.versions[0].primary_tags
        assert article.versions[0].secondary_tags


create_test_cases(CustomConditionRelationsTestCase)
            ['name', 'content'],
            metadata=self.Base.metadata
        )
        conn.execute(
            '''INSERT INTO article (name, content)
            VALUES ('some name', 'some bad content')'''
        )
        vector = conn.execute('SELECT search_vector FROM article').scalar()
        assert vector == "'content':5 'good':4 'name':2"

    def test_trigger_with_reserved_word(self):
        conn = self.session.bind
        conn.execute(
            '''INSERT INTO article (name, content, "current_user")
            VALUES ('some name', 'some bad content', now())'''
        )

        sync_trigger(
            conn,
            'article',
            'search_vector',
            ['name', 'content', 'current_user']
        )
        # raises ProgrammingError without reserved_words:
        conn.execute(
            '''UPDATE article SET name=name'''
        )


create_test_cases(SyncTriggerTestCase)
from sqlalchemy_continuum import tx_column_name, version_class

from tests import TestCase, create_test_cases


setting_variants = {
    'transaction_column_name': ['transaction_id', 'tx_id'],
}


class TxColumnNameTestCase(TestCase):
    def test_with_version_class(self):
        assert tx_column_name(version_class(self.Article)) == self.options[
            'transaction_column_name'
        ]

    def test_with_version_obj(self):
        history_obj = version_class(self.Article)()
        assert tx_column_name(history_obj) == self.options[
            'transaction_column_name'
        ]

    def test_with_versioned_class(self):
        assert tx_column_name(self.Article) == self.options[
            'transaction_column_name'
        ]


create_test_cases(TxColumnNameTestCase, setting_variants=setting_variants)
    def test_delete(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        tag = self.Tag(name=u'some tag')
        article.tags.append(tag)
        self.session.add(article)
        self.session.commit()
        self.session.delete(tag)
        article.name = u'Updated article'
        self.session.commit()
        assert len(article.versions[0].tags) == 1
        assert len(article.versions[1].tags) == 0


create_test_cases(OneToManyRelationshipsTestCase)


class TestOneToManyWithUseListFalse(TestCase):
    def create_models(self):
        class Article(self.Model):
            __tablename__ = 'article'
            __versioned__ = {}

            id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
            name = sa.Column(sa.Unicode(255), nullable=False)
            content = sa.Column(sa.UnicodeText)
            description = sa.Column(sa.UnicodeText)

        class Category(self.Model):
            __tablename__ = 'category'
    def test_multiple_inserts_in_consecutive_transactions(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        tag = self.Tag(name=u'some tag')
        article.tags.append(tag)
        self.session.add(article)
        self.session.commit()
        article.tags.append(self.Tag(name=u'other tag'))
        article.name = u'Updated article'
        self.session.commit()
        assert article.versions[0].tags.count() == 1
        assert article.versions[1].tags.count() == 2

    def test_delete(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        tag = self.Tag(name=u'some tag')
        article.tags.append(tag)
        self.session.add(article)
        self.session.commit()
        self.session.delete(tag)
        article.name = u'Updated article'
        self.session.commit()
        assert article.versions[0].tags.count() == 1
        assert article.versions[1].tags.count() == 0


create_test_cases(OneToManyRelationshipsTestCase)
        self.session.commit()
        article.name = u'Updated article'
        self.session.commit()
        assert article.versions.count() == 2

        assert self.session.execute(
            'SELECT %s FROM text_item_version '
            'ORDER BY %s LIMIT 1' % (end_tx_column, tx_column)
        ).scalar()
        assert self.session.execute(
            'SELECT %s FROM article_version '
            'ORDER BY %s LIMIT 1' % (end_tx_column, tx_column)
        ).scalar()


create_test_cases(JoinTableInheritanceTestCase)


class TestDeepJoinedTableInheritance(TestCase):
    def create_models(self):
        class Node(self.Model):
            __versioned__ = {}
            __tablename__ = 'node'
            __mapper_args__ = dict(
                polymorphic_on='type',
                polymorphic_identity='node',
                with_polymorphic='*',
            )

            id = sa.Column(sa.Integer, primary_key=True)
            type = sa.Column(sa.String(30), nullable=False)
        assert user.versions[2].previous
        assert user.versions[1].previous
        assert user.versions[2].previous == user.versions[1]
        assert user.versions[1].previous == user.versions[0]

    def test_next_two_versions(self):
        user = self.User()
        user.first_name = u'Some user'
        user.last_name = u'Some last_name'
        self.session.add(user)
        self.session.commit()
        user2 = self.User()
        user2.first_name = u'Second user'
        user2.last_name = u'Second user'
        self.session.add(user2)
        self.session.commit()

        user.email = u'Updated user'
        self.session.commit()
        user.email = u'Updated user 2'
        self.session.commit()

        assert user.versions[0].next
        assert user.versions[1].next
        assert user.versions[0].next == user.versions[1]
        assert user.versions[1].next == user.versions[2]


create_test_cases(VersionModelAccessorsTestCase)
create_test_cases(VersionModelAccessorsWithCompositePkTestCase)
Esempio n. 9
0
    def test_drops_triggers_and_functions(self):
        conn = self.session.bind
        sync_trigger(conn, 'article', 'search_vector', ['name', 'content'])

        def trigger_exist():
            return conn.execute("""SELECT COUNT(*)
                   FROM pg_trigger
                   WHERE tgname='article_search_vector_trigger'
                """).scalar()

        def function_exist():
            return conn.execute("""SELECT COUNT(*)
                   FROM pg_proc
                   WHERE proname='article_search_vector_update'
                   """).scalar()

        assert trigger_exist() == 1
        assert function_exist() == 1

        drop_trigger(
            conn,
            'article',
            'search_vector',
        )

        assert trigger_exist() == 0
        assert function_exist() == 0


create_test_cases(DropTriggerTestCase)
                'base_classes': (self.Model, )
            }

            id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
            name = sa.Column(sa.Unicode(255))
            articles = relationship('Article', secondary=published_articles_table)

        self.Author = Author

    def test_version_relations(self):
        article = self.Article()
        name = u'Some article'
        article.name = name
        article.content = u'Some content'
        self.session.add(article)
        self.session.commit()
        assert article.versions[0].name == name

        au = self.Author(name=u'Some author')
        self.session.add(au)
        self.session.commit()

        pa = self.PublishedArticle(article_id=article.id, author_id=au.id)
        self.session.add(pa)

        self.session.commit()



create_test_cases(AssociationTableRelationshipsTestCase)
        assert user.versions[2].previous
        assert user.versions[1].previous
        assert user.versions[2].previous == user.versions[1]
        assert user.versions[1].previous == user.versions[0]

    def test_next_two_versions(self):
        user = self.User()
        user.first_name = u'Some user'
        user.last_name = u'Some last_name'
        self.session.add(user)
        self.session.commit()
        user2 = self.User()
        user2.first_name = u'Second user'
        user2.last_name = u'Second user'
        self.session.add(user2)
        self.session.commit()

        user.email = u'Updated user'
        self.session.commit()
        user.email = u'Updated user 2'
        self.session.commit()

        assert user.versions[0].next
        assert user.versions[1].next
        assert user.versions[0].next == user.versions[1]
        assert user.versions[1].next == user.versions[2]


create_test_cases(VersionModelAccessorsTestCase)
create_test_cases(VersionModelAccessorsWithCompositePkTestCase)
Esempio n. 12
0
        assert self.ArticleVersion.__table__.name == 'text_item_version'
        assert self.BlogPostVersion.__table__.name == 'text_item_version'

    def test_each_object_has_distinct_version_class(self):
        article = self.Article()
        blogpost = self.BlogPost()
        textitem = self.TextItem()

        self.session.add(article)
        self.session.add(blogpost)
        self.session.add(textitem)
        self.session.commit()

        assert type(textitem.versions[0]) == self.TextItemVersion
        assert type(article.versions[0]) == self.ArticleVersion
        assert type(blogpost.versions[0]) == self.BlogPostVersion

    def test_transaction_changed_entities(self):
        article = self.Article()
        article.name = u'Text 1'
        self.session.add(article)
        self.session.commit()
        Transaction = versioning_manager.transaction_cls
        transaction = (self.session.query(Transaction).order_by(
            sa.sql.expression.desc(Transaction.issued_at))).first()
        assert transaction.entity_names == [u'Article']
        assert transaction.changed_entities


create_test_cases(SingleTableInheritanceTestCase)
                'base_classes': (self.Model, )
            }

            id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
            name = sa.Column(sa.Unicode(255))
            articles = relationship('Article', secondary=published_articles_table)

        self.Author = Author

    def test_version_relations(self):
        article = self.Article()
        name = u'Some article'
        article.name = name
        article.content = u'Some content'
        self.session.add(article)
        self.session.commit()
        assert article.versions[0].name == name

        au = self.Author(name=u'Some author')
        self.session.add(au)
        self.session.commit()

        pa = self.PublishedArticle(article_id=article.id, author_id=au.id)
        self.session.add(pa)

        self.session.commit()



create_test_cases(AssociationTableRelationshipsTestCase)
        article.name = u'updated article x2'
        self.session.commit()

        assert len(article.versions[0].tags) == 1
        assert article.versions[0].tags[0] is tag1.versions[0]

        assert len(article.versions[1].tags) == 2
        assert tag1.versions[1] in article.versions[1].tags
        assert tag2.versions[0] in article.versions[1].tags

        assert len(article.versions[2].tags) == 2
        assert tag1.versions[2] in article.versions[2].tags
        assert tag2.versions[0] in article.versions[2].tags


create_test_cases(ManyToManyRelationshipsTestCase)


class TestManyToManyRelationshipWithViewOnly(TestCase):
    def create_models(self):
        class Article(self.Model):
            __tablename__ = 'article'
            __versioned__ = {'base_classes': (self.Model, )}

            id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
            name = sa.Column(sa.Unicode(255))

        article_tag = sa.Table(
            'article_tag', self.Model.metadata,
            sa.Column(
                'article_id',
        article2 = self.Article()
        article2.name = u'Another article'
        article2.content = u'Some other content'
        self.session.add(article)
        self.session.add(article2)
        self.session.commit()

        self.session.delete(article)
        self.session.flush()

        article2.id = article.id
        self.session.commit()
        assert article2.versions.count() == 2
        assert article2.versions[0].operation_type == 0
        assert article2.versions[1].operation_type == 1

    def test_insert_flushed_object(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        self.session.add(article)
        self.session.flush()
        self.session.commit()

        assert article.versions.count() == 1
        assert article.versions[0].operation_type == 0


# Skip the tests until SQLAlchemy has renewed its UOW handling:
create_test_cases(ExoticOperationCombosTestCase)
        def trigger_exist():
            return conn.execute(
                """SELECT COUNT(*)
                   FROM pg_trigger
                   WHERE tgname = 'article_search_vector_trigger'
                """
            ).scalar()

        def function_exist():
            return conn.execute(
                """SELECT COUNT(*)
                   FROM pg_proc
                   WHERE proname = 'article_search_vector_update'
                   """
            ).scalar()

        assert trigger_exist() == 1
        assert function_exist() == 1

        drop_trigger(
            conn,
            'article',
            'search_vector',
        )

        assert trigger_exist() == 0
        assert function_exist() == 0


create_test_cases(DropTriggerTestCase)
Esempio n. 17
0
from sqlalchemy_continuum import tx_column_name, version_class

from tests import TestCase, create_test_cases

setting_variants = {
    'transaction_column_name': ['transaction_id', 'tx_id'],
}


class TxColumnNameTestCase(TestCase):
    def test_with_version_class(self):
        assert tx_column_name(version_class(
            self.Article)) == self.options['transaction_column_name']

    def test_with_version_obj(self):
        history_obj = version_class(self.Article)()
        assert tx_column_name(
            history_obj) == self.options['transaction_column_name']

    def test_with_versioned_class(self):
        assert tx_column_name(
            self.Article) == self.options['transaction_column_name']


create_test_cases(TxColumnNameTestCase, setting_variants=setting_variants)
        self.session.add(item)
        self.session.commit()
        item.name = u'Some other thing'
        self.session.commit()
        item.versions[0].revert()
        self.session.commit()

    def test_previous_for_deleted_parent(self):
        item = self.TextItem()
        item.name = u'Some item'
        item.content = u'Some content'
        self.session.add(item)
        self.session.commit()
        self.session.delete(item)
        self.session.commit()
        TextItemVersion = version_class(self.TextItem)

        versions = (
            self.session.query(TextItemVersion)
            .order_by(
                getattr(
                    TextItemVersion,
                    self.options['transaction_column_name']
                )
            )
        ).all()
        assert versions[1].previous.name == u'Some item'


create_test_cases(ColumnAliasesTestCase)
        article2 = self.Article()
        article2.name = u'Another article'
        article2.content = u'Some other content'
        self.session.add(article)
        self.session.add(article2)
        self.session.commit()

        self.session.delete(article)
        self.session.flush()

        article2.id = article.id
        self.session.commit()
        assert article2.versions.count() == 2
        assert article2.versions[0].operation_type == 0
        assert article2.versions[1].operation_type == 1

    def test_insert_flushed_object(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        self.session.add(article)
        self.session.flush()
        self.session.commit()

        assert article.versions.count() == 1
        assert article.versions[0].operation_type == 0


# Skip the tests until SQLAlchemy has renewed its UOW handling:
create_test_cases(ExoticOperationCombosTestCase)
Esempio n. 20
0
        sync_trigger(conn, 'article', 'search_vector', ['name', 'content'])
        conn.execute('''INSERT INTO article (name, content)
            VALUES ('some name', 'some content')''')
        conn.execute('ALTER TABLE article DROP COLUMN name')
        sync_trigger(conn, 'article', 'search_vector', ['content'])
        vector = conn.execute('SELECT search_vector FROM article').scalar()
        assert vector == "'content':2"

    def test_custom_vectorizers(self):
        articles = sa.Table('article',
                            self.Base.metadata,
                            autoload=True,
                            autoload_with=self.session.bind)

        @vectorizer(articles.c.content)
        def vectorize_content(column):
            return sa.func.replace(column, 'bad', 'good')

        conn = self.session.bind
        sync_trigger(conn,
                     'article',
                     'search_vector', ['name', 'content'],
                     metadata=self.Base.metadata)
        conn.execute('''INSERT INTO article (name, content)
            VALUES ('some name', 'some bad content')''')
        vector = conn.execute('SELECT search_vector FROM article').scalar()
        assert vector == "'content':5 'good':4 'name':2"


create_test_cases(SyncTriggerTestCase)
        article.name = u'updated article x2'
        self.session.commit()

        assert len(article.versions[0].tags) == 1
        assert article.versions[0].tags[0] is tag1.versions[0]

        assert len(article.versions[1].tags) == 2
        assert tag1.versions[1] in article.versions[1].tags
        assert tag2.versions[0] in article.versions[1].tags

        assert len(article.versions[2].tags) == 2
        assert tag1.versions[2] in article.versions[2].tags
        assert tag2.versions[0] in article.versions[2].tags


create_test_cases(ManyToManyRelationshipsTestCase)


class TestManyToManyRelationshipWithViewOnly(TestCase):
    def create_models(self):
        class Article(self.Model):
            __tablename__ = 'article'
            __versioned__ = {
                'base_classes': (self.Model, )
            }

            id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
            name = sa.Column(sa.Unicode(255))

        article_tag = sa.Table(
            'article_tag',
Esempio n. 22
0
        article = self.Article()
        self.session.add(article)
        self.session.commit()
        article.name = u'Updated article'
        self.session.commit()
        assert article.versions.count() == 2

        assert self.session.execute('SELECT %s FROM text_item_version '
                                    'ORDER BY %s LIMIT 1' %
                                    (end_tx_column, tx_column)).scalar()
        assert self.session.execute('SELECT %s FROM article_version '
                                    'ORDER BY %s LIMIT 1' %
                                    (end_tx_column, tx_column)).scalar()


create_test_cases(JoinTableInheritanceTestCase)


class TestDeepJoinedTableInheritance(TestCase):
    def create_models(self):
        class Node(self.Model):
            __versioned__ = {}
            __tablename__ = 'node'
            __mapper_args__ = dict(
                polymorphic_on='type',
                polymorphic_identity='node',
                with_polymorphic='*',
            )

            id = sa.Column(sa.Integer, primary_key=True)
            type = sa.Column(sa.String(30), nullable=False)
    def test_each_object_has_distinct_version_class(self):
        article = self.Article()
        blogpost = self.BlogPost()
        textitem = self.TextItem()

        self.session.add(article)
        self.session.add(blogpost)
        self.session.add(textitem)
        self.session.commit()

        assert type(textitem.versions[0]) == self.TextItemVersion
        assert type(article.versions[0]) == self.ArticleVersion
        assert type(blogpost.versions[0]) == self.BlogPostVersion

    def test_transaction_changed_entities(self):
        article = self.Article()
        article.name = u'Text 1'
        self.session.add(article)
        self.session.commit()
        Transaction = versioning_manager.transaction_cls
        transaction = (
            self.session.query(Transaction)
            .order_by(sa.sql.expression.desc(Transaction.issued_at))
        ).first()
        assert transaction.entity_names == [u'Article']
        assert transaction.changed_entities


create_test_cases(SingleTableInheritanceTestCase)
        self.session.add(item)
        self.session.commit()
        assert item.versions[0].name == u'Something'

    def test_revert(self):
        item = self.TextItem(name=u'Something')
        self.session.add(item)
        self.session.commit()
        item.name = u'Some other thing'
        self.session.commit()
        item.versions[0].revert()
        self.session.commit()

    def test_previous_for_deleted_parent(self):
        item = self.TextItem()
        item.name = u'Some item'
        item.content = u'Some content'
        self.session.add(item)
        self.session.commit()
        self.session.delete(item)
        self.session.commit()
        TextItemVersion = version_class(self.TextItem)

        versions = (self.session.query(TextItemVersion).order_by(
            getattr(TextItemVersion,
                    self.options['transaction_column_name']))).all()
        assert versions[1].previous.name == u'Some item'


create_test_cases(ColumnAliasesTestCase)
        )

        Article.secondary_tags = sa.orm.relationship(
            Tag,
            primaryjoin=sa.and_(
                Tag.article_id == Article.id,
                Tag.category == u'secondary'
            ),
        )

        self.Article = Article
        self.Tag = Tag

    def test_relationship_condition_reflection(self):
        article = self.Article()
        article.name = u'Some article'
        article.content = u'Some content'
        article.primary_tags.append(
            self.Tag(name=u'tag #1', category=u'primary')
        )
        article.secondary_tags.append(
            self.Tag(name=u'tag #2', category=u'secondary')
        )
        self.session.add(article)
        self.session.commit()
        assert article.versions[0].primary_tags
        assert article.versions[0].secondary_tags


create_test_cases(CustomConditionRelationsTestCase)