<commit_before>"""SQLAlchemy models."""

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.session import make_transient
from sqlalchemy.orm import sessionmaker
from sqlalchemy import (and_, create_engine, Column, ForeignKey, Integer,
                        Sequence, String)


BASE = declarative_base()


def initialize_db():
    """Initialize the DB and return SQLAlchemy Session class.

    This should only be called once when the server starts.
    """
    # hard coded might not be the best approach
    engine = create_engine('sqlite:///dbtest', echo=False)

    # create tables and prepare to make sessions
    BASE.metadata.create_all(engine)
    return sessionmaker(bind=engine)

# Counts the number of Feeds with id == feed_id, i.e., returns 0 or 1


def exists_feed(session, feed_id):
    return session.query(Feed).filter(Feed.id == feed_id).count()


class User(BASE):
    __tablename__ = 'users'

    username = Column(String, primary_key=True)
    password_hash = Column(String)

    def __init__(self, name, pwhash):
        self.username = name
        self.password_hash = <PASSWORD>

    def __repr__(self):
        return "<User('%s')>" % (self.username)

    def remove(self, session):
        # remove subscriptions for this user
        subs = session.query(
            Subscription).filter(
            Subscription.username == self.username).all()
        for sub in subs:
            session.delete(sub)
        # also remove read entries
        reads = sess.query(Read).filter(Read.username == self.username).all()
        for read in reads:
            session.delete(read)
        session.delete(self)
        make_transient(self)

    def subscribe(self, session, feed_id):
        sub = Subscription(self.username, feed_id)
        session.add(sub)

    def is_sub_of_feed(self, session, feed_id):
        return session.query(Subscription).filter(and_(
            Subscription.username == self.username,
            Subscription.feed_id == feed_id,
        )).count()

    def unsubscribe(self, session, feed_id):
        sub = session.query(
            Subscription).filter(
            and_(
                Subscription.username == self.username,
                Subscription.feed_id == feed_id)).one(
        )
        session.delete(sub)

    def mark_read(self, session, entry_id):
        read = Read(self.username, entry_id)
        session.add(read)

    def num_unread_in_feed(self, session, feed_id):
        read_ids = self.get_read_ids(session)
        if read_ids != []:
            return session.query(Entry).filter(and_(Entry.feed_id == feed_id,
                                                    ~Entry.id.in_(read_ids))).count()
        else:
            return session.query(Entry).filter(Entry.feed_id == feed_id
                                               ).count()

    def get_read_ids(self, session):
        id_list = []
        reads = session.query(
            Read).filter(
            Read.username == self.username).all(
        )
        for read in reads:
            id_list.append(read.entry_id)
        return id_list

    def get_feeds(self, session):
        id_list = []
        subs = session.query(
            Subscription).filter(
            Subscription.username == self.username).all(
        )
        for sub in subs:
            id_list.append(sub.feed_id)
        feeds = session.query(Feed).filter(Feed.id.in_(id_list)).all()
        return feeds

    """
    Collects all the entries of a feed
    precondition: is_sub_of_feed should be called prior to
                  this function call
    Input: session, Feed.id
    Ouput: dictionary -- {
                            "all_entries": list
                            "num_read": int
                         }
           the list is Entry instances,
           the read entries are in list[0:num_read-1] if any exist
    """

    def get_feed_entries(self, session, feed_id):
        # Queries
        entry_ids = []
        # Can't make this a single statement because query(Entry.id) produces
        #  a list [(1,), (2,), . . . ]
        for row in session.query(Entry).filter(
                Entry.feed_id == feed_id).all():
            entry_ids.append(row.id)
        read_ids = []
        for row in session.query(Read).filter(and_(
                Read.username == self.username, Read.entry_id.in_(entry_ids)
        )).all():
            read_ids.append(row.entry_id)
        raw_entries = session.query(Entry).filter(Entry.feed_id == feed_id
                                                  ).all()
        # Processing
        feed_entries = []
        size_read = 0
        for entry in raw_entries:
            if entry.id in read_ids:
                feed_entries.insert(size_read, entry)
                size_read += 1
            else:
                feed_entries.append(entry)

        return {"all_entries": feed_entries, "num_read": size_read}


class Feed(BASE):
    __tablename__ = 'feeds'

    id = Column(Integer, Sequence('feed_id_seq'),
                primary_key=True)
    title = Column(String)
    feed_url = Column(String)  # feed resource
    site_url = Column(String)  # main site
    last_refresh_date = Column(Integer)

    def __init__(self, title, feed_url, site_url):
        self.title = title
        self.feed_url = feed_url
        self.site_url = site_url
        #self.last_refresh_date = now()

    def __repr__(self):
        return "<RSSFeed('%s','%s')>" % (self.title, self.site_url)

    def remove(self, session):
        # check that no users are subscribed
        if session.query(Subscription).filter(
                Subscription.feed_id == self.id).count() == 0:
            # remove all associated entries
            entries = session.query(Entry).filter(
                Entry.feed_id == self.id
            ).all()
            entry_ids = []
            for entry in entries:
                entry_ids.append(entry.id)
                session.delete(entry)
            reads = session.query(Read).filter(Read.entry_id.in_(entry_ids))\
                                       .all()

            for read in reads:
                session.delete(read)

            session.delete(self)
            make_transient(self)

    def get_entries(self, session):
        return session.query(Entry).filter(Entry.feed_id == self.id).all()

    def get_users(self, session):
        name_list = []
        subs = session.query(
            Subscription).filter(
            Subscription.feed_id == self.id).all(
        )
        for sub in subs:
            name_list.append(sub.username)
        users = session.query(User).filter(User.username.in_(name_list)).all()
        return users


