Juan Zacarias has proposed merging lp:~zorba-coders/zorba/couchbase-module-new-options into lp:zorba/couchbase-module.
Commit message: *Added new options to the cb:view Function: -"limit" option, allows the user to limit the numbers of results shown by the view -"stale" option, allows the user to specify when to update the view: update after the view is returned(default by couchbase), update before the view is returned, and don't update if the view function is called. *Added a new option to the cb:put-text and cb:put-binary Functions: -"wait" option, allows the user to wait for confirmation from couchbase that the key/value pair was stored in disk. Modified test view.xq using the new options so it doesn't fail when ran for the first time. Requested reviews: Sorin Marian Nasoi (sorin.marian.nasoi) Chris Hillery (ceejatec) For more details, see: https://code.launchpad.net/~zorba-coders/zorba/couchbase-module-new-options/+merge/143187 -- https://code.launchpad.net/~zorba-coders/zorba/couchbase-module-new-options/+merge/143187 Your team Zorba Coders is subscribed to branch lp:zorba/couchbase-module.
=== modified file 'examples/example.xq' --- examples/example.xq 2013-01-10 07:59:35 +0000 +++ examples/example.xq 2013-01-14 21:43:21 +0000 @@ -7,7 +7,7 @@ "password" : null, "bucket" : "default"}); variable $view-name := cb:create-view($instance, "zip", "zip", {"key" : "doc.state", "values" : "doc.pop"}); -variable $data := cb:view($instance, $view-name); +variable $data := cb:view($instance, $view-name, {"stale" : "false"}); for $d in jn:members($data("rows")) let $state := $d("key") group by $state === modified file 'src/couchbase.xq' --- src/couchbase.xq 2013-01-10 08:07:25 +0000 +++ src/couchbase.xq 2013-01-14 21:43:21 +0000 @@ -232,7 +232,10 @@ : @option "operation" type of operation, possible values are : "add", "replace", "set", "append" and "prepend". : @option "encoding" the encoding that should be used for the - : value (default is UTF-8). + : value (default is UTF-8). + : @option "wait" variable for setting if a wait for persistancy in + : the storing key is needed, possible values are "persist" + : and "false". : : @error cb:LCB0002 if any error occurs in the communication with : the server. @@ -241,6 +244,7 @@ : @error cb:CB0006 if the given encoding is not supported. : @error cb:CB0007 if any of the options is not supported. : @error cb:CB0009 if the given expiration time is not an xs:integer. + : @error cb:CB0011 if the stored Variable was not stored : : @return a empty sequence. :) @@ -286,6 +290,9 @@ : expiration time in seconds. : @option "operation" type of operation, possible values are : "add", "replace", "set", "append" and "prepend". + : @option "wait" variable for setting if a wait for persistancy in + : the storing key is needed, possible values are "persist" + : and "false". : : @error cb:LCB0002 if any error occurs in the communication with : the server. @@ -293,6 +300,7 @@ : of values. : @error cb:CB0007 if any of the options is not supported. : @error cb:CB0009 if the given expiration time is not an xs:integer. + : @error cb:CB0011 if the stored Variable was not stored : : @return a empty sequence. :) @@ -365,8 +373,18 @@ : (e.g. "_design/test/_view/vies"). : @param $options JSONiq object with additional options : - : @option "encoding" string with the name of the encoding of the returned - : strings (if not UTF-8). + : @option Json object whith options for the querying the view. available options: + : "encoding" string with the name of the encoding of the returned + : strings (if not UTF-8). + : "stale" option's value is a string with the type of stale to be used. + : Valid values: + : "ok" : the view is not updated + : "false" : the view is updated before the function view is executed, + : this options needs the key to be on disk before the call of the + : view function. + : "update_after" : the view is updated after the call of view + : "limit" option's value is an integer which sets a number of how many + : rows the view will show. : : @error cb:LCB0002 if any error occurs in the communication with : the server. === modified file 'src/couchbase.xq.src/couchbase.cpp' --- src/couchbase.xq.src/couchbase.cpp 2013-01-10 07:59:35 +0000 +++ src/couchbase.xq.src/couchbase.cpp 2013-01-14 21:43:21 +0000 @@ -190,6 +190,30 @@ return NULL; } +String + CouchbaseFunction::ViewOptions::getPathOptions() +{ + String lPathOptions("?"); + bool lAmp = false; + if (theStaleOption != "") + { + lPathOptions.append(theStaleOption); + lAmp = true; + } + if (theLimitOption != "") + { + if(lAmp) + lPathOptions.append("&"); + lPathOptions.append(theLimitOption); + lAmp = true; + } + + if (lPathOptions == "?") + lPathOptions = ""; + + return lPathOptions; +} + void CouchbaseFunction::ViewOptions::setOptions(Item& aOptions) { @@ -216,6 +240,42 @@ throwError("CB0006", lMsg.str().c_str()); } } + else if (lStrKey == "stale") + { + Item lValue = aOptions.getObjectValue(lStrKey); + String lString = lValue.getStringValue(); + if (lString == "false") + { + theStaleOption ="stale=false"; + } + else if (lString == "ok") + { + theStaleOption ="stale=ok"; + } + else if (lString == "update_after") + { + theStaleOption ="stale=update_after"; + } + else + { + std::ostringstream lMsg; + lMsg << lStrKey << "=" << lString << ": option not supported"; + throwError("CB0007", lMsg.str().c_str()); + } + } + else if (lStrKey == "limit") + { + Item lValue = aOptions.getObjectValue(lStrKey); + try + { + int lLimit = lValue.getIntValue(); + theLimitOption = "limit=" + lLimit; + } + catch (ZorbaException& e) + { + throwError("CB0009", " limit option must be an integer value"); + } + } else { std::ostringstream lMsg; @@ -371,6 +431,28 @@ throwError("CB0006", lMsg.str().c_str()); } } + else if (lStrKey == "wait") + { + Item lValue = aOptions.getObjectValue(lStrKey); + String lStrValue = lValue.getStringValue(); + std::transform( + lStrValue.begin(), lStrValue.end(), + lStrValue.begin(), tolower); + if (lStrValue == "persist") + { + theWaitType = CB_WAIT_PERSIST; + } + else if (lStrValue == "false") + { + theWaitType = CB_WAIT_FALSE; + } + else + { + std::ostringstream lMsg; + lMsg << lStrKey << "=" << lStrValue << " : option not supported"; + throwError("CB0007", lMsg.str().c_str()); + } + } else { std::ostringstream lMsg; @@ -731,6 +813,26 @@ /******************************************************************************* ******************************************************************************/ +void CouchbaseFunction::observe_callback(lcb_t instance, const void *cookie, lcb_error_t error, const lcb_observe_resp_t *resp) +{ + if (error != LCB_SUCCESS) + { + libCouchbaseError (instance, error); + } + + PutOptions* lWait = (PutOptions*) cookie; + //verify is coming from the master + if (resp->v.v0.from_master > 0) + { + lcb_observe_t lStatus = resp->v.v0.status;if (lStatus == LCB_OBSERVE_NOT_FOUND) + { + throwError("CB0011", "Variable stored not found."); + } + //check for flag of persisntancy + lWait->setWaiting(lStatus & LCB_OBSERVE_PERSISTED?false:true); + } +} + void CouchbaseFunction::put (lcb_t aInstance, Iterator_t aKeys, Iterator_t aValues, PutOptions aOptions) { lcb_error_t lError; @@ -800,9 +902,23 @@ { libCouchbaseError (aInstance, lError); } - - + //Wait for store lcb_wait(aInstance); + //Check if wait for disk + if (aOptions.getWaitType() != CB_WAIT_FALSE) + { + lcb_set_observe_callback(aInstance, observe_callback); + PutOptions* lOptions = &aOptions; + do { + lcb_observe_cmd_t lObserve; + lObserve.version = 0; + lObserve.v.v0.key = lStrKey.c_str(); + lObserve.v.v0.nkey = lStrKey.size(); + lcb_observe_cmd_t* lCommands[1] = { &lObserve }; + lcb_observe(aInstance, lOptions, 1, lCommands); + lcb_wait(aInstance); + }while(lOptions->isWaiting()); + } } if (aValues->next(lValue)) @@ -1005,19 +1121,23 @@ if (thePaths->next(lPath)) { ViewOptions* lOptions = &theOptions; - + String lPathOptions = lOptions->getPathOptions(); + String lPathString = lPath.getStringValue(); + if (lPathOptions != "") + { + lPathString.append(lPathOptions); + } lcb_http_request_t lReq; lcb_http_cmd_t lCmd; lCmd.version = 0; - lCmd.v.v0.path = lPath.getStringValue().c_str(); - lCmd.v.v0.npath = lPath.getStringValue().size(); + lCmd.v.v0.path = lPathString.c_str(); + lCmd.v.v0.npath = lPathString.size(); lCmd.v.v0.body = NULL; lCmd.v.v0.nbody = 0; lCmd.v.v0.method = LCB_HTTP_METHOD_GET; lCmd.v.v0.chunked = 1; lCmd.v.v0.content_type = "application/json"; lcb_error_t err = lcb_make_http_request(theInstance, lOptions, LCB_HTTP_TYPE_VIEW, &lCmd, &lReq); - if (err != LCB_SUCCESS) { libCouchbaseError (theInstance, err); === modified file 'src/couchbase.xq.src/couchbase.h' --- src/couchbase.xq.src/couchbase.h 2013-01-10 06:51:21 +0000 +++ src/couchbase.xq.src/couchbase.h 2013-01-14 21:43:21 +0000 @@ -86,16 +86,25 @@ } lcb_storage_type_t; + typedef enum + { + CB_WAIT_FALSE = 0x00, + CB_WAIT_PERSIST = 0x01, + CB_WAIT_REPLICATE = 0x02 + } cb_wait_type_t; + class ViewOptions { protected: String theEncoding; String thePath; + String theStaleOption; + String theLimitOption; public: std::unique_ptr<std::stringstream>* theStream; - ViewOptions() : theEncoding("UTF-8"), thePath("") { theStream = NULL; } + ViewOptions() : theEncoding("UTF-8"), thePath(""), theStaleOption(""), theLimitOption("") { theStream = NULL; } ViewOptions(String& aPath) : theEncoding("UTF-8"), thePath(aPath) {} @@ -106,6 +115,8 @@ String getEncoding() { return theEncoding; } String getPath() { return thePath; } + + String getPathOptions(); }; class GetOptions @@ -137,17 +148,18 @@ class PutOptions { protected: - lcb_storage_t theOperation; lcb_storage_type_t theType; unsigned int theExpTime; String theEncoding; + cb_wait_type_t theWaitType; + bool theIsWaiting; public: - PutOptions() : theOperation(LCB_ADD), theType(LCB_JSON), theExpTime(0), theEncoding("") { } + PutOptions() : theOperation(LCB_ADD), theType(LCB_JSON), theExpTime(0), theEncoding(""), theWaitType(CB_WAIT_FALSE), theIsWaiting(false){ } - PutOptions(lcb_storage_type_t aType) : theOperation(LCB_SET), theType(aType), theExpTime(0) { } + PutOptions(lcb_storage_type_t aType) : theOperation(LCB_SET), theType(aType), theExpTime(0), theWaitType(CB_WAIT_FALSE), theIsWaiting(false) { } void setOptions(Item& aOptions); @@ -160,6 +172,12 @@ unsigned int getExmpTime() { return theExpTime; } String getEncoding() { return theEncoding; } + + cb_wait_type_t getWaitType() { return theWaitType; } + + bool isWaiting() { return theIsWaiting; } + + void setWaiting(bool isWaiting) { theIsWaiting = isWaiting; } }; class ViewItemSequence : public ItemSequence @@ -299,6 +317,14 @@ static void put (lcb_t aInstance, Iterator_t aKeys, Iterator_t aValues, PutOptions aOptions); + + static void + observe_callback( + lcb_t instance, + const void *cookie, + lcb_error_t error, + const lcb_observe_resp_t *resp); + public: CouchbaseFunction(const CouchbaseModule* module); === modified file 'test/Queries/couchbase_module/view.xq' --- test/Queries/couchbase_module/view.xq 2013-01-10 07:59:35 +0000 +++ test/Queries/couchbase_module/view.xq 2013-01-14 21:43:21 +0000 @@ -6,12 +6,14 @@ "password" : null, "bucket" : "default"}); -cb:put-text($instance, "view", '{ "view" : 1 }'); +cb:remove($instance, "view"); +cb:put-text($instance, "view", '{ "view" : 1 }', { "wait" : "persist" }); variable $view-name := cb:create-view($instance, "test-view", "test", {"key":"doc.view"}); -variable $data := cb:view($instance, $view-name); + +variable $data := cb:view($instance, $view-name, {"stale" : "false"}); for $d in jn:members($data("rows")) -where $d("key") >0 +where $d("key") > 0 return $d
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp