diff --git a/README.mkd b/README.mkd index 7dff9d2..800ff6a 100644 --- a/README.mkd +++ b/README.mkd @@ -5,7 +5,7 @@ Edit a copy of `archrepo.ini` and then run `./archreposrv `. DEPENDENCIES ==== -* Python, >= 3.3, with gdbm support +* Python, >= 3.3, with sqlite support * tornado, > 2.4.1 * pyinotify, tested 0.9.4 * winterpy diff --git a/archrepo.ini b/archrepo.ini index fbf954f..ba1cf16 100644 --- a/archrepo.ini +++ b/archrepo.ini @@ -11,6 +11,9 @@ path: /home/lilydjwg/tmpfs/test # A database to store package filenames. Default to ${path}/repofiles.db #files-db: /home/lilydjwg/tmpfs/test/repofiles.db +# A database to store package info. Default to ${path}/pkginfo.db +#info-db: /home/lilydjwg/tmpfs/test/pkginfo.db + # Specify where to find these commands #command-add: repo-add #command-remove: repo-remove diff --git a/archreposrv b/archreposrv index 1919a96..5260519 100755 --- a/archreposrv +++ b/archreposrv @@ -7,7 +7,7 @@ import configparser from functools import partial import queue import logging -import dbm.gnu +import sqlite3 import pyinotify from tornado.ioloop import IOLoop @@ -17,8 +17,6 @@ import archpkg from myutils import enable_pretty_logging enable_pretty_logging(logging.DEBUG) -# FIXME: 如果一个软件包消失了,那么如果它在仓库数据库里,它就应当从数据库删除。否则不应该 - class ActionInfo(archpkg.PkgNameInfo): def __new__(cls, path, action, four=None, five=None): if four is not None: @@ -132,8 +130,13 @@ class EventHandler(pyinotify.ProcessEvent): self._ioloop = ioloop or IOLoop.instance() base = config.get('path') - dbname = config.get('files-db', os.path.join(base, 'repofiles.db')) - self._db = dbm.gnu.open(dbname, 'cs') + dbname = config.get('info-db', os.path.join(base, 'pkginfo.db')) + self._db = sqlite3.connect(dbname, isolation_level=None) # isolation_level=None means autocommit + self._db.execute('''create table if not exists pkginfo + (filename text unique, + pkgname text, + pkgarch text, + state int)''') dirs = [os.path.join(base, x) for x in ('any', 'i686', 'x86_64')] self.files = files = set() @@ -145,7 +148,7 @@ class EventHandler(pyinotify.ProcessEvent): self._initial_update(files) def _initial_update(self, files): - oldfiles = {f.decode('utf-8') for f in self._db.keys()} + oldfiles = {f[0] for f in self._db.execute('select filename from pkginfo')} for f in files - oldfiles: if f.endswith('.pkg.tar.xz'): @@ -227,16 +230,19 @@ class EventHandler(pyinotify.ProcessEvent): self._real_dispatch(d, act) def _real_dispatch(self, d, act): - key = act.path.encode('utf-8') if act.action == 'add': + self._db.execute('update pkginfo set state = 0 where pkgname = ? and pkgarch = ?', (act.name, act.arch)) def callback(): - self._db[key] = b'\x01' + self._db.execute( + 'insert or replace into pkginfo (filename, pkgname, pkgarch, state) values (?, ?, ?, ?)', + (act.path, act.name, act.arch, 1)) else: + res = self._db.execute('select state from pkginfo where filename = ? and state = 1 limit 1', (act.path,)) + if tuple(res) == (): + # the file isn't in repo database, ignoring + return def callback(): - try: - del self._db[key] - except KeyError: - logging.warn('files db inconsistent: key %s not there', key) + self._db.execute('delete from pkginfo where pkgfile = ?', (act.path,)) act.callback = callback self.repomans[d].add_action(act)