b6f731677c2c288645ee4a49dff530ed3a04c7bb
[~helmut/debian-dedup.git] / readyaml.py
1 #!/usr/bin/python
2 """This tool reads a yaml file as generated by importpkg.py on stdin and
3 updates the database with the contents."""
4
5 import argparse
6 import sqlite3
7 import sys
8
9 from debian.debian_support import version_compare
10 import yaml
11
12 def readyaml(db, stream):
13     cur = db.cursor()
14     cur.execute("PRAGMA foreign_keys = ON;")
15     gen = yaml.safe_load_all(stream)
16     metadata = next(gen)
17     package = metadata["package"]
18     cur.execute("SELECT id, version FROM package WHERE name = ?;",
19                     (package,))
20     row = cur.fetchone()
21     if row:
22         pid, version = row
23         if version_compare(version, metadata["version"]) > 0:
24             return
25     else:
26         pid = None
27
28     cur.execute("BEGIN;")
29     cur.execute("SELECT name, id FROM function;")
30     funcmapping = dict(cur.fetchall())
31     if pid is not None:
32         cur.execute("DELETE FROM content WHERE pid = ?;", (pid,))
33         cur.execute("DELETE FROM dependency WHERE pid = ?;", (pid,))
34         cur.execute("UPDATE package SET version = ?, architecture = ?, source = ? WHERE id = ?;",
35                     (metadata["version"], metadata["architecture"], metadata["source"], pid))
36     else:
37         cur.execute("INSERT INTO package (name, version, architecture, source) VALUES (?, ?, ?, ?);",
38                     (package, metadata["version"], metadata["architecture"],
39                      metadata["source"]))
40         pid = cur.lastrowid
41     cur.executemany("INSERT INTO dependency (pid, required) VALUES (?, ?);",
42                     ((pid, dep) for dep in metadata["depends"]))
43     for entry in gen:
44         if entry == "commit":
45             db.commit()
46             return
47
48         cur.execute("INSERT INTO content (pid, filename, size) VALUES (?, ?, ?);",
49                     (pid, entry["name"], entry["size"]))
50         cid = cur.lastrowid
51         cur.executemany("INSERT INTO hash (cid, fid, hash) VALUES (?, ?, ?);",
52                         ((cid, funcmapping[func], hexhash)
53                          for func, hexhash in entry["hashes"].items()))
54     raise ValueError("missing commit block")
55
56 def main():
57     parser = argparse.ArgumentParser()
58     parser.add_argument("-d", "--database", action="store",
59                         default="test.sqlite3",
60                         help="path to the sqlite3 database file")
61     args = parser.parse_args()
62     db = sqlite3.connect(args.database)
63     readyaml(db, sys.stdin)
64
65 if __name__ == "__main__":
66     main()