|
|
|
@ -1,5 +1,8 @@
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
metadatadb.py
|
|
|
|
metadatadb.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Everything needed to interact with the metadata database; namely SQL ORM objects, a context
|
|
|
|
|
|
|
|
generator for the actual database, and a handful of convenience functions.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
import contextlib
|
|
|
|
import contextlib
|
|
|
|
import collections
|
|
|
|
import collections
|
|
|
|
@ -15,8 +18,6 @@ HASH_CHUNK_SIZE = 10485760 # 10mb
|
|
|
|
_db_session_maker = sqlalchemy.orm.sessionmaker()
|
|
|
|
_db_session_maker = sqlalchemy.orm.sessionmaker()
|
|
|
|
_engine = None
|
|
|
|
_engine = None
|
|
|
|
|
|
|
|
|
|
|
|
ImageData = collections.namedtuple('ImageData', 'UUID, sha1sum, filename, release_group')
|
|
|
|
|
|
|
|
ReleaseGroupData = collections.namedtuple('ReleaseGroupData', 'UUID, name, platform')
|
|
|
|
|
|
|
|
DatData = collections.namedtuple('DatData', 'UUID, name, website, version, image_list')
|
|
|
|
DatData = collections.namedtuple('DatData', 'UUID, name, website, version, image_list')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -25,7 +26,38 @@ def _uuidgen():
|
|
|
|
|
|
|
|
|
|
|
|
_SQLBase = sqlalchemy.ext.declarative.declarative_base()
|
|
|
|
_SQLBase = sqlalchemy.ext.declarative.declarative_base()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Image(_SQLBase):
|
|
|
|
|
|
|
|
'''SQLAlchemy ORM class for ROM image metadata.'''
|
|
|
|
|
|
|
|
# TODO: Split filenames into more meaningful metadata.
|
|
|
|
|
|
|
|
__tablename__ = 'images'
|
|
|
|
|
|
|
|
id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.Sequence('image_id_sequence'),
|
|
|
|
|
|
|
|
primary_key=True)
|
|
|
|
|
|
|
|
uuid = sqlalchemy.Column(sqlalchemy.String, nullable=False, default=_uuidgen)
|
|
|
|
|
|
|
|
sha1sum = sqlalchemy.Column(sqlalchemy.String, unique=True, nullable=False)
|
|
|
|
|
|
|
|
filename = sqlalchemy.Column(sqlalchemy.String, unique=True, nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: Add many-to-one relationship to release groups.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
|
|
|
return 'ROM Image: id: %s, uuid: %s, sha1sum: %s, filename: %s' % (self.id, self.uuid,
|
|
|
|
|
|
|
|
self.sha1sum, self.filename)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ReleaseGroup(_SQLBase):
|
|
|
|
|
|
|
|
'''SQLAlchemy ORM class for release group metadata.'''
|
|
|
|
|
|
|
|
__tablename__ = 'release_groups'
|
|
|
|
|
|
|
|
id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.Sequence('image_id_sequence'),
|
|
|
|
|
|
|
|
primary_key=True)
|
|
|
|
|
|
|
|
uuid = sqlalchemy.Column(sqlalchemy.String, nullable=False, default=_uuidgen)
|
|
|
|
|
|
|
|
name = sqlalchemy.Column(sqlalchemy.String, unique=True, nullable=False)
|
|
|
|
|
|
|
|
# TODO: Add many-to-one relationship to platforms.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
|
|
|
return 'Release Group: id: %s, uuid: %s, name: %s' % (self.id, self.uuid,
|
|
|
|
|
|
|
|
self.name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Platform(_SQLBase):
|
|
|
|
class Platform(_SQLBase):
|
|
|
|
|
|
|
|
'''SQLAlchemy ORM class for platform metadata.'''
|
|
|
|
__tablename__ = 'platforms'
|
|
|
|
__tablename__ = 'platforms'
|
|
|
|
id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.Sequence('platform_id_sequence'),
|
|
|
|
id = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.Sequence('platform_id_sequence'),
|
|
|
|
primary_key=True)
|
|
|
|
primary_key=True)
|
|
|
|
@ -37,6 +69,7 @@ class Platform(_SQLBase):
|
|
|
|
return 'Platform: id: %s, uuid: %s, fullname: %s, shortcode: %s' % (self.id, self.uuid,
|
|
|
|
return 'Platform: id: %s, uuid: %s, fullname: %s, shortcode: %s' % (self.id, self.uuid,
|
|
|
|
self.fullname, self.shortcode)
|
|
|
|
self.fullname, self.shortcode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: This should go in the eventual romdb class.
|
|
|
|
# TODO: This should go in the eventual romdb class.
|
|
|
|
def get_file_sha1sum(filename):
|
|
|
|
def get_file_sha1sum(filename):
|
|
|
|
sha1sum = hashlib.sha1()
|
|
|
|
sha1sum = hashlib.sha1()
|
|
|
|
@ -50,12 +83,27 @@ def get_file_sha1sum(filename):
|
|
|
|
return sha1sum.hexdigest()
|
|
|
|
return sha1sum.hexdigest()
|
|
|
|
|
|
|
|
|
|
|
|
def configure(db_path):
|
|
|
|
def configure(db_path):
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
Configure and initialize the database for the entire module.
|
|
|
|
|
|
|
|
Currently, only SQLite is supported.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_path: Path for the SQLite database
|
|
|
|
|
|
|
|
'''
|
|
|
|
_engine = sqlalchemy.create_engine('sqlite:///%s' % db_path)
|
|
|
|
_engine = sqlalchemy.create_engine('sqlite:///%s' % db_path)
|
|
|
|
|
|
|
|
|
|
|
|
_SQLBase.metadata.create_all(_engine)
|
|
|
|
_SQLBase.metadata.create_all(_engine)
|
|
|
|
_db_session_maker.configure(bind=_engine)
|
|
|
|
_db_session_maker.configure(bind=_engine)
|
|
|
|
|
|
|
|
|
|
|
|
def search(session, table_object, inclusive=True, **constraints):
|
|
|
|
def search(session, table_object, **constraints):
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
Search the database for entries matching the given constraints.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
session: SQLAlchemy session, presumably from get_db_session
|
|
|
|
|
|
|
|
table_object: SQLAlchemy ORM table object, defined in the file above
|
|
|
|
|
|
|
|
constraints: key-value pairs to match against specific fields in the database
|
|
|
|
|
|
|
|
Note: Currently, only the query.ilike method is supported. This is intended to
|
|
|
|
|
|
|
|
eventually support the entire range of available filters.
|
|
|
|
|
|
|
|
'''
|
|
|
|
query = session.query(table_object)
|
|
|
|
query = session.query(table_object)
|
|
|
|
|
|
|
|
|
|
|
|
for key, value in constraints.items():
|
|
|
|
for key, value in constraints.items():
|
|
|
|
@ -69,6 +117,7 @@ def search(session, table_object, inclusive=True, **constraints):
|
|
|
|
|
|
|
|
|
|
|
|
@contextlib.contextmanager
|
|
|
|
@contextlib.contextmanager
|
|
|
|
def get_db_session():
|
|
|
|
def get_db_session():
|
|
|
|
|
|
|
|
'''Get a SQLAlchemy database session with a proper context object. '''
|
|
|
|
session = _db_session_maker()
|
|
|
|
session = _db_session_maker()
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
yield session
|
|
|
|
yield session
|
|
|
|
|