# Path: sacredboard/app/business/runfacade.py
# class RunFacade:
#     """Enables a more complex manipulation with Runs."""
# 
#     def __init__(self, datastorage: DataStorage):
#         self.datastorage = datastorage
# 
#     def delete_run(self, run_id):
#         """
#         Delete run of the given run_id.
# 
#         :raise NotImplementedError If not supported by the backend.
#         :raise DataSourceError General data source error.
#         :raise NotFoundError The run was not found. (Some backends may succeed even if the run does not exist.
#         """
#         ds = self.datastorage
#         ds.get_metrics_dao().delete(run_id)
#         # TODO: implement
#         # ds.get_artifact_dao().delete(run_id)
#         # ds.get_resource_dao().delete(run_id)
#         ds.get_run_dao().delete(run_id)
# 
# Path: sacredboard/app/data/errors.py
# class DataSourceError(Exception):
#     """Error when accessing the data source."""
# 
#     def __init__(self, *args, **kwargs):
#         """Error when accessing the data source."""
#         Exception.__init__(self, *args, **kwargs)
# 
# Path: sacredboard/app/data/datastorage.py
# class DataStorage:
#     """
#     Interface for data backends.
# 
#     Defines the API for various data stores
#     databases, file stores, etc. --- that sacred supports.
#     """
# 
#     def __init__(self):
#         """Initialize data accessor."""
#         pass
# 
#     def get_metrics_dao(self) -> MetricsDAO:
#         """
#         Return a data access object for metrics.
# 
#         By default, returns a dummy Data Access Object if not overridden.
#         Issue: https://github.com/chovanecm/sacredboard/issues/62
# 
#         :return MetricsDAO
#         """
#         return DummyMetricsDAO()
# 
#     def get_run_dao(self) -> RunDAO:
#         """
#         Return a data access object for Runs.
# 
#         :return: RunDAO
#         """
#         raise NotImplementedError(
#             "Run Data Access Object must be implemented.")
# 
#     def get_files_dao(self) -> FilesDAO:
#         """
#         Return a data access object for files.
# 
#         :return: FilesDAO
#         """
#         raise NotImplementedError(
#             "Artifacts Data Access Object must be implemented.")


import json
from flask import current_app, request, Response, render_template, Blueprint
from sacredboard.app.business import RunFacade
from sacredboard.app.data import DataSourceError, DataStorage
    draw = parse_int_arg("draw", 1)
    start = parse_int_arg("start", 0)
    length = parse_int_arg("length", -1)
    length = length if length >= 0 else None
    order_column = request.args.get("order[0][column]")
    order_dir = request.args.get("order[0][dir]")

    query = parse_query_filter()

    if order_column is not None:
        order_column = \
            request.args.get("columns[%d][name]" % int(order_column))
        if order_column == "hostname":
            order_column = "host.hostname"

    runs = data.get_run_dao().get_runs(
        start=start, limit=length,
        sort_by=order_column, sort_direction=order_dir, query=query)
    # records_total should be the total size of the records in the database,
    # not what was returned
    records_total = runs.count()
    records_filtered = runs.count()
    return Response(render_template(
        "api/runs.js", runs=runs,
        draw=draw, recordsTotal=records_total,
        recordsFiltered=records_filtered),
        mimetype="application/json")


@runs.errorhandler(DataSourceError)

# Path: sacredboard/app/business/runfacade.py
# class RunFacade:
#     """Enables a more complex manipulation with Runs."""
# 
#     def __init__(self, datastorage: DataStorage):
#         self.datastorage = datastorage
# 
#     def delete_run(self, run_id):
#         """
#         Delete run of the given run_id.
# 
#         :raise NotImplementedError If not supported by the backend.
#         :raise DataSourceError General data source error.
#         :raise NotFoundError The run was not found. (Some backends may succeed even if the run does not exist.
#         """
#         ds = self.datastorage
#         ds.get_metrics_dao().delete(run_id)
#         # TODO: implement
#         # ds.get_artifact_dao().delete(run_id)
#         # ds.get_resource_dao().delete(run_id)
#         ds.get_run_dao().delete(run_id)
# 
# Path: sacredboard/app/data/errors.py
# class DataSourceError(Exception):
#     """Error when accessing the data source."""
# 
#     def __init__(self, *args, **kwargs):
#         """Error when accessing the data source."""
#         Exception.__init__(self, *args, **kwargs)
# 
# Path: sacredboard/app/data/datastorage.py
# class DataStorage:
#     """
#     Interface for data backends.
# 
#     Defines the API for various data stores
#     databases, file stores, etc. --- that sacred supports.
#     """
# 
#     def __init__(self):
#         """Initialize data accessor."""
#         pass
# 
#     def get_metrics_dao(self) -> MetricsDAO:
#         """
#         Return a data access object for metrics.
# 
#         By default, returns a dummy Data Access Object if not overridden.
#         Issue: https://github.com/chovanecm/sacredboard/issues/62
# 
#         :return MetricsDAO
#         """
#         return DummyMetricsDAO()
# 
#     def get_run_dao(self) -> RunDAO:
#         """
#         Return a data access object for Runs.
# 
#         :return: RunDAO
#         """
#         raise NotImplementedError(
#             "Run Data Access Object must be implemented.")
# 
#     def get_files_dao(self) -> FilesDAO:
#         """
#         Return a data access object for files.
# 
#         :return: FilesDAO
#         """
#         raise NotImplementedError(
#             "Artifacts Data Access Object must be implemented.")


# Path: sacredboard/app/webapi/runs.py
import json
from flask import current_app, request, Response, render_template, Blueprint
from sacredboard.app.business import RunFacade
from sacredboard.app.data import DataSourceError, DataStorage

    draw = parse_int_arg("draw", 1)
    start = parse_int_arg("start", 0)
    length = parse_int_arg("length", -1)
    length = length if length >= 0 else None
    order_column = request.args.get("order[0][column]")
    order_dir = request.args.get("order[0][dir]")

    query = parse_query_filter()

    if order_column is not None:
        order_column = \
            request.args.get("columns[%d][name]" % int(order_column))
        if order_column == "hostname":
            order_column = "host.hostname"

    runs = data.get_run_dao().get_runs(
        start=start, limit=length,
        sort_by=order_column, sort_direction=order_dir, query=query)
    # records_total should be the total size of the records in the database,
    # not what was returned
    records_total = runs.count()
    records_filtered = runs.count()
    return Response(render_template(
        "api/runs.js", runs=runs,
        draw=draw, recordsTotal=records_total,
        recordsFiltered=records_filtered),
        mimetype="application/json")


@runs.errorhandler(DataSourceError)

def handle_data_source_error(e: DataSourceError):