use sqlite instead of gdbm to keep more info

This commit is contained in:
lilydjwg 2012-12-15 12:42:06 +08:00
parent 6dfb7b4de8
commit 0d4e0500f4
3 changed files with 22 additions and 13 deletions

View file

@ -5,7 +5,7 @@ Edit a copy of `archrepo.ini` and then run `./archreposrv <config>`.
DEPENDENCIES DEPENDENCIES
==== ====
* Python, &gt;= 3.3, with gdbm support * Python, &gt;= 3.3, with sqlite support
* tornado, > 2.4.1 * tornado, > 2.4.1
* pyinotify, tested 0.9.4 * pyinotify, tested 0.9.4
* winterpy * winterpy

View file

@ -11,6 +11,9 @@ path: /home/lilydjwg/tmpfs/test
# A database to store package filenames. Default to ${path}/repofiles.db # A database to store package filenames. Default to ${path}/repofiles.db
#files-db: /home/lilydjwg/tmpfs/test/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 # Specify where to find these commands
#command-add: repo-add #command-add: repo-add
#command-remove: repo-remove #command-remove: repo-remove

View file

@ -7,7 +7,7 @@ import configparser
from functools import partial from functools import partial
import queue import queue
import logging import logging
import dbm.gnu import sqlite3
import pyinotify import pyinotify
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
@ -17,8 +17,6 @@ import archpkg
from myutils import enable_pretty_logging from myutils import enable_pretty_logging
enable_pretty_logging(logging.DEBUG) enable_pretty_logging(logging.DEBUG)
# FIXME: 如果一个软件包消失了,那么如果它在仓库数据库里,它就应当从数据库删除。否则不应该
class ActionInfo(archpkg.PkgNameInfo): class ActionInfo(archpkg.PkgNameInfo):
def __new__(cls, path, action, four=None, five=None): def __new__(cls, path, action, four=None, five=None):
if four is not None: if four is not None:
@ -132,8 +130,13 @@ class EventHandler(pyinotify.ProcessEvent):
self._ioloop = ioloop or IOLoop.instance() self._ioloop = ioloop or IOLoop.instance()
base = config.get('path') base = config.get('path')
dbname = config.get('files-db', os.path.join(base, 'repofiles.db')) dbname = config.get('info-db', os.path.join(base, 'pkginfo.db'))
self._db = dbm.gnu.open(dbname, 'cs') 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')] dirs = [os.path.join(base, x) for x in ('any', 'i686', 'x86_64')]
self.files = files = set() self.files = files = set()
@ -145,7 +148,7 @@ class EventHandler(pyinotify.ProcessEvent):
self._initial_update(files) self._initial_update(files)
def _initial_update(self, 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: for f in files - oldfiles:
if f.endswith('.pkg.tar.xz'): if f.endswith('.pkg.tar.xz'):
@ -227,16 +230,19 @@ class EventHandler(pyinotify.ProcessEvent):
self._real_dispatch(d, act) self._real_dispatch(d, act)
def _real_dispatch(self, d, act): def _real_dispatch(self, d, act):
key = act.path.encode('utf-8')
if act.action == 'add': if act.action == 'add':
self._db.execute('update pkginfo set state = 0 where pkgname = ? and pkgarch = ?', (act.name, act.arch))
def callback(): 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: 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(): def callback():
try: self._db.execute('delete from pkginfo where pkgfile = ?', (act.path,))
del self._db[key]
except KeyError:
logging.warn('files db inconsistent: key %s not there', key)
act.callback = callback act.callback = callback
self.repomans[d].add_action(act) self.repomans[d].add_action(act)