class Entry(BASE):
    __tablename__ = 'entries'

    id = Column(Integer, Sequence('entry_id_seq'), primary_key=True)
    feed_id = Column(Integer, ForeignKey('feeds.id'))
    content = Column(String)
    title = Column(String)
    author = Column(String)
    date = Column(Integer)
    guid = Column(String)

    def __init__(self, feed_id, content, title, author, date):
        self.feed_id = feed_id
        self.content = content
        self.title = title
        self.author = author
        self.date = date

    def __repr__(self):
        return (
            "<FeedItem('%s','%s','%s')>" % (
                    self.title, self.author, self.date)
                    )

    def remove(self, session):
        session.delete(self)
        make_transient(self)


class Subscription(BASE):
    __tablename__ = 'subscriptions'

    username = Column(
        String(50),
        ForeignKey('users.username'),
        primary_key=True)
    feed_id = Column(Integer, ForeignKey('feeds.id'), primary_key=True)

    def __init__(self, user, feed):
        self.username = user
        self.feed_id = feed

    def __repr__(self):
        return "<Subscription('%s','%s')>" % (self.username, self.feed_id)


class Read(BASE):
    __tablename__ = 'reads'

    username = Column(
        String(50),
        ForeignKey('users.username'),
        primary_key=True)
    entry_id = Column(Integer, ForeignKey('entries.id'), primary_key=True)

    def __init__(self, user, entry_id):
        self.username = user
        self.entry_id = entry_id

    def __repr__(self):
        return "<Read('%s','%s')>" % (self.username, self.entry_id)
<commit_msg>Changed sqlite db to be stored in-memory... again<commit_after>"""SQLAlchemy models."""

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.session import make_transient
from sqlalchemy.orm import sessionmaker
from sqlalchemy import (and_, create_engine, Column, ForeignKey, Integer,
                        Sequence, String)


BASE = declarative_base()


def initialize_db():
    """Initialize the DB and return SQLAlchemy Session class.

    This should only be called once when the server starts.
    """
    # hard coded might not be the best approach
    engine = create_engine('sqlite://', echo=False)

    # create tables and prepare to make sessions
    BASE.metadata.create_all(engine)
    return sessionmaker(bind=engine)

# Counts the number of Feeds with id == feed_id, i.e., returns 0 or 1


def exists_feed(session, feed_id):
    return session.query(Feed).filter(Feed.id == feed_id).count()


class User(BASE):
    __tablename__ = 'users'

    username = Column(String, primary_key=True)
    password_hash = Column(String)

    def __init__(self, name, pwhash):
        self.username = name
        self.password_hash = pwhash

    def __repr__(self):
        return "<User('%s')>" % (self.username)

    def remove(self, session):
        # remove subscriptions for this user
        subs = session.query(
            Subscription).filter(
            Subscription.username == self.username).all()
        for sub in subs:
            session.delete(sub)
        # also remove read entries
        reads = sess.query(Read).filter(Read.username == self.username).all()
        for read in reads:
            session.delete(read)
        session.delete(self)
        make_transient(self)

    def subscribe(self, session, feed_id):
        sub = Subscription(self.username, feed_id)
        session.add(sub)

    def is_sub_of_feed(self, session, feed_id):
        return session.query(Subscription).filter(and_(
            Subscription.username == self.username,
            Subscription.feed_id == feed_id,
        )).count()

    def unsubscribe(self, session, feed_id):
        sub = session.query(
            Subscription).filter(
            and_(
                Subscription.username == self.username,
                Subscription.feed_id == feed_id)).one(
        )
        session.delete(sub)

    def mark_read(self, session, entry_id):
        read = Read(self.username, entry_id)
        session.add(read)

    def num_unread_in_feed(self, session, feed_id):
        read_ids = self.get_read_ids(session)
        if read_ids != []:
            return session.query(Entry).filter(and_(Entry.feed_id == feed_id,
                                                    ~Entry.id.in_(read_ids))).count()
        else:
            return session.query(Entry).filter(Entry.feed_id == feed_id
                                               ).count()

    def get_read_ids(self, session):
        id_list = []
        reads = session.query(
            Read).filter(
            Read.username == self.username).all(
        )
        for read in reads:
            id_list.append(read.entry_id)
        return id_list

    def get_feeds(self, session):
        id_list = []
        subs = session.query(
            Subscription).filter(
            Subscription.username == self.username).all(
        )
        for sub in subs:
            id_list.append(sub.feed_id)
        feeds = session.query(Feed).filter(Feed.id.in_(id_list)).all()
        return feeds

    """
    Collects all the entries of a feed
    precondition: is_sub_of_feed should be called prior to
                  this function call
    Input: session, Feed.id
    Ouput: dictionary -- {
                            "all_entries": list
                            "num_read": int
                         }
           the list is Entry instances,
           the read entries are in list[0:num_read-1] if any exist
    """

    def get_feed_entries(self, session, feed_id):
        # Queries
        entry_ids = []
        # Can't make this a single statement because query(Entry.id) produces
        #  a list [(1,), (2,), . . . ]
        for row in session.query(Entry).filter(
                Entry.feed_id == feed_id).all():
            entry_ids.append(row.id)
        read_ids = []
        for row in session.query(Read).filter(and_(
                Read.username == self.username, Read.entry_id.in_(entry_ids)
        )).all():
            read_ids.append(row.entry_id)
        raw_entries = session.query(Entry).filter(Entry.feed_id == feed_id
                                                  ).all()
        # Processing
        feed_entries = []
        size_read = 0
        for entry in raw_entries:
            if entry.id in read_ids:
                feed_entries.insert(size_read, entry)
                size_read += 1
            else:
                feed_entries.append(entry)

        return {"all_entries": feed_entries, "num_read": size_read}


