@@ -653,6 +653,14 @@ def splunk_version(self):
653653 self ._splunk_version = tuple ([int (p ) for p in self .info ['version' ].split ('.' )])
654654 return self ._splunk_version
655655
656+ @property
657+ def kvstore (self ):
658+ """Returns the collection of KV Store collections.
659+
660+ :return: A :class:`KVStoreCollections` collection of :class:`KVStoreCollection` entities.
661+ """
662+ return KVStoreCollections (self )
663+
656664 @property
657665 def users (self ):
658666 """Returns the collection of users.
@@ -3518,3 +3526,194 @@ def package(self):
35183526 def updateInfo (self ):
35193527 """Returns any update information that is available for the app."""
35203528 return self ._run_action ("update" )
3529+
3530+ class KVStoreCollections (Collection ):
3531+ def __init__ (self , service ):
3532+ Collection .__init__ (self , service , 'storage/collections/config' , item = KVStoreCollection )
3533+
3534+ def create (self , name , indexes = {}, fields = {}, ** kwargs ):
3535+ """Creates a KV Store Collection.
3536+
3537+ :param name: name of collection to create
3538+ :type name: ``string``
3539+ :param indexes: dictionary of index definitions
3540+ :type indexes: ``dict``
3541+ :param fields: dictionary of field definitions
3542+ :type fields: ``dict``
3543+ :param kwargs: a dictionary of additional parameters specifying indexes and field definitions
3544+ :type kwargs: ``dict``
3545+
3546+ :return: Result of POST request
3547+ """
3548+ for k , v in indexes .iteritems ():
3549+ if isinstance (v , dict ):
3550+ v = json .dumps (v )
3551+ kwargs ['index.' + k ] = v
3552+ for k , v in fields .iteritems ():
3553+ kwargs ['field.' + k ] = v
3554+ return self .post (name = name , ** kwargs )
3555+
3556+ class KVStoreCollection (Entity ):
3557+ @property
3558+ def data (self ):
3559+ """Returns data object for this Collection.
3560+
3561+ :rtype: :class:`KVStoreData`
3562+ """
3563+ return KVStoreCollectionData (self )
3564+
3565+ def update_index (self , name , value ):
3566+ """Changes the definition of a KV Store index.
3567+
3568+ :param name: name of index to change
3569+ :type name: ``string``
3570+ :param value: new index definition
3571+ :type value: ``dict`` or ``string``
3572+
3573+ :return: Result of POST request
3574+ """
3575+ kwargs = {}
3576+ kwargs ['index.' + name ] = value if isinstance (value , basestring ) else json .dumps (value )
3577+ return self .post (** kwargs )
3578+
3579+ def update_field (self , name , value ):
3580+ """Changes the definition of a KV Store field.
3581+
3582+ :param name: name of field to change
3583+ :type name: ``string``
3584+ :param value: new field definition
3585+ :type value: ``string``
3586+
3587+ :return: Result of POST request
3588+ """
3589+ kwargs = {}
3590+ kwargs ['field.' + name ] = value
3591+ return self .post (** kwargs )
3592+
3593+ class KVStoreCollectionData (object ):
3594+ """This class represents the data endpoint for a KVStoreCollection.
3595+
3596+ Retrieve using :meth:`KVStoreCollection.data`
3597+ """
3598+ JSON_HEADER = [('Content-Type' , 'application/json' )]
3599+
3600+ def __init__ (self , collection ):
3601+ self .service = collection .service
3602+ self .collection = collection
3603+ self .owner , self .app , self .sharing = collection ._proper_namespace ()
3604+ self .path = 'storage/collections/data/' + UrlEncoded (self .collection .name ) + '/'
3605+
3606+ def _get (self , url , ** kwargs ):
3607+ return self .service .get (self .path + url , owner = self .owner , app = self .app , sharing = self .sharing , ** kwargs )
3608+
3609+ def _post (self , url , ** kwargs ):
3610+ return self .service .post (self .path + url , owner = self .owner , app = self .app , sharing = self .sharing , ** kwargs )
3611+
3612+ def _delete (self , url , ** kwargs ):
3613+ return self .service .delete (self .path + url , owner = self .owner , app = self .app , sharing = self .sharing , ** kwargs )
3614+
3615+ def query (self , ** query ):
3616+ """
3617+ Gets the results of query, with optional parameters sort, limit, skip, and fields.
3618+
3619+ :param query: Optional parameters. Valid options are sort, limit, skip, and fields
3620+ :type query: ``dict``
3621+
3622+ :return: Array of documents retrieved by query.
3623+ :rtype: ``array``
3624+ """
3625+ return json .loads (self ._get ('' , ** query ).body .read ())
3626+
3627+ def query_by_id (self , id ):
3628+ """
3629+ Returns object with _id = id.
3630+
3631+ :param id: Value for ID. If not a string will be coerced to string.
3632+ :type id: ``string``
3633+
3634+ :return: Document with id
3635+ :rtype: ``dict``
3636+ """
3637+ return json .loads (self ._get (UrlEncoded (str (id ))).body .read ())
3638+
3639+ def insert (self , data ):
3640+ """
3641+ Inserts item into this collection. An _id field will be generated if not assigned in the data.
3642+
3643+ :param data: Document to insert
3644+ :type data: ``string``
3645+
3646+ :return: _id of inserted object
3647+ :rtype: ``dict``
3648+ """
3649+ return json .loads (self ._post ('' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ())
3650+
3651+ def delete (self , query = None ):
3652+ """
3653+ Deletes all data in collection if query is absent. Otherwise, deletes all data matched by query.
3654+
3655+ :param query: Query to select documents to delete
3656+ :type query: ``string``
3657+
3658+ :return: Result of DELETE request
3659+ """
3660+ return self ._delete ('' , ** ({'query' : query }) if query else {})
3661+
3662+ def delete_by_id (self , id ):
3663+ """
3664+ Deletes document that has _id = id.
3665+
3666+ :param id: id of document to delete
3667+ :type id: ``string``
3668+
3669+ :return: Result of DELETE request
3670+ """
3671+ return self ._delete (UrlEncoded (str (id )))
3672+
3673+ def update (self , id , data ):
3674+ """
3675+ Replaces document with _id = id with data.
3676+
3677+ :param id: _id of document to update
3678+ :type id: ``string``
3679+ :param data: the new document to insert
3680+ :type data: ``string``
3681+
3682+ :return: id of replaced document
3683+ :rtype: ``dict``
3684+ """
3685+ return json .loads (self ._post (UrlEncoded (str (id )), headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ())
3686+
3687+ def batch_find (self , * dbqueries ):
3688+ """
3689+ Returns array of results from queries dbqueries.
3690+
3691+ :param dbqueries: Array of individual queries as dictionaries
3692+ :type dbqueries: ``array`` of ``dict``
3693+
3694+ :return: Results of each query
3695+ :rtype: ``array`` of ``array``
3696+ """
3697+ if len (dbqueries ) < 1 :
3698+ raise Exception ('Must have at least one query.' )
3699+
3700+ data = json .dumps (dbqueries )
3701+
3702+ return json .loads (self ._post ('batch_find' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ())
3703+
3704+ def batch_save (self , * documents ):
3705+ """
3706+ Inserts or updates every document specified in documents.
3707+
3708+ :param documents: Array of documents to save as dictionaries
3709+ :type documents: ``array`` of ``dict``
3710+
3711+ :return: Results of update operation as overall stats
3712+ :rtype: ``dict``
3713+ """
3714+ if len (documents ) < 1 :
3715+ raise Exception ('Must have at least one document.' )
3716+
3717+ data = json .dumps (documents )
3718+
3719+ return json .loads (self ._post ('batch_save' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ())
0 commit comments