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
====
* Python, &gt;= 3.3, with gdbm support
* Python, &gt;= 3.3, with sqlite support
* tornado, > 2.4.1
* pyinotify, tested 0.9.4
* winterpy

View file

@ -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

View file

@ -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)