mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Support units in filters
This commit is contained in:
parent
8bfeb98478
commit
ab85605c61
2 changed files with 23 additions and 4 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue