You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.6 KiB
83 lines
2.6 KiB
6 years ago
|
# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
|
||
|
#
|
||
|
# This module is part of GitDB and is released under
|
||
|
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
|
||
|
import codecs
|
||
|
from gitdb.db.base import (
|
||
|
CompoundDB,
|
||
|
)
|
||
|
|
||
|
__all__ = ('ReferenceDB', )
|
||
|
|
||
|
|
||
|
class ReferenceDB(CompoundDB):
|
||
|
|
||
|
"""A database consisting of database referred to in a file"""
|
||
|
|
||
|
# Configuration
|
||
|
# Specifies the object database to use for the paths found in the alternates
|
||
|
# file. If None, it defaults to the GitDB
|
||
|
ObjectDBCls = None
|
||
|
|
||
|
def __init__(self, ref_file):
|
||
|
super(ReferenceDB, self).__init__()
|
||
|
self._ref_file = ref_file
|
||
|
|
||
|
def _set_cache_(self, attr):
|
||
|
if attr == '_dbs':
|
||
|
self._dbs = list()
|
||
|
self._update_dbs_from_ref_file()
|
||
|
else:
|
||
|
super(ReferenceDB, self)._set_cache_(attr)
|
||
|
# END handle attrs
|
||
|
|
||
|
def _update_dbs_from_ref_file(self):
|
||
|
dbcls = self.ObjectDBCls
|
||
|
if dbcls is None:
|
||
|
# late import
|
||
|
from gitdb.db.git import GitDB
|
||
|
dbcls = GitDB
|
||
|
# END get db type
|
||
|
|
||
|
# try to get as many as possible, don't fail if some are unavailable
|
||
|
ref_paths = list()
|
||
|
try:
|
||
|
with codecs.open(self._ref_file, 'r', encoding="utf-8") as f:
|
||
|
ref_paths = [l.strip() for l in f]
|
||
|
except (OSError, IOError):
|
||
|
pass
|
||
|
# END handle alternates
|
||
|
|
||
|
ref_paths_set = set(ref_paths)
|
||
|
cur_ref_paths_set = set(db.root_path() for db in self._dbs)
|
||
|
|
||
|
# remove existing
|
||
|
for path in (cur_ref_paths_set - ref_paths_set):
|
||
|
for i, db in enumerate(self._dbs[:]):
|
||
|
if db.root_path() == path:
|
||
|
del(self._dbs[i])
|
||
|
continue
|
||
|
# END del matching db
|
||
|
# END for each path to remove
|
||
|
|
||
|
# add new
|
||
|
# sort them to maintain order
|
||
|
added_paths = sorted(ref_paths_set - cur_ref_paths_set, key=lambda p: ref_paths.index(p))
|
||
|
for path in added_paths:
|
||
|
try:
|
||
|
db = dbcls(path)
|
||
|
# force an update to verify path
|
||
|
if isinstance(db, CompoundDB):
|
||
|
db.databases()
|
||
|
# END verification
|
||
|
self._dbs.append(db)
|
||
|
except Exception:
|
||
|
# ignore invalid paths or issues
|
||
|
pass
|
||
|
# END for each path to add
|
||
|
|
||
|
def update_cache(self, force=False):
|
||
|
# re-read alternates and update databases
|
||
|
self._update_dbs_from_ref_file()
|
||
|
return super(ReferenceDB, self).update_cache(force)
|