view backend/sqlalchemy/SqlAlchemyBackend.py @ 205:adf7f617bda9

make the name of the design document configurable via command line switch. When cloning the feedworm db, the design document is no longer the same as the database name
author dirk
date Sat, 02 Jun 2012 04:24:49 +0200
parents 7157bfd3f4d4
children bb3c851b18b1
line wrap: on
line source


from Feed import Feed
from FeedEntry import FeedEntry
from FeedUpdater import FeedUpdater
from Preferences import Preferences
from backend.AbstractBackend import AbstractBackend
from sqlalchemy.orm import joinedload
from sqlalchemy.sql import and_
import Database
import Mapping
import logging
import util

class SqlAlchemyBackend(AbstractBackend):
    '''
    Backend that uses sqlalchemy for persistence
    '''

    def __init__(self):
        AbstractBackend.__init__(self)
        self._initLogging()
        self.session = Database.createSession()
        self.prefs = Preferences(self.session)
        self.updater = None

    def _initLogging(self):
        logging.getLogger("sqlalchemy.orm").setLevel(logging.WARN)

        sqlalchemyLogLevel = logging.ERROR
        if util.databaseLoggingEnabled():
            sqlalchemyLogLevel = logging.INFO
        logging.getLogger("sqlalchemy").setLevel(sqlalchemyLogLevel)

    def preferences(self):
        return self.prefs

    def dispose(self):
        # save all uncommitted state, just in case
        self.session.commit()
        self.session.close()

    #
    # handling of feeds
    #

    def getFeeds(self):
        if self.preferences().showOnlyUnreadFeeds():
            self.feeds = self._getUnreadFeeds()
        else:
            self.feeds = Feed.all(self.session)
        return self.feeds

    def _getUnreadFeeds(self):
        query = self.session.query(FeedEntry).filter(FeedEntry.read == 0)
        queryWithOptions = query.options(joinedload("feed"))
        result = queryWithOptions.all()
        return self._collectFeeds(result)

    def _collectFeeds(self, feedEntries):
        feeds = [entry.feed for entry in feedEntries]
        uniqueFeeds = set(feeds)
        return list(uniqueFeeds)

    def _retrieveEntriesForSelectedFeed(self, hideReadEntries):
        return self.selectedFeed.entriesSortedByUpdateDate(hideReadEntries)

    def deleteSelectedFeed(self):
        self.session.delete(self.selectedFeed)
        self.session.commit()

    def createFeed(self, url):
        try:
            newFeed = Feed(url)
            self.session.add(newFeed)

            FeedUpdater(self.preferences(), self.session).update(newFeed)
            self.session.commit()
        except AttributeError as ae:
            self.session.rollback()
            raise ae

    def updateAllFeeds(self):
        FeedUpdater.updateAllFeeds(self.preferences(), self.session)
        self.session.commit()

    def updateFeed(self, feed, changes):
        feed.takeChangesFrom(changes)
        feed.incrementNextUpdateDate()
        self.session.commit()

    #
    # handling of the selected feed entry
    #

    def _markSelectedFeedEntryRead(self):
        self.selectedFeedEntry.markRead()

    def markFeedEntriesAsRead(self, indices):
        for index in indices:
            self.feedEntries[index].markRead()
        self.session.commit()

    def toggleSelectedFeedEntryRead(self):
        self.selectedFeedEntry.toggleRead()
        self.session.commit()

    def expireFeedEntries(self):
        logger = logging.getLogger("feedupdater")
        expireDate = self._calculateExpireDate()
        logger.info("expiring entries older than " + str(expireDate))
        feedEntry = Mapping.feedEntryTable
        deleteStatement = feedEntry.delete().where(
            and_(feedEntry.c.create_timestamp < expireDate, feedEntry.c.read == 1)
        )
        deleteStatement.execute()
        self.session.commit()