# Path: src/petmail/eventual.py
# def flushEventualQueue(value=None):
#     """This returns a Deferred which fires when the eventual-send queue is
#     finally empty. This is useful to wait upon as the last step of a Trial
#     test method. If an argument is provided, the Deferred will fire with it,
#     making this useful at the end of a unit test:
# 
#         d = some_stuff_that_uses_eventual_sends()
#         d.addBoth(flushEventualQueue)
#         return d
#     """
#     d = _theSimpleQueue.flush()
#     d.addBoth(lambda _: value)
#     return d
# 
# Path: src/petmail/database.py
# def get_db(dbfile, stderr=sys.stderr):
#     """Open or create the given db file. The parent directory must exist.
#     Returns the db connection object, or raises DBError.
#     """
# 
#     must_create = not os.path.exists(dbfile)
#     try:
#         db = sqlite3.connect(dbfile)
#     except (EnvironmentError, sqlite3.OperationalError), e:
#         raise DBError("Unable to create/open db file %s: %s" % (dbfile, e))
#     db.row_factory = sqlite3.Row
# 
#     VERSION = 1
#     if must_create:
#         schema = get_schema(VERSION)
#         db.executescript(schema)
#         db.execute("INSERT INTO version (version) VALUES (?)", (VERSION,))
#         db.commit()
# 
#     try:
#         version = db.execute("SELECT version FROM version").fetchone()[0]
#     except sqlite3.DatabaseError, e:
#         # this indicates that the file is not a compatible database format.
#         # Perhaps it was created with an old version, or it might be junk.
#         raise DBError("db file is unusable: %s" % e)
# 
#     if version != VERSION:
#         raise DBError("Unable to handle db version %s" % version)
# 
#     return db
# 
# def make_observable_db(dbfile, stderr=sys.stderr):
#     return ObservableDatabase(get_db(dbfile, stderr))
# 
# class DBError(Exception):
#     pass


import os.path
from twisted.trial import unittest
from common import BasedirMixin
from ..eventual import flushEventualQueue
from ..database import get_db, make_observable_db, DBError

class Database(BasedirMixin, unittest.TestCase):
    def test_create(self):
        basedir = self.make_basedir()
        dbfile = os.path.join(basedir, "test.db")
        db = get_db(dbfile)

        row = db.execute("SELECT * FROM version").fetchone()
        self.failUnlessEqual(row["version"], 1)

    def test_create_failure(self):
        bad_dbfile = "missing/directory/test.db"
        err = self.failUnlessRaises(DBError, get_db, bad_dbfile)
        self.failUnlessIn("Unable to create/open db file", str(err))
        self.failUnlessIn("unable to open database file", str(err))

    def test_versions(self):
        basedir = self.make_basedir()
        dbfile = os.path.join(basedir, "test.db")
        db = get_db(dbfile)

        db.execute("UPDATE version SET version=2")
        db.commit()

# Path: src/petmail/eventual.py
# def flushEventualQueue(value=None):
#     """This returns a Deferred which fires when the eventual-send queue is
#     finally empty. This is useful to wait upon as the last step of a Trial
#     test method. If an argument is provided, the Deferred will fire with it,
#     making this useful at the end of a unit test:
# 
#         d = some_stuff_that_uses_eventual_sends()
#         d.addBoth(flushEventualQueue)
#         return d
#     """
#     d = _theSimpleQueue.flush()
#     d.addBoth(lambda _: value)
#     return d
# 
# Path: src/petmail/database.py
# def get_db(dbfile, stderr=sys.stderr):
#     """Open or create the given db file. The parent directory must exist.
#     Returns the db connection object, or raises DBError.
#     """
# 
#     must_create = not os.path.exists(dbfile)
#     try:
#         db = sqlite3.connect(dbfile)
#     except (EnvironmentError, sqlite3.OperationalError), e:
#         raise DBError("Unable to create/open db file %s: %s" % (dbfile, e))
#     db.row_factory = sqlite3.Row
# 
#     VERSION = 1
#     if must_create:
#         schema = get_schema(VERSION)
#         db.executescript(schema)
#         db.execute("INSERT INTO version (version) VALUES (?)", (VERSION,))
#         db.commit()
# 
#     try:
#         version = db.execute("SELECT version FROM version").fetchone()[0]
#     except sqlite3.DatabaseError, e:
#         # this indicates that the file is not a compatible database format.
#         # Perhaps it was created with an old version, or it might be junk.
#         raise DBError("db file is unusable: %s" % e)
# 
#     if version != VERSION:
#         raise DBError("Unable to handle db version %s" % version)
# 
#     return db
# 
# def make_observable_db(dbfile, stderr=sys.stderr):
#     return ObservableDatabase(get_db(dbfile, stderr))
# 
# class DBError(Exception):
#     pass


# Path: src/petmail/test/test_database.py
import os.path
from twisted.trial import unittest
from common import BasedirMixin
from ..eventual import flushEventualQueue
from ..database import get_db, make_observable_db, DBError


class Database(BasedirMixin, unittest.TestCase):
    def test_create(self):
        basedir = self.make_basedir()
        dbfile = os.path.join(basedir, "test.db")
        db = get_db(dbfile)

        row = db.execute("SELECT * FROM version").fetchone()
        self.failUnlessEqual(row["version"], 1)

    def test_create_failure(self):
        bad_dbfile = "missing/directory/test.db"
        err = self.failUnlessRaises(DBError, get_db, bad_dbfile)
        self.failUnlessIn("Unable to create/open db file", str(err))
        self.failUnlessIn("unable to open database file", str(err))

    def test_versions(self):
        basedir = self.make_basedir()
        dbfile = os.path.join(basedir, "test.db")
        db = get_db(dbfile)

        db.execute("UPDATE version SET version=2")
        db.commit()

        err = self.failUnlessRaises(DBError, get_db, dbfile)