from contextlib import contextmanager
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import func

from .errors import ServerError

db = SQLAlchemy()

@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = db.session()
    try:
        yield session
        session.commit()
    except Exception as e:
        session.rollback()
        raise e
    finally:
        session.close()

@contextmanager
def db_safety():
    try:
        with session_scope() as session:
            yield session
    except Exception as e:
        raise ServerError()

class Account(db.Model):
    __tablename__ = 'accounts'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30), unique=True)
    public_key = db.Column(db.String(68))

    @staticmethod
    def lookup_from_username(username):
        return Account.query.filter(func.lower(Account.username) == func.lower(username)).first()

    @staticmethod
    def create(session, username, public_key):
        new_account = Account(username, public_key)
        session.add(new_account)
        session.flush()

        return new_account.id

    def __init__(self, username, public_key):
        self.username = username
        self.public_key = public_key

class Event(db.Model):
    __tablename__ = 'events'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True)
    start = db.Column(db.DateTime())
    end = db.Column(db.DateTime())
    description = db.Column(db.String(1000))

    @staticmethod
    def create(session, name, start, end, description):
        new_event = Event(username, public_key)
        session.add(new_event)
        session.flush()

        return new_event.id

    def __init__(self, name, start, end, description):
        self.name = name
        self.start = start
        self.end = end
        self.description = description

@@ -1943,12 +1943,586 @@
 description%0A
+%0Aclass Attendees(db.Model):%0A    __tablename__ = 'attendees'%0A%0A    id = db.Column(db.Integer, primary_key=True)%0A    event_id = db.Column(db.Integer(), db.ForeignKey('events.id'))%0A    account_id = db.Column(db.Integer(), db.ForeignKey('accounts.id'))%0A%0A    @staticmethod%0A    def create(session, event_id, account_id):%0A        new_attendee = Account(event_id, account_id)%0A        session.add(new_attendee)%0A        session.flush()%0A%0A        return new_attendee.id%0A%0A    def __init__(self, event_id, account_id):%0A        self.event_id = event_id%0A        self.account_id = account_id%0A

Add attendee table to map guests to events.