1 | from collections import defaultdict |
---|
2 | from .._compat import with_metaclass, iteritems |
---|
3 | from .._gae import gae |
---|
4 | from ..helpers._internals import Dispatcher |
---|
5 | |
---|
6 | |
---|
7 | parsers = Dispatcher("parser") |
---|
8 | |
---|
9 | |
---|
10 | class for_type(object): |
---|
11 | def __init__(self, field_type): |
---|
12 | self.field_type = field_type |
---|
13 | |
---|
14 | def __call__(self, f): |
---|
15 | self.f = f |
---|
16 | return self |
---|
17 | |
---|
18 | |
---|
19 | class before_parse(object): |
---|
20 | def __init__(self, field_type): |
---|
21 | self.field_type = field_type |
---|
22 | |
---|
23 | def __call__(self, f): |
---|
24 | self.f = f |
---|
25 | return self |
---|
26 | |
---|
27 | |
---|
28 | class MetaParser(type): |
---|
29 | def __new__(cls, name, bases, attrs): |
---|
30 | new_class = type.__new__(cls, name, bases, attrs) |
---|
31 | if bases == (object,): |
---|
32 | return new_class |
---|
33 | #: collect declared attributes |
---|
34 | parsers = {} |
---|
35 | before = {} |
---|
36 | for key, value in list(attrs.items()): |
---|
37 | if isinstance(value, for_type): |
---|
38 | parsers[key] = value |
---|
39 | elif isinstance(value, before_parse): |
---|
40 | before[key] = value |
---|
41 | #: get super declared attributes |
---|
42 | declared_parsers = {} |
---|
43 | declared_before = {} |
---|
44 | for base in reversed(new_class.__mro__[1:]): |
---|
45 | if hasattr(base, "_declared_parsers_"): |
---|
46 | declared_parsers.update(base._declared_parsers_) |
---|
47 | if hasattr(base, "_declared_before_"): |
---|
48 | declared_before.update(base._declared_before_) |
---|
49 | #: set parsers |
---|
50 | declared_parsers.update(parsers) |
---|
51 | declared_before.update(before) |
---|
52 | new_class._declared_parsers_ = declared_parsers |
---|
53 | new_class._declared_before_ = declared_before |
---|
54 | return new_class |
---|
55 | |
---|
56 | |
---|
57 | class ParserMethodWrapper(object): |
---|
58 | def __init__(self, parser, f, extra=None): |
---|
59 | self.parser = parser |
---|
60 | self.f = f |
---|
61 | if extra: |
---|
62 | self.extra = extra |
---|
63 | self.call = self._call_with_extras |
---|
64 | else: |
---|
65 | self.call = self._call |
---|
66 | |
---|
67 | def _call_with_extras(self, value, field_type): |
---|
68 | extras = self.extra(self.parser, field_type) |
---|
69 | return self.f(self.parser, value, **extras) |
---|
70 | |
---|
71 | def _call(self, value, field_type): |
---|
72 | return self.f(self.parser, value) |
---|
73 | |
---|
74 | def __call__(self, value, field_type): |
---|
75 | return self.call(value, field_type) |
---|
76 | |
---|
77 | |
---|
78 | class Parser(with_metaclass(MetaParser)): |
---|
79 | def __init__(self, adapter): |
---|
80 | self.adapter = adapter |
---|
81 | self.dialect = adapter.dialect |
---|
82 | self._before_registry_ = {} |
---|
83 | for name, obj in iteritems(self._declared_before_): |
---|
84 | self._before_registry_[obj.field_type] = obj.f |
---|
85 | self.registered = defaultdict(lambda self=self: self._default) |
---|
86 | for name, obj in iteritems(self._declared_parsers_): |
---|
87 | if obj.field_type in self._before_registry_: |
---|
88 | self.registered[obj.field_type] = ParserMethodWrapper( |
---|
89 | self, obj.f, self._before_registry_[obj.field_type] |
---|
90 | ) |
---|
91 | else: |
---|
92 | self.registered[obj.field_type] = ParserMethodWrapper(self, obj.f) |
---|
93 | |
---|
94 | def _default(self, value, field_type): |
---|
95 | return value |
---|
96 | |
---|
97 | def parse(self, value, field_itype, field_type): |
---|
98 | return self.registered[field_itype](value, field_type) |
---|
99 | |
---|
100 | |
---|
101 | from .base import BasicParser |
---|
102 | from .sqlite import SQLiteParser |
---|
103 | from .postgre import PostgreParser |
---|
104 | from .mongo import MongoParser |
---|
105 | from .oracle import OracleParser |
---|
106 | |
---|
107 | if gae is not None: |
---|
108 | from .google import GoogleDatastoreParser |
---|