From 8f1cdf7a6eb9d91283e153a2aeffae492ba879bb Mon Sep 17 00:00:00 2001 From: Emily Frost Date: Mon, 6 Jun 2022 07:38:55 -0500 Subject: [PATCH] Classified the loose functions in metadata.py --- metadata.py | 138 +++++++++++++++++++++++++--------------------------- 1 file changed, 66 insertions(+), 72 deletions(-) diff --git a/metadata.py b/metadata.py index 1305535..526b535 100644 --- a/metadata.py +++ b/metadata.py @@ -14,20 +14,8 @@ import sqlalchemy.orm # TODO: l o g g i n g HASH_CHUNK_SIZE = 10485760 # 10mb -db_session = None - -_db_session_maker = sqlalchemy.orm.sessionmaker() -_engine = None -_configured = False _SQLBase = sqlalchemy.ext.declarative.declarative_base() -class MetadataDBSessionException(Exception): - '''This exception is raised when something goes wrong with a database session.''' - - -def _uuidgen(): - return str(uuid.uuid4()) - ''' Metadata ORM classes for SQLAlchemy. For a detailed description of each piece of data, refer to metadata/README.md @@ -112,63 +100,69 @@ class Image(_SQLBase): ) ) - -''' -# TODO: I was attempting to avoid writing a class to see if I could, but it is not worth the clunk. -Rewrite these functions into a class. -''' - -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) - - _SQLBase.metadata.create_all(_engine) - _db_session_maker.configure(bind=_engine) - _configured = True - -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) - - for key, value in constraints.items(): - query = query.filter(getattr(table_object, key).ilike('%%%s%%' % value)) - - item_list = [] - for item in query: - item_list.append(item) - - return item_list - -@contextlib.contextmanager -def get_db_session(): - '''Get a SQLAlchemy database session with a proper context object. ''' - # TODO: There's probably a more reliable way of knowing whether the database was configured. - if not _configured: - raise MetadataDBSessionException('Tried to get session without configuring a database.') - - session = _db_session_maker() - try: - yield session - - except: - # TODO: Decide which exceptions to handle/eat here and which ones belong in UI. - # This one is okay to put off until you start really building UI. - session.rollback() - raise - else: - session.commit() - finally: - session.close() +class hashdb: + _engine = None + + # TODO: db_path's default should be set here, not in frontend. + def __init__(self, db_path): + ''' + Configure and initialize the database for the entire module. + Currently, only SQLite is supported. + + db_path: Path for the SQLite database + ''' + self._engine = sqlalchemy.create_engine('sqlite:///%s' % db_path) + + _SQLBase.metadata.create_all(self._engine) + self._session_maker.configure(bind=self._engine) + + def search(self, table_object, **constraints): + ''' + Search the database for entries matching the given constraints. + + 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. + ''' + + with self._get_db_session() as session: + # TODO: Consider making this return data recursively on items that reference other + # tables. + query = session.query(table_object) + + for key, value in constraints.items(): + query = query.filter(getattr(table_object, key).ilike('%%%s%%' % value)) + + item_list = [] + for item in query: + item_list.append(item) + + return item_list + + def import_json(self, json_file): + ''' + Import metadata from a json file. + ''' + + # json files can be large, but not too large for ram + # do not exit on invalid metadata, log the error and skip the object + pass + + @contextlib.contextmanager + def _get_db_session(): + '''Get a SQLAlchemy database session with a proper context object. ''' + + session = sqlalchemy.orm.sessionmaker() + try: + yield session + + except: + # TODO: Decide which exceptions to handle/eat here and which ones belong in UI. + # This one is okay to put off until you start really building UI. + session.rollback() + raise + else: + session.commit() + finally: + session.close()