Repository: pymedusa/Medusa

Issue:
[APP SUBMITTED]: sqlite3.OperationalError: near "WHERE": syntax error

### INFO
**Python Version**: `3.9.13 (main, May 24 2022, 21:28:44) [Clang 13.0.0 (clang-1300.0.29.30)]`
**Operating System**: `macOS-11.6.7-x86_64-i386-64bit`
**Locale**: `UTF-8`
**Branch**: [develop](../tree/develop)
**Database**: `44.19`
**Commit**: pymedusa/Medusa@135a704943350809d166e26c3751c5738472af97
**Link to Log**: https://gist.github.com/16f0cc444ec4bbf9aecc0f59c756cab4
### ERROR
<pre>
2022-07-19 04:04:02 ERROR    APIv2-Thread_0 :: [135a704] DB error: near "WHERE": syntax error
Traceback (most recent call last):
  File "/Users/ovidijus/Apps/Medusa/<a href="../blob/135a704943350809d166e26c3751c5738472af97/medusa/db.py#L285">medusa/db.py</a>", line 285, in action
    sql_results = self._execute(query, args, fetchall=fetchall, fetchone=fetchone)
  File "/Users/ovidijus/Apps/Medusa/<a href="../blob/135a704943350809d166e26c3751c5738472af97/medusa/db.py#L115">medusa/db.py</a>", line 115, in _execute
    sql_results = cursor.execute(query, args)
sqlite3.OperationalError: near "WHERE": syntax error
</pre>
---
_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators



Discussion:

Resolving patch:
diff --git a/medusa/server/api/v2/history.py b/medusa/server/api/v2/history.py
--- a/medusa/server/api/v2/history.py
+++ b/medusa/server/api/v2/history.py
@@ -3,11 +3,13 @@
 from __future__ import unicode_literals
 
 import json
+import logging
 from os.path import basename
 
 from medusa import db
 from medusa.common import DOWNLOADED, FAILED, SNATCHED, SUBTITLED, statusStrings
 from medusa.indexers.utils import indexer_id_to_name
+from medusa.logger.adapters.style import BraceAdapter
 from medusa.providers import get_provider_class
 from medusa.providers.generic_provider import GenericProvider
 from medusa.schedulers.download_handler import ClientStatus
@@ -15,6 +17,10 @@
 from medusa.tv.series import Series, SeriesIdentifier
 
 
+log = BraceAdapter(logging.getLogger(__name__))
+log.logger.addHandler(logging.NullHandler())
+
+
 class HistoryHandler(BaseRequestHandler):
     """History request handler."""
 
@@ -60,6 +66,7 @@ def get(self, series_slug, path_param):
             return self._ok(data=results[0])
 
         where = []
+        where_with_ops = []
 
         if series_slug is not None:
             series_identifier = SeriesIdentifier.from_slug(series_slug)
@@ -102,24 +109,32 @@ def get(self, series_slug, path_param):
                 where += [filter_field]
                 params += [filter_value]
 
-        if where:
-            sql_base += ' WHERE ' + ' AND '.join(f'{item} = ?' for item in where)
-
         # Add size query (with operator)
         if size_operator and size:
-            sql_base += f' {"AND" if where else "WHERE"} size {size_operator} ?'
-            params.append(int(size) * 1024 * 1024)
+            try:
+                size = int(size) * 1024 * 1024
+                where_with_ops += [f' size {size_operator} ? ']
+                params.append(size)
+            except ValueError:
+                log.info('Could not parse {size} into a valid number', {'size': size})
 
         # Add provider with like %provider%
         if provider:
-            sql_base += f' {"AND" if where else "WHERE"} provider LIKE ?'
+            where_with_ops += [' provider LIKE ? ']
             params.append(f'%%{provider}%%')
 
         # Search resource with like %resource%
         if resource:
-            sql_base += f' {"AND" if where else "WHERE"} resource LIKE ?'
+            where_with_ops += [' resource LIKE ? ']
             params.append(f'%%{resource}%%')
 
+        if where:
+            sql_base += ' WHERE ' + ' AND '.join(f'{item} = ?' for item in where)
+
+        if where_with_ops:
+            sql_base += ' WHERE ' if not where else ' AND '
+            sql_base += ' AND '.join(where_with_ops)
+
         if sort is not None and len(sort) == 1:  # Only support one sort column right now.
             field = sort[0].get('field').lower()
             order = sort[0].get('type')


Test patch: