summaryrefslogtreecommitdiff
path: root/readyaml.py
blob: fac3c40bd07c7a06d1aed51ae99295023d999171 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/python
"""This tool reads a yaml file as generated by importpkg.py on stdin and
updates the database with the contents."""

import optparse
import sys

from debian.debian_support import version_compare
import sqlalchemy
import yaml

from dedup import schema
from dedup.utils import configure_database_engine

def readyaml(conn, stream):
    gen = yaml.safe_load_all(stream)
    metadata = next(gen)
    package = metadata["package"]
    row = conn.execute(sqlalchemy.text("SELECT id, version FROM package WHERE name = :name;"),
                       name=package).fetchone()
    if row:
        pid, version = row
        if version_compare(version, metadata["version"]) > 0:
            return
    else:
        pid = None

    cur = conn.execute("SELECT name, id FROM function;")
    funcmapping = dict(cur.fetchall())
    if pid is not None:
        conn.execute(sqlalchemy.text("DELETE FROM content WHERE pid = :pid;"),
                     pid=pid)
        conn.execute(sqlalchemy.text("DELETE FROM dependency WHERE pid = :pid;"),
                     pid=pid)
        conn.execute(sqlalchemy.text("UPDATE package SET version = :version, architecture = :architecture, source = :source WHERE id = :pid;"),
                     version=metadata["version"],
                     architecture=metadata["architecture"],
                     source=metadata["source"], pid=pid)
    else:
        pid = conn.execute(schema.package.insert().values(
                           name=package, version=metadata["version"],
                           architecture=metadata["architecture"],
                           source=metadata["source"])).inserted_primary_key[0]
    if metadata["depends"]:
        conn.execute(sqlalchemy.text("INSERT INTO dependency (pid, required) VALUES (:pid, :required);"),
                     [dict(pid=pid, required=dep)
                      for dep in metadata["depends"]])
    for entry in gen:
        if entry == "commit":
            return

        cid = conn.execute(schema.content.insert().values(
                           pid=pid, filename=entry["name"], size=entry["size"])
                ).inserted_primary_key[0]
        if entry["hashes"]:
            conn.execute(sqlalchemy.text("INSERT INTO hash (cid, fid, hash) VALUES (:cid, :fid, :hash);"),
                         [dict(cid=cid, fid=funcmapping[func], hash=hexhash)
                          for func, hexhash in entry["hashes"].items()])
    raise ValueError("missing commit block")

def main():
    parser = optparse.OptionParser()
    parser.add_option("-d", "--database", action="store",
                      default="sqlite:///test.sqlite3",
                      help="location of the database")
    options, args = parser.parse_args()
    db = sqlalchemy.create_engine(options.database)
    configure_database_engine(db)
    with db.begin() as conn:
        readyaml(conn, sys.stdin)

if __name__ == "__main__":
    main()