source: OpenRLabs-Git/deploy/rlabs-docker/web2py-rlabs/gluon/packages/dal/pydal/parsers/__init__.py

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100755
File size: 3.3 KB
Line 
1from collections import defaultdict
2from .._compat import with_metaclass, iteritems
3from .._gae import gae
4from ..helpers._internals import Dispatcher
5
6
7parsers = Dispatcher("parser")
8
9
10class 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
19class 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
28class 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
57class 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
78class 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
101from .base import BasicParser
102from .sqlite import SQLiteParser
103from .postgre import PostgreParser
104from .mongo import MongoParser
105from .oracle import OracleParser
106
107if gae is not None:
108    from .google import GoogleDatastoreParser
Note: See TracBrowser for help on using the repository browser.