@@ -44,8 +44,19 @@ def __init__(self, database, document_id=None):
4444 if document_id and not document_id .startswith ('_design/' ):
4545 document_id = '_design/{0}' .format (document_id )
4646 super (DesignDocument , self ).__init__ (database , document_id )
47- self .setdefault ('views' , dict ())
48- self .setdefault ('indexes' , dict ())
47+ self ._nested_object_names = frozenset (['views' , 'indexes' , 'lists' ])
48+ for prop in self ._nested_object_names :
49+ self .setdefault (prop , dict ())
50+
51+ @property
52+ def lists (self ):
53+ """
54+ Provides an accessor property to the lists dictionary in the locally
55+ cached DesignDocument.
56+
57+ :returns: Dictionary containing list names and objects as key/value
58+ """
59+ return self .get ('lists' )
4960
5061 @property
5162 def rewrites (self ):
@@ -149,6 +160,21 @@ def add_search_index(self, index_name, search_func, analyzer=None):
149160
150161 self .indexes .__setitem__ (index_name , search )
151162
163+ def add_list_function (self , list_name , list_func ):
164+ """
165+ Appends a list function to the locally cached DesignDocument
166+ indexes dictionary.
167+
168+ :param str list_name: Name used to identify the list function.
169+ :param str list_func: Javascript list function.
170+ """
171+ if self .get_list_function (list_name ) is not None :
172+ msg = ('A list with name {0} already exists in this design doc'
173+ .format (list_name ))
174+ raise CloudantArgumentError (msg )
175+
176+ self .lists .__setitem__ (list_name , codify (list_func ))
177+
152178 def update_view (self , view_name , map_func , reduce_func = None , ** kwargs ):
153179 """
154180 Modifies/overwrites an existing MapReduce view definition in the
@@ -195,6 +221,21 @@ def update_search_index(self, index_name, search_func, analyzer=None):
195221
196222 self .indexes .__setitem__ (index_name , search )
197223
224+ def update_list_function (self , list_name , list_func ):
225+ """
226+ Modifies/overwrites an existing list function in the
227+ locally cached DesignDocument indexes dictionary.
228+
229+ :param str list_name: Name used to identify the list function.
230+ :param str list_func: Javascript list function.
231+ """
232+ if self .get_list_function (list_name ) is None :
233+ msg = ('A list with name {0} does not exist in this design doc'
234+ .format (list_name ))
235+ raise CloudantArgumentError (msg )
236+
237+ self .lists .__setitem__ (list_name , codify (list_func ))
238+
198239 def delete_view (self , view_name ):
199240 """
200241 Removes an existing MapReduce view definition from the locally cached
@@ -227,6 +268,15 @@ def delete_index(self, index_name):
227268
228269 self .indexes .__delitem__ (index_name )
229270
271+ def delete_list_function (self , list_name ):
272+ """
273+ Removes an existing list function in the locally cached DesignDocument
274+ lists dictionary.
275+
276+ :param str list_name: Name used to identify the list.
277+ """
278+ self .lists .__delitem__ (list_name )
279+
230280 def fetch (self ):
231281 """
232282 Retrieves the remote design document content and populates the locally
@@ -236,10 +286,7 @@ def fetch(self):
236286 ``dict`` types.
237287 """
238288 super (DesignDocument , self ).fetch ()
239- if not self .views :
240- # Ensure views dict exists in locally cached DesignDocument.
241- self .setdefault ('views' , dict ())
242- else :
289+ if self .views :
243290 for view_name , view_def in iteritems_ (self .get ('views' , dict ())):
244291 if self .get ('language' , None ) != QUERY_LANGUAGE :
245292 self ['views' ][view_name ] = View (
@@ -258,11 +305,11 @@ def fetch(self):
258305 ** view_def
259306 )
260307
261- if not self .indexes :
262- # Ensure indexes dict exists in locally cached DesignDocument.
263- self .setdefault ('indexes' , dict ())
308+ for prop in self ._nested_object_names :
309+ # Ensure views, indexes, and lists dict exist in locally cached DesignDocument.
310+ getattr ( self , prop , self .setdefault (prop , dict () ))
264311
265- # pylint: disable-msg =too-many-branches
312+ # pylint: disable=too-many-branches
266313 def save (self ):
267314 """
268315 Saves changes made to the locally cached DesignDocument object's data
@@ -285,9 +332,6 @@ def save(self):
285332 'View {0} must be of type QueryIndexView.'
286333 ).format (view_name )
287334 raise CloudantException (msg )
288- else :
289- # Ensure empty views dict is not saved remotely.
290- self .__delitem__ ('views' )
291335
292336 if self .indexes :
293337 if self .get ('language' , None ) != QUERY_LANGUAGE :
@@ -307,18 +351,17 @@ def save(self):
307351 'be of type dict.'
308352 ).format (index_name )
309353 raise CloudantException (msg )
310- else :
311- # Ensure empty indexes dict is not saved remotely.
312- self .__delitem__ ('indexes' )
354+
355+ for prop in self ._nested_object_names :
356+ if not getattr (self , prop ):
357+ # Ensure empty views, indexes, or lists dict is not saved remotely.
358+ self .__delitem__ (prop )
313359
314360 super (DesignDocument , self ).save ()
315361
316- if not self .views :
317- # Ensure views dict exists in locally cached DesignDocument.
318- self .setdefault ('views' , dict ())
319- if not self .indexes :
320- # Ensure indexes dict exists in locally cached DesignDocument.
321- self .setdefault ('indexes' , dict ())
362+ for prop in self ._nested_object_names :
363+ # Ensure views, indexes, and lists dict exist in locally cached DesignDocument.
364+ getattr (self , prop , self .setdefault (prop , dict ()))
322365
323366 def __setitem__ (self , key , value ):
324367 """
@@ -368,6 +411,17 @@ def iterindexes(self):
368411 for index_name , search_func in iteritems_ (self .indexes ):
369412 yield index_name , search_func
370413
414+ def iterlists (self ):
415+ """
416+ Provides a way to iterate over the locally cached DesignDocument
417+ lists dictionary.
418+
419+ :returns: Iterable containing list function name and associated
420+ list function
421+ """
422+ for list_name , list_func in iteritems_ (self .lists ):
423+ yield list_name , list_func
424+
371425 def list_views (self ):
372426 """
373427 Retrieves a list of available View objects in the locally cached
@@ -386,6 +440,15 @@ def list_indexes(self):
386440 """
387441 return list (self .indexes .keys ())
388442
443+ def list_list_functions (self ):
444+ """
445+ Retrieves a list of available list functions in the locally cached
446+ DesignDocument lists dictionary.
447+
448+ :returns: List of list function names
449+ """
450+ return list (self .lists .keys ())
451+
389452 def get_view (self , view_name ):
390453 """
391454 Retrieves a specific View from the locally cached DesignDocument by
@@ -408,6 +471,17 @@ def get_index(self, index_name):
408471 """
409472 return self .indexes .get (index_name )
410473
474+ def get_list_function (self , list_name ):
475+ """
476+ Retrieves a specific list function from the locally cached DesignDocument
477+ lists dictionary by name.
478+
479+ :param str list_name: Name used to identify the list function.
480+
481+ :returns: Index dictionary for the specified list function name
482+ """
483+ return self .lists .get (list_name )
484+
411485 def info (self ):
412486 """
413487 Retrieves the design document view information data, returns dictionary
0 commit comments