2
2
Contains the :class:`base class <tinydb.middlewares.Middleware>` for
3
3
middlewares and implementations.
4
4
"""
5
+ from tinydb import TinyDB
6
+ from tinydb .storages import JSONStorage
5
7
6
8
7
9
class Middleware (object ):
@@ -17,7 +19,7 @@ class Middleware(object):
17
19
example).
18
20
"""
19
21
20
- def __init__ (self , storage_cls ):
22
+ def __init__ (self , storage_cls = TinyDB . DEFAULT_STORAGE ):
21
23
self ._storage_cls = storage_cls
22
24
self .storage = None
23
25
@@ -84,7 +86,7 @@ class CachingMiddleware(Middleware):
84
86
#: The number of write operations to cache before writing to disc
85
87
WRITE_CACHE_SIZE = 1000
86
88
87
- def __init__ (self , storage_cls ):
89
+ def __init__ (self , storage_cls = TinyDB . DEFAULT_STORAGE ):
88
90
super (CachingMiddleware , self ).__init__ (storage_cls )
89
91
90
92
self .cache = None
@@ -116,3 +118,75 @@ def flush(self):
116
118
def close (self ):
117
119
self .flush ()
118
120
self .storage .close ()
121
+
122
+
123
+ class SerializationMiddleware (Middleware ):
124
+ """
125
+ Provide custom serialization for TinyDB.
126
+
127
+ This middleware allows users of TinyDB to register custom serializations.
128
+ The serialized data will be passed to the wrapped storage and data that
129
+ is read from the storage will be deserialized.
130
+ """
131
+
132
+ def __init__ (self , storage_cls = TinyDB .DEFAULT_STORAGE ):
133
+ super (SerializationMiddleware , self ).__init__ (storage_cls )
134
+
135
+ self ._serializers = {}
136
+
137
+ def register_serializer (self , serializer , name ):
138
+ """
139
+ Register a new Serializer.
140
+
141
+ When reading from/writing to the underlying storage, TinyDB
142
+ will run all objects through the list of registered serializers
143
+ allowing each one to handle objects it recognizes.
144
+
145
+ .. note:: The name has to be unique among this database instance.
146
+ Re-using the same name will overwrite the old serializer.
147
+ Also, registering a serializer will be reflected in all
148
+ tables when reading/writing them.
149
+
150
+ :param serializer: an instance of the serializer
151
+ :type serializer: tinydb.serialize.Serializer
152
+ """
153
+ self ._serializers [name ] = serializer
154
+
155
+ def read (self ):
156
+ data = self .storage .read ()
157
+
158
+ for serializer_name in self ._serializers :
159
+ serializer = self ._serializers [serializer_name ]
160
+ tag = '{{{}}}:' .format (serializer_name ) # E.g: '{TinyDate}:'
161
+
162
+ for eid in data :
163
+ for field in data [eid ]:
164
+ try :
165
+ if data [eid ][field ].startswith (tag ):
166
+ encoded = data [eid ][field ][len (tag ):]
167
+ data [eid ][field ] = serializer .decode (encoded )
168
+ except AttributeError :
169
+ pass # Not a string
170
+
171
+ return data
172
+
173
+ def write (self , data ):
174
+ for serializer_name in self ._serializers :
175
+ # If no serializers are registered, this code will just look up
176
+ # the serializer list and continue. But if there are serializers,
177
+ # the inner loop will run very often.
178
+ # For that reason, the lookup of the serialized class is pulled
179
+ # out into the outer loop:
180
+
181
+ serializer = self ._serializers [serializer_name ]
182
+ serializer_class = serializer .OBJ_CLASS
183
+
184
+ for eid in data :
185
+ for field in data [eid ]:
186
+ if isinstance (data [eid ][field ], serializer_class ):
187
+ encoded = serializer .encode (data [eid ][field ])
188
+ tagged = '{{{}}}:{}' .format (serializer_name , encoded )
189
+
190
+ data [eid ][field ] = tagged
191
+
192
+ self .storage .write (data )
0 commit comments