# Path: tasks/meta.py
# class CurrentSession(object):
# 
#     def __init__(self, async_conn=False):
#         self._session = None
#         self._pid = None
#         self._async_conn = False
#         # https://docs.python.org/3/howto/logging.html#optimization
#         self.debug_logging_enabled = LOGGER.isEnabledFor(DEBUG)
# 
#     def begin(self):
#         if not self._session:
#             self._session = sessionmaker(bind=get_engine())()
#         self._pid = os.getpid()
# 
#     def get(self):
#         # If we forked, there would be a PID mismatch and we need a new
#         # connection
#         if self._pid != os.getpid():
#             self._session = None
#             LOGGER.debug('FORKED: {} not {}'.format(self._pid, os.getpid()))
#         if not self._session:
#             self.begin()
#         try:
#             self._session.execute("SELECT 1")
#             # Useful for debugging. This is called thousands of times
#             if self.debug_logging_enabled:
#                 curframe = inspect.currentframe()
#                 calframe = inspect.getouterframes(curframe, 2)
#                 callers = ' <- '.join([c[3] for c in calframe[1:9]])
#                 # TODO: don't know why, `.debug` won't work at this point
#                 LOGGER.info('callers: {}'.format(callers))
#         except:
#             self._session = None
#             self.begin()
#         return self._session
# 
#     def commit(self):
#         if self._pid != os.getpid():
#             raise Exception('cannot commit forked connection')
#         if not self._session:
#             return
#         try:
#             self._session.commit()
#         except:
#             self._session.rollback()
#             self._session.expunge_all()
#             raise
#         finally:
#             self._session.close()
#             self._session = None
# 
#     def rollback(self):
#         if self._pid != os.getpid():
#             raise Exception('cannot rollback forked connection')
#         if not self._session:
#             return
#         try:
#             self._session.rollback()
#         except:
#             raise
#         finally:
#             self._session.expunge_all()
#             self._session.close()
#             self._session = None


import argparse
import os
import json
from tasks.meta import CurrentSession

    exclusions = exclusions_string.split(',') if exclusions_string else []

    if len(id) < MINIMUM_ID_LENGTH:
        print("The identifier '{}' is too short (minimum {} characters)".format(id, MINIMUM_ID_LENGTH))
        return

    session = CurrentSession().get()

    id_query = "id LIKE '{}%'".format(id)
    if exclusions:
        exclusions_quoted = ','.join(["'{}%'".format(e) for e in exclusions])
        id_query += ' AND id NOT LIKE ALL(ARRAY[{}])'.format(exclusions_quoted)

    numtables = session.execute(
        "SELECT count(*) FROM observatory.obs_table WHERE {}"
        .format(id_query)).fetchone()[0]
    print(" --> This will delete {} entries from observatory.OBS_TABLE".format(numtables))
    for table in session.execute("SELECT id FROM observatory.obs_table WHERE {}".format(id_query)).fetchall():
        print("\t" + table[0])

    numcols = session.execute(
        "SELECT count(*) FROM observatory.obs_column WHERE {}"
        .format(id_query)).fetchone()[0]
    print(" --> This will delete {} entries from observatory.OBS_COLUMNS".format(numcols))
    for column in session.execute(
            "SELECT id FROM observatory.obs_column WHERE {}".format(id_query)).fetchmany(MAX_COLS_TO_PRINT):
        print("\t" + column[0])
    if numcols > MAX_COLS_TO_PRINT:
        print("\t... ({} more)".format(numcols - MAX_COLS_TO_PRINT))

# Path: tasks/meta.py
# class CurrentSession(object):
# 
#     def __init__(self, async_conn=False):
#         self._session = None
#         self._pid = None
#         self._async_conn = False
#         # https://docs.python.org/3/howto/logging.html#optimization
#         self.debug_logging_enabled = LOGGER.isEnabledFor(DEBUG)
# 
#     def begin(self):
#         if not self._session:
#             self._session = sessionmaker(bind=get_engine())()
#         self._pid = os.getpid()
# 
#     def get(self):
#         # If we forked, there would be a PID mismatch and we need a new
#         # connection
#         if self._pid != os.getpid():
#             self._session = None
#             LOGGER.debug('FORKED: {} not {}'.format(self._pid, os.getpid()))
#         if not self._session:
#             self.begin()
#         try:
#             self._session.execute("SELECT 1")
#             # Useful for debugging. This is called thousands of times
#             if self.debug_logging_enabled:
#                 curframe = inspect.currentframe()
#                 calframe = inspect.getouterframes(curframe, 2)
#                 callers = ' <- '.join([c[3] for c in calframe[1:9]])
#                 # TODO: don't know why, `.debug` won't work at this point
#                 LOGGER.info('callers: {}'.format(callers))
#         except:
#             self._session = None
#             self.begin()
#         return self._session
# 
#     def commit(self):
#         if self._pid != os.getpid():
#             raise Exception('cannot commit forked connection')
#         if not self._session:
#             return
#         try:
#             self._session.commit()
#         except:
#             self._session.rollback()
#             self._session.expunge_all()
#             raise
#         finally:
#             self._session.close()
#             self._session = None
# 
#     def rollback(self):
#         if self._pid != os.getpid():
#             raise Exception('cannot rollback forked connection')
#         if not self._session:
#             return
#         try:
#             self._session.rollback()
#         except:
#             raise
#         finally:
#             self._session.expunge_all()
#             self._session.close()
#             self._session = None


# Path: tasks/tools.py
import argparse
import os
import json
from tasks.meta import CurrentSession


    exclusions = exclusions_string.split(',') if exclusions_string else []

    if len(id) < MINIMUM_ID_LENGTH:
        print("The identifier '{}' is too short (minimum {} characters)".format(id, MINIMUM_ID_LENGTH))
        return

    session = CurrentSession().get()

    id_query = "id LIKE '{}%'".format(id)
    if exclusions:
        exclusions_quoted = ','.join(["'{}%'".format(e) for e in exclusions])
        id_query += ' AND id NOT LIKE ALL(ARRAY[{}])'.format(exclusions_quoted)

    numtables = session.execute(
        "SELECT count(*) FROM observatory.obs_table WHERE {}"
        .format(id_query)).fetchone()[0]
    print(" --> This will delete {} entries from observatory.OBS_TABLE".format(numtables))
    for table in session.execute("SELECT id FROM observatory.obs_table WHERE {}".format(id_query)).fetchall():
        print("\t" + table[0])

    numcols = session.execute(
        "SELECT count(*) FROM observatory.obs_column WHERE {}"
        .format(id_query)).fetchone()[0]
    print(" --> This will delete {} entries from observatory.OBS_COLUMNS".format(numcols))
    for column in session.execute(
            "SELECT id FROM observatory.obs_column WHERE {}".format(id_query)).fetchmany(MAX_COLS_TO_PRINT):
        print("\t" + column[0])
    if numcols > MAX_COLS_TO_PRINT:
        print("\t... ({} more)".format(numcols - MAX_COLS_TO_PRINT))

    print(" --> This will drop {} tables from the 'observatory' schema".format(session.execute(