schema: reference package table by integer key
[~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 sqlite3
6 import sys
7
8 from debian.debian_support import version_compare
9 import yaml
10
11 def readyaml(db, stream):
12     cur = db.cursor()
13     cur.execute("PRAGMA foreign_keys = ON;")
14     gen = yaml.safe_load_all(stream)
15     metadata = next(gen)
16     package = metadata["package"]
17     cur.execute("SELECT id, version FROM package WHERE name = ?;",
18                     (package,))
19     row = cur.fetchone()
20     if row:
21         pid, version = row
22         if version_compare(version, metadata["version"]) > 0:
23             return
24     else:
25         pid = None
26
27     cur.execute("BEGIN;")
28     if pid is not None:
29         cur.execute("DELETE FROM content WHERE pid = ?;", (pid,))
30         cur.execute("DELETE FROM dependency WHERE pid = ?;", (pid,))
31         cur.execute("UPDATE package SET version = ?, architecture = ?, source = ? WHERE id = ?;",
32                     (metadata["version"], metadata["architecture"], metadata["source"], pid))
33     else:
34         cur.execute("INSERT INTO package (name, version, architecture, source) VALUES (?, ?, ?, ?);",
35                     (package, metadata["version"], metadata["architecture"],
36                      metadata["source"]))
37         pid = cur.lastrowid
38     cur.executemany("INSERT INTO dependency (pid, required) VALUES (?, ?);",
39                     ((pid, dep) for dep in metadata["depends"]))
40     for entry in gen:
41         if entry == "commit":
42             db.commit()
43             return
44
45         cur.execute("INSERT INTO content (pid, filename, size) VALUES (?, ?, ?);",
46                     (pid, entry["name"], entry["size"]))
47         cid = cur.lastrowid
48         cur.executemany("INSERT INTO hash (cid, function, hash) VALUES (?, ?, ?);",
49                         ((cid, func, hexhash)
50                          for func, hexhash in entry["hashes"].items()))
51     raise ValueError("missing commit block")
52
53 def main():
54     db = sqlite3.connect("test.sqlite3")
55     readyaml(db, sys.stdin)
56
57 if __name__ == "__main__":
58     main()