class Feed(BASE):
    __tablename__ = 'feeds'

    id = Column(Integer, Sequence('feed_id_seq'),
                primary_key=True)
    title = Column(String)
    feed_url = Column(String)  # feed resource
    site_url = Column(String)  # main site
    last_refresh_date = Column(Integer)

    def __init__(self, title, feed_url, site_url):
        self.title = title
        self.feed_url = feed_url
        self.site_url = site_url
        #self.last_refresh_date = now()

    def __repr__(self):
        return "<RSSFeed('%s','%s')>" % (self.title, self.site_url)

    def remove(self, session):
        # check that no users are subscribed
        if session.query(Subscription).filter(
                Subscription.feed_id == self.id).count() == 0:
            # remove all associated entries
            entries = session.query(Entry).filter(
                Entry.feed_id == self.id
            ).all()
            entry_ids = []
            for entry in entries:
                entry_ids.append(entry.id)
                session.delete(entry)
            reads = session.query(Read).filter(Read.entry_id.in_(entry_ids))\
                                       .all()

            for read in reads:
                session.delete(read)

            session.delete(self)
            make_transient(self)

    def get_entries(self, session):
        return session.query(Entry).filter(Entry.feed_id == self.id).all()

    def get_users(self, session):
        name_list = []
        subs = session.query(
            Subscription).filter(
            Subscription.feed_id == self.id).all(
        )
        for sub in subs:
            name_list.append(sub.username)
        users = session.query(User).filter(User.username.in_(name_list)).all()
        return users


class Entry(BASE):
    __tablename__ = 'entries'

    id = Column(Integer, Sequence('entry_id_seq'), primary_key=True)
    feed_id = Column(Integer, ForeignKey('feeds.id'))
    content = Column(String)
    title = Column(String)
    author = Column(String)
    date = Column(Integer)
    guid = Column(String)

    def __init__(self, feed_id, content, title, author, date):
        self.feed_id = feed_id
        self.content = content
        self.title = title
        self.author = author
        self.date = date

    def __repr__(self):
        return (
            "<FeedItem('%s','%s','%s')>" % (
                    self.title, self.author, self.date)
                    )

    def remove(self, session):
        session.delete(self)
        make_transient(self)


class Subscription(BASE):
    __tablename__ = 'subscriptions'

    username = Column(
        String(50),
        ForeignKey('users.username'),
        primary_key=True)
    feed_id = Column(Integer, ForeignKey('feeds.id'), primary_key=True)

    def __init__(self, user, feed):
        self.username = user
        self.feed_id = feed

    def __repr__(self):
        return "<Subscription('%s','%s')>" % (self.username, self.feed_id)


class Read(BASE):
    __tablename__ = 'reads'

    username = Column(
        String(50),
        ForeignKey('users.username'),
        primary_key=True)
    entry_id = Column(Integer, ForeignKey('entries.id'), primary_key=True)

    def __init__(self, user, entry_id):
        self.username = user
        self.entry_id = entry_id

    def __repr__(self):
        return "<Read('%s','%s')>" % (self.username, self.entry_id)

{'fraction_non_alphanumeric': 0.10924169202314897, 'fraction_numerical': 0.001551220094266452, 'mean_word_length': 2.01095742769894, 'pattern_counts': {'":': 8, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '493386', 'n_tokens_mistral': 4900, 'n_tokens_neox': 4728, 'n_words': 1089}