From cb29e77a05a764bd92d5a0fd6cbf9987ca2c7dce Mon Sep 17 00:00:00 2001 From: James Turk Date: Mon, 28 Jun 2010 10:43:19 -0400 Subject: [PATCH] initial subrecord filter --- saucebrush/filters.py | 23 +++++++++++++++++++++++ saucebrush/tests/filters.py | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/saucebrush/filters.py b/saucebrush/filters.py index 525fe19..5df31a9 100644 --- a/saucebrush/filters.py +++ b/saucebrush/filters.py @@ -122,6 +122,29 @@ class ValidationError(Exception): super(ValidationError, self).__init__(repr(record)) self.record = record +def _dotted_get(d, path): + if path: + key_pieces = path.split('.', 1) + piece = d[key_pieces[0]] + if isinstance(piece, (tuple, list)): + return [_dotted_get(i, '.'.join(key_pieces[1:])) for i in piece] + elif isinstance(piece, (dict)): + return _dotted_get(piece, '.'.join(key_pieces[1:])) + else: + return d + +class SubrecordFilter(Filter): + + def __init__(self, field_path, filter_): + self.field_path = field_path + self.filter = filter_ + + def process_record(self, record): + subrecord = _dotted_get(record, self.field_path) + for p in subrecord: + p = self.filter.process_record(p) + return record + ##################### ## Generic Filters ## ##################### diff --git a/saucebrush/tests/filters.py b/saucebrush/tests/filters.py index 7458df6..32ff19c 100644 --- a/saucebrush/tests/filters.py +++ b/saucebrush/tests/filters.py @@ -2,6 +2,7 @@ import unittest import operator import types from saucebrush.filters import (Filter, YieldFilter, FieldFilter, + SubrecordFilter, ConditionalFilter, FieldModifier, FieldRemover, FieldMerger, FieldAdder, FieldCopier, FieldRenamer, Unique) @@ -99,6 +100,24 @@ class FilterTestCase(unittest.TestCase): # ensure only even numbers remain self.assertEquals(list(result), [0,2,4,6,8]) + ### FILTERS FOR Subrecord + + def test_subrecord_filter(self): + data = [{'a': [{'b': 2}, {'b': 4}]}, + {'a': [{'b': 5}]}, + {'a': [{'b': 8}, {'b':2}, {'b':1}]}] + + + expected = [{'a': [{'b': 4}, {'b': 8}]}, + {'a': [{'b': 10}]}, + {'a': [{'b': 16}, {'b':4}, {'b':2}]}] + + sf = SubrecordFilter('a', FieldDoubler('b')) + result = sf.attach(data) + + self.assertEquals(list(result), expected) + + def test_field_modifier(self): # another version of FieldDoubler fm = FieldModifier(['a', 'c'], lambda x: x*2)