1from functools import wraps
2
3from Orange.widgets.utils.messages import UnboundMsg
4from Orange.data import Table
5from Orange.data.sql.table import SqlTable, AUTO_DL_LIMIT
6
7_download_sql_data = UnboundMsg(
8    "Download (and sample if necessary) the SQL data first")
9
10
11def check_sql_input(f):
12    """
13    Wrapper for widget's set_data method that first checks if the input
14    is a SqlTable and:
15    - if small enough, download all data and convert to Table
16    - for large sql tables, show an error
17
18    :param f: widget's `set_data` method to wrap
19    :return: wrapped method that handles SQL data inputs
20    """
21    @wraps(f)
22    def new_f(widget, data, *args, **kwargs):
23        widget.Error.add_message("download_sql_data", _download_sql_data)
24        widget.Error.download_sql_data.clear()
25        if isinstance(data, SqlTable):
26            if data.approx_len() < AUTO_DL_LIMIT:
27                data = Table(data)
28            else:
29                widget.Error.download_sql_data()
30                data = None
31        return f(widget, data, *args, **kwargs)
32
33    return new_f
34