Hide pretest information by default
[build-farm.git] / buildfarm / sqldb.py
index 8aa2cf85fead330952e30fb02d9bd86db9e2b1f0..f679fb40159151951460787561355882f5e29bcc 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from buildfarm import (
-    BuildFarm,
+from buildfarm.tree import (
     Tree,
     )
 from buildfarm.build import (
-    Build,
-    BuildResultStore,
-    BuildStatus,
-    NoSuchBuildError,
+    StormBuild,
+    Test,
+    TestResult,
     )
 from buildfarm.hostdb import (
     Host,
@@ -34,14 +32,14 @@ from buildfarm.hostdb import (
     NoSuchHost,
     )
 
-import os
+
 try:
     from pysqlite2 import dbapi2 as sqlite3
 except ImportError:
     import sqlite3
 from storm.database import create_database
 from storm.expr import EXPR, FuncExpr, compile
-from storm.locals import Bool, Desc, Int, Unicode, RawStr
+from storm.locals import Bool, Desc, Int, RawStr, Reference, Unicode
 from storm.store import Store
 
 
@@ -61,40 +59,6 @@ def compile_count(compile, cast, state):
     return "CAST(%s AS %s)" % (column, cast.type)
 
 
-class StormBuild(Build):
-    __storm_table__ = "build"
-
-    id = Int(primary=True)
-    tree = RawStr()
-    revision = RawStr()
-    host = RawStr()
-    compiler = RawStr()
-    checksum = RawStr()
-    upload_time = Int(name="age")
-    status_str = RawStr(name="status")
-    basename = RawStr()
-    host_id = Int()
-    tree_id = Int()
-    compiler_id = Int()
-
-    def status(self):
-        return BuildStatus.__deserialize__(self.status_str)
-
-    def revision_details(self):
-        return self.revision
-
-    def log_checksum(self):
-        return self.checksum
-
-    def remove(self):
-        super(StormBuild, self).remove()
-        Store.of(self).remove(self)
-
-    def remove_logs(self):
-        super(StormBuild, self).remove_logs()
-        self.basename = None
-
-
 class StormHost(Host):
     __storm_table__ = "host"
 
@@ -155,7 +119,8 @@ class StormHostDatabase(HostDatabase):
         return self.store.find(StormHost).order_by(StormHost.name)
 
     def __getitem__(self, name):
-        result = self.store.find(StormHost, Cast(StormHost.name, "TEXT") == Cast(name, "TEXT"))
+        result = self.store.find(StormHost,
+            Cast(StormHost.name, "TEXT") == Cast(name, "TEXT"))
         ret = result.one()
         if ret is None:
             raise NoSuchHost(name)
@@ -165,100 +130,6 @@ class StormHostDatabase(HostDatabase):
         self.store.commit()
 
 
-class StormCachingBuildResultStore(BuildResultStore):
-
-    def __init__(self, basedir, store=None):
-        super(StormCachingBuildResultStore, self).__init__(basedir)
-
-        if store is None:
-            store = memory_store()
-
-        self.store = store
-
-    def __contains__(self, build):
-        return not (self.store.find(StormBuild,
-            Cast(StormBuild.checksum, "TEXT") == build.log_checksum()).is_empty())
-
-    def get_previous_revision(self, tree, host, compiler, revision):
-        result = self.store.find(StormBuild,
-            StormBuild.tree == tree,
-            StormBuild.host == host,
-            StormBuild.compiler == compiler,
-            Cast(StormBuild.revision, "TEXT") == revision)
-        cur_build = result.any()
-        if cur_build is None:
-            raise NoSuchBuildError(tree, host, compiler, revision)
-
-        result = self.store.find(StormBuild,
-            StormBuild.tree == tree,
-            StormBuild.host == host,
-            StormBuild.compiler == compiler,
-            Cast(StormBuild.revision, "TEXT") != revision,
-            StormBuild.id < cur_build.id)
-        result = result.order_by(Desc(StormBuild.id))
-        prev_build = result.first()
-        if prev_build is None:
-            raise NoSuchBuildError(tree, host, compiler, revision)
-        return prev_build.revision
-
-    def get_latest_revision(self, tree, host, compiler):
-        result = self.store.find(StormBuild,
-            StormBuild.tree == tree,
-            StormBuild.host == host,
-            StormBuild.compiler == compiler)
-        result = result.order_by(Desc(StormBuild.id))
-        build = result.first()
-        if build is None:
-            raise NoSuchBuildError(tree, host, compiler)
-        return build.revision
-
-    def upload_build(self, build):
-        existing_build = self.store.find(StormBuild,
-            Cast(StormBuild.checksum, "TEXT") == build.log_checksum()).order_by(StormBuild.upload_time).first()
-        if existing_build is not None:
-            # Already present
-            assert build.tree == existing_build.tree
-            assert build.host == existing_build.host
-            assert build.compiler == existing_build.compiler
-            return existing_build
-        rev = build.revision_details()
-        super(StormCachingBuildResultStore, self).upload_build(build)
-        new_basename = self.build_fname(build.tree, build.host, build.compiler, rev)
-        new_build = StormBuild(new_basename, build.tree, build.host,
-            build.compiler, rev)
-        new_build.checksum = build.log_checksum()
-        new_build.upload_time = build.upload_time
-        new_build.status_str = build.status().__serialize__()
-        new_build.basename = new_basename
-        new_build.host_id = self.store.find(
-            StormHost, Cast(StormHost.name, "TEXT") == build.host).one().id
-        self.store.add(new_build)
-        return new_build
-
-    def get_old_builds(self, tree, host, compiler):
-        result = self.store.find(StormBuild,
-            StormBuild.tree == tree,
-            StormBuild.host == host,
-            StormBuild.compiler == compiler)
-        return result.order_by(Desc(StormBuild.upload_time))
-
-    def get_build(self, tree, host, compiler, revision=None, checksum=None):
-        expr = [
-            StormBuild.tree == tree,
-            StormBuild.host == host,
-            StormBuild.compiler == compiler,
-            ]
-        if revision is not None:
-            expr.append(Cast(StormBuild.revision, "TEXT") == revision)
-        if checksum is not None:
-            expr.append(Cast(StormBuild.checksum, "TEXT") == checksum)
-        result = self.store.find(StormBuild, *expr).order_by(Desc(StormBuild.upload_time))
-        ret = result.first()
-        if ret is None:
-            raise NoSuchBuildError(tree, host, compiler, revision)
-        return ret
-
-
 def distinct_builds(builds):
     done = set()
     for build in builds:
@@ -269,50 +140,6 @@ def distinct_builds(builds):
         yield build
 
 
-class StormCachingBuildFarm(BuildFarm):
-
-    def __init__(self, path=None, store=None, timeout=0.5):
-        self.timeout = timeout
-        self.store = store
-        super(StormCachingBuildFarm, self).__init__(path)
-
-    def _get_store(self):
-        if self.store is not None:
-            return self.store
-        db_path = os.path.join(self.path, "db", "hostdb.sqlite")
-        db = create_database("sqlite:%s?timeout=%f" % (db_path, self.timeout))
-        self.store = Store(db)
-        setup_schema(self.store)
-        return self.store
-
-    def _open_hostdb(self):
-        return StormHostDatabase(self._get_store())
-
-    def _open_build_results(self):
-        path = os.path.join(self.path, "data", "oldrevs")
-        return StormCachingBuildResultStore(path, self._get_store())
-
-    def get_host_builds(self, host):
-        result = self._get_store().find(StormBuild, StormBuild.host == host)
-        return distinct_builds(result.order_by(Desc(StormBuild.upload_time)))
-
-    def get_tree_builds(self, tree):
-        result = self._get_store().find(StormBuild, Cast(StormBuild.tree, "TEXT") == tree)
-        return distinct_builds(result.order_by(Desc(StormBuild.upload_time)))
-
-    def get_last_builds(self):
-        result = self._get_store().find(StormBuild)
-        return distinct_builds(result.order_by(Desc(StormBuild.upload_time)))
-
-    def get_revision_builds(self, tree, revision=None):
-        return self._get_store().find(StormBuild,
-            Cast(StormBuild.tree, "TEXT") == tree,
-            Cast(StormBuild.revision, "TEXT") == revision)
-
-    def commit(self):
-        self.store.commit()
-
-
 class StormTree(Tree):
     __storm_table__ = "tree"
 
@@ -325,6 +152,24 @@ class StormTree(Tree):
     scm = RawStr()
 
 
+class StormTest(Test):
+    __storm_table__ = "test"
+
+    id = Int(primary=True)
+    name = RawStr()
+
+
+class StormTestResult(TestResult):
+    __storm_table__ = "test_result"
+
+    id = Int(primary=True)
+    build_id = Int(name="build")
+    build = Reference(build_id, StormBuild)
+
+    test_id = Int(name="test")
+    test = Reference(test_id, StormTest)
+
+
 def setup_schema(db):
     db.execute("PRAGMA foreign_keys = 1;", noresult=True)
     db.execute("""
@@ -383,6 +228,19 @@ CREATE TABLE IF NOT EXISTS compiler (
     db.execute("""
 CREATE UNIQUE INDEX IF NOT EXISTS unique_compiler_name ON compiler(name);
 """, noresult=True)
+    db.execute("""
+CREATE TABLE IF NOT EXISTS test (
+    id integer primary key autoincrement,
+    name text not null);
+    """, noresult=True)
+    db.execute("CREATE UNIQUE INDEX IF NOT EXISTS test_name ON test(name);",
+        noresult=True)
+    db.execute("""CREATE TABLE IF NOT EXISTS test_result (
+        build int,
+        test int,
+        result int
+        );""", noresult=True)
+    db.execute("""CREATE UNIQUE INDEX IF NOT EXISTS build_test_result ON test_result(build, test);""", noresult=True)
 
 
 def memory_store():