Support units in filters

This commit is contained in:
Russ Garrett 2018-04-14 11:41:27 +01:00
commit ab85605c61
No known key found for this signature in database
GPG key ID: 68880BB652AB0570
2 changed files with 23 additions and 4 deletions

View file

@ -647,7 +647,9 @@ class TableView(RowTableShared):
forward_querystring=False forward_querystring=False
) )
filters = Filters(sorted(other_args.items())) units = self.table_metadata(name, table).get('units', {})
filters = Filters(sorted(other_args.items()), units, ureg)
where_clauses, params = filters.build_where_clauses() where_clauses, params = filters.build_where_clauses()
# _search support: # _search support:
@ -891,7 +893,7 @@ class TableView(RowTableShared):
'filtered_table_rows_count': filtered_table_rows_count, 'filtered_table_rows_count': filtered_table_rows_count,
'columns': columns, 'columns': columns,
'primary_keys': pks, 'primary_keys': pks,
'units': self.table_metadata(name, table).get('units', {}), 'units': units,
'query': { 'query': {
'sql': sql, 'sql': sql,
'params': params, 'params': params,

View file

@ -10,6 +10,7 @@ import tempfile
import time import time
import shutil import shutil
import urllib import urllib
import numbers
# From https://www.sqlite.org/lang_keywords.html # From https://www.sqlite.org/lang_keywords.html
@ -459,8 +460,10 @@ class Filters:
f.key: f for f in _filters f.key: f for f in _filters
} }
def __init__(self, pairs): def __init__(self, pairs, units={}, ureg=None):
self.pairs = pairs self.pairs = pairs
self.units = units
self.ureg = ureg
def lookups(self): def lookups(self):
"Yields (lookup, display, no_argument) pairs" "Yields (lookup, display, no_argument) pairs"
@ -500,13 +503,27 @@ class Filters:
def has_selections(self): def has_selections(self):
return bool(self.pairs) return bool(self.pairs)
def convert_unit(self, column, value):
"If the user has provided a unit in the quey, convert it into the column unit, if present."
if column not in self.units:
return value
# Try to interpret the value as a unit
value = self.ureg(value)
if isinstance(value, numbers.Number):
# It's just a bare number, assume it's the column unit
return value
column_unit = self.ureg(self.units[column])
return value.to(column_unit).magnitude
def build_where_clauses(self): def build_where_clauses(self):
sql_bits = [] sql_bits = []
params = {} params = {}
for i, (column, lookup, value) in enumerate(self.selections()): for i, (column, lookup, value) in enumerate(self.selections()):
filter = self._filters_by_key.get(lookup, None) filter = self._filters_by_key.get(lookup, None)
if filter: if filter:
sql_bit, param = filter.where_clause(column, value, i) sql_bit, param = filter.where_clause(column, self.convert_unit(column, value), i)
sql_bits.append(sql_bit) sql_bits.append(sql_bit)
if param is not None: if param is not None:
param_id = 'p{}'.format(i) param_id = 'p{}'.format(i)