Welcome to mirror list, hosted at ThFree Co, Russian Federation.

db.py « calm - cygwin.com/git/cygwin-apps/calm.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0aef83ab6a014263f8eaaf73de632df37fd488fc (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3
#
# Copyright (c) 2022 Jon Turney
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

#
# package db
#


import logging
import os
import sqlite3

from . import package
from . import utils


def connect(args):
    utils.makedirs(args.htdocs)
    dbfn = os.path.join(args.htdocs, 'calm.db')
    logging.debug("sqlite3 database %s" % (dbfn))

    conn = sqlite3.connect(dbfn, detect_types=sqlite3.PARSE_DECLTYPES)
    conn.execute('''CREATE TABLE IF NOT EXISTS historic_package_names
                    (name TEXT NOT NULL PRIMARY KEY
                    )''')

    conn.execute('''CREATE TABLE IF NOT EXISTS vault_requests
                    (srcpackage TEXT NOT NULL,
                     vr TEXT NOT NULL
                    )''')

    conn.execute('''CREATE TABLE IF NOT EXISTS missing_obsolete
                    (name TEXT NOT NULL,
                     arch TEXT NOT NULL,
                     replaces TEXT NOT NULL,
                     PRIMARY KEY (name, arch)
                    )''')
    conn.commit()

    return conn


#
# this tracks the set of all names we have ever had for packages, and returns
# ones which aren't in the set of names for current package
#
def update_package_names(args, packages):
    current_names = set()
    for arch in packages:
        current_names.update(packages[arch])

    with connect(args) as conn:
        conn.row_factory = sqlite3.Row

        cur = conn.execute("SELECT name FROM historic_package_names")
        historic_names = set([row['name'] for row in cur.fetchall()])

        # add newly appearing names to current_names
        for n in (current_names - historic_names):
            conn.execute('INSERT INTO historic_package_names (name) VALUES (?)', (n,))
            logging.debug("package '%s' name is added" % (n))

    # this is data isn't quite perfect for this purpose: it doesn't know about:
    # - names which the removed package provide:d
    # - other packages which might provide: the name of a removed package
    return (historic_names - current_names)


#
# vault requests made via 'calm-tool vault'
#
def vault_requests(args):
    requests = {}

    with connect(args) as conn:
        conn.row_factory = sqlite3.Row

        cur = conn.execute("SELECT * FROM vault_requests")
        for row in cur.fetchall():
            spkg = row['srcpackage']
            if spkg not in requests:
                requests[spkg] = set()
            requests[spkg].add(row['vr'])

        # remove all rows
        cur = conn.execute("DELETE FROM vault_requests")

    return requests


def vault_request_add(args, p, v):
    with connect(args) as conn:
        conn.execute('INSERT INTO vault_requests (srcpackage, vr) VALUES (?,?)', (p, v))


#
# this accumulates missing_obsoletes data for packages, so we will remember it
# even after the obsoleted package has been removed
#
def update_missing_obsolete(args, packages, arch):
    data = {}
    with connect(args) as conn:
        conn.row_factory = sqlite3.Row

        # read
        cur = conn.execute("SELECT name, replaces FROM missing_obsolete WHERE arch = ?", (arch,))
        for row in cur.fetchall():
            data[row['name']] = set(row['replaces'].split())

        # update missing obsoletes data
        missing_obsolete = package.upgrade_oldstyle_obsoletes(packages[arch], data.copy())

        # update
        for n, r in missing_obsolete.items():
            if n not in data:
                conn.execute('INSERT INTO missing_obsolete (name, arch, replaces) VALUES (?, ? , ?)', (n, arch, ' '.join(r)))
            else:
                conn.execute('UPDATE missing_obsolete SET replaces = ? WHERE name = ? AND arch = ?', (' '.join(r), n, arch))

    return missing_obsolete