]> git.ipfire.org Git - people/stevee/pakfire.git/blame - pakfire/repository/database.py
Add copyright information to all files.
[people/stevee/pakfire.git] / pakfire / repository / database.py
CommitLineData
47a4cb89 1#!/usr/bin/python
b792d887
MT
2###############################################################################
3# #
4# Pakfire - The IPFire package management system #
5# Copyright (C) 2011 Pakfire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
47a4cb89
MT
21
22import logging
23import os
5cc35aa4 24import random
2568a6d1 25import shutil
47a4cb89 26import sqlite3
66af936c 27import time
47a4cb89 28
c605d735
MT
29import pakfire.packages as packages
30
a2d1644c 31from pakfire.constants import *
66af936c 32
b6da0663
MT
33class Cursor(sqlite3.Cursor):
34 def execute(self, *args, **kwargs):
35 # For debugging of SQL queries.
36 #print args, kwargs
37
38 return sqlite3.Cursor.execute(self, *args, **kwargs)
39
40
47a4cb89 41class Database(object):
3723913b
MT
42 def __init__(self, pakfire, filename):
43 self.pakfire = pakfire
5cc35aa4
MT
44 self.filename = filename
45
c605d735 46 self._db = None
47a4cb89
MT
47
48 def __del__(self):
49 if self._db:
47a4cb89 50 self._db.close()
c605d735 51 self._db = None
47a4cb89
MT
52
53 def create(self):
54 pass
55
56 def open(self):
c605d735 57 if self._db is None:
47a4cb89
MT
58 logging.debug("Open database %s" % self.filename)
59
5cc35aa4
MT
60 dirname = os.path.dirname(self.filename)
61 if not os.path.exists(dirname):
62 os.makedirs(dirname)
47a4cb89 63
5cc35aa4 64 database_exists = os.path.exists(self.filename)
47a4cb89
MT
65
66 # Make a connection to the database.
67 self._db = sqlite3.connect(self.filename)
68 self._db.row_factory = sqlite3.Row
69
70 # Create the database if it was not there, yet.
71 if not database_exists:
72 self.create()
73
74 def close(self):
c605d735 75 self.__del__()
5cc35aa4 76
47a4cb89 77 def commit(self):
c605d735 78 self.open()
47a4cb89
MT
79 self._db.commit()
80
81 def cursor(self):
c605d735 82 self.open()
b6da0663 83 return self._db.cursor(Cursor)
47a4cb89 84
a2d1644c 85 def executescript(self, *args, **kwargs):
c605d735 86 self.open()
a2d1644c
MT
87 return self._db.executescript(*args, **kwargs)
88
2568a6d1 89
c605d735
MT
90class DatabaseLocal(Database):
91 def __init__(self, pakfire, repo):
92 self.repo = repo
2568a6d1 93
c605d735
MT
94 # Generate filename for package database
95 filename = os.path.join(pakfire.path, PACKAGES_DB)
96
97 Database.__init__(self, pakfire, filename)
98
99 def __len__(self):
100 count = 0
47a4cb89 101
47a4cb89 102 c = self.cursor()
c605d735
MT
103 c.execute("SELECT COUNT(*) AS count FROM packages")
104 for row in c:
105 count = row["count"]
106 c.close()
47a4cb89 107
c605d735
MT
108 return count
109
110 def create(self):
111 c = self.cursor()
47a4cb89 112 c.executescript("""
c605d735
MT
113 CREATE TABLE settings(
114 key TEXT,
115 val TEXT
116 );
117 INSERT INTO settings(key, val) VALUES('version', '0');
118
47a4cb89
MT
119 CREATE TABLE files(
120 name TEXT,
121 pkg INTEGER,
122 size INTEGER,
123 type INTEGER,
66af936c 124 hash1 TEXT
47a4cb89
MT
125 );
126
127 CREATE TABLE packages(
128 id INTEGER PRIMARY KEY,
129 name TEXT,
130 epoch INTEGER,
131 version TEXT,
132 release TEXT,
c560c27a 133 arch TEXT,
8537c16d 134 groups TEXT,
fa6d335b 135 filename TEXT,
ba8c383d 136 size INTEGER,
47a4cb89
MT
137 hash1 TEXT,
138 provides TEXT,
139 requires TEXT,
140 conflicts TEXT,
141 obsoletes TEXT,
142 license TEXT,
143 summary TEXT,
144 description TEXT,
1317485d 145 uuid TEXT,
47a4cb89
MT
146 build_id TEXT,
147 build_host TEXT,
0c665250 148 build_date TEXT,
c605d735
MT
149 build_time INTEGER,
150 installed INT,
151 reason TEXT,
152 repository TEXT,
153 scriptlet TEXT,
154 triggers TEXT
47a4cb89
MT
155 );
156 """)
157 # XXX add some indexes here
47a4cb89
MT
158 self.commit()
159 c.close()
160
66af936c 161 def add_package(self, pkg, reason=None):
fa6d335b
MT
162 logging.debug("Adding package to database: %s" % pkg.friendly_name)
163
164 c = self.cursor()
fa6d335b 165
c605d735
MT
166 try:
167 c.execute("""
168 INSERT INTO packages(
169 name,
170 epoch,
171 version,
172 release,
173 arch,
174 groups,
175 filename,
176 size,
177 hash1,
178 provides,
179 requires,
180 conflicts,
181 obsoletes,
182 license,
183 summary,
184 description,
185 uuid,
186 build_id,
187 build_host,
188 build_date,
189 build_time,
190 installed,
191 repository,
192 reason,
193 scriptlet,
194 triggers
195 ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
196 (
197 pkg.name,
198 pkg.epoch,
199 pkg.version,
200 pkg.release,
201 pkg.arch,
202 " ".join(pkg.groups),
203 pkg.filename,
204 pkg.size,
205 pkg.hash1,
206 " ".join(pkg.provides),
207 " ".join(pkg.requires),
208 " ".join(pkg.conflicts),
209 " ".join(pkg.obsoletes),
210 pkg.license,
211 pkg.summary,
212 pkg.description,
213 pkg.uuid,
214 pkg.build_id,
215 pkg.build_host,
216 pkg.build_date,
217 pkg.build_time,
218 time.time(),
219 pkg.repo.name,
220 reason or "",
221 pkg.scriptlet,
222 " ".join(pkg.triggers)
223 )
224 )
66af936c 225
c605d735 226 pkg_id = c.lastrowid
66af936c 227
c605d735
MT
228 c.executemany("INSERT INTO files(name, pkg) VALUES(?, ?)",
229 ((file, pkg_id) for file in pkg.filelist))
66af936c 230
c605d735
MT
231 except:
232 raise
66af936c 233
c605d735
MT
234 else:
235 self.commit()
66af936c 236
66af936c 237 c.close()
fa6d335b 238
e871a081
MT
239 def rem_package(self, pkg):
240 logging.debug("Removing package from database: %s" % pkg.friendly_name)
241
242 assert pkg.uuid
243
244 # Get the ID of the package in the database.
245 c = self.cursor()
246 c.execute("SELECT id FROM packages WHERE uuid = ? LIMIT 1", (pkg.uuid,))
247
248 id = None
249 for row in c:
250 id = row["id"]
251 break
252 assert id
253
254 # First, delete all files from the database and then delete the pkg itself.
255 c.execute("DELETE FROM files WHERE pkg = ?", (id,))
256 c.execute("DELETE FROM packages WHERE id = ?", (id,))
257
258 c.close()
259 self.commit()
260
c605d735
MT
261 @property
262 def packages(self):
47a4cb89
MT
263 c = self.cursor()
264
c605d735 265 c.execute("SELECT * FROM packages ORDER BY name")
47a4cb89 266
c605d735
MT
267 for row in c:
268 yield packages.DatabasePackage(self.pakfire, self.repo, self, row)
47a4cb89 269
66af936c 270 c.close()
6ee3d6b9
MT
271
272 def get_package_from_solv(self, solv_pkg):
273 c = self.cursor()
274 c.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
275
276 try:
277 for row in c:
278 return packages.DatabasePackage(self.pakfire, self.repo, self, row)
279
280 finally:
281 c.close()