├── .gitignore ├── LICENSE ├── README.md ├── c ├── .clang-format ├── .gitignore ├── Makefile ├── README.md ├── bincoding │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── avatar.h │ ├── base64.c │ ├── base64.h │ ├── bincoding.c │ ├── cJSON.c │ ├── cJSON.h │ └── demo.png ├── bulk-get.cc ├── bulk-store.cc ├── cas.cc ├── cloud.c ├── connecting-cert-auth.c ├── connecting-ssl.c ├── connecting.c ├── counter.cc ├── create-remove-bucket.cc ├── durability.cc ├── encryption │ ├── .gitignore │ ├── Makefile │ ├── common_provider.c │ ├── common_provider.h │ ├── openssl_asymmetric_decrypt.c │ ├── openssl_asymmetric_encrypt.c │ ├── openssl_asymmetric_provider.c │ ├── openssl_asymmetric_provider.h │ ├── openssl_symmetric_decrypt.c │ ├── openssl_symmetric_encrypt.c │ ├── openssl_symmetric_provider.c │ └── openssl_symmetric_provider.h ├── expiration.cc ├── flush.cc ├── fts-basic.cc ├── n1ql-create-primary-index.cc ├── query-atplus.cc ├── query-consistency.cc ├── query-create-index.cc ├── query-criteria.cc ├── query-placeholders.cc ├── retrieving.cc ├── subdoc-retrieving.cc ├── subdoc-updating.cc └── updating.c ├── dotnet ├── .gitignore ├── App.config ├── AsyncBatch.cs ├── AsyncExample.cs ├── BulkGet.cs ├── BulkInsert.cs ├── Cas.cs ├── ConnectionBase.cs ├── ConnectionConfig.cs ├── Counter.cs ├── Data.cs ├── DevGuide.csproj ├── DevGuide.sln ├── Durability.cs ├── Expiration.cs ├── FieldEncryptionAes.cs ├── FieldEncryptionRsa.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── Retrieve.cs ├── SyncExample.cs ├── Update.cs ├── etc │ └── person.json └── packages.config ├── etc ├── field-level-encryption │ ├── .gitignore │ └── create-cert.sh └── x509-cert │ ├── .gitignore │ ├── create-keystore-for-java.sh │ ├── create-pfx-for-net.sh │ ├── generate-new-client-cert.sh │ └── setup-x509-on-cluster.sh ├── go ├── bulk-get.go ├── bulk-insert.go ├── cloud.go ├── connecting-cca.go ├── connecting.go ├── counter.go ├── durability.go ├── expiration.go ├── field-encryption.go ├── query-create-index.go ├── query-criteria.go ├── query-marshalling-rest.go ├── query-placeholders.go ├── retrieving.go ├── subdocument.go └── updating.go ├── java ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── couchbase │ │ └── devguide │ │ ├── BulkGet.java │ │ ├── BulkInsert.java │ │ ├── Cas.java │ │ ├── Cloud.java │ │ ├── ConnectingCertAuth.java │ │ ├── ConnectingSsl.java │ │ ├── ConnectionBase.java │ │ ├── Counter.java │ │ ├── Durability.java │ │ ├── Expiration.java │ │ ├── FieldEncryptionAES.java │ │ ├── QueryConsistency.java │ │ ├── QueryCriteria.java │ │ ├── QueryPlaceholders.java │ │ ├── QueryPrepared.java │ │ ├── Retrieving.java │ │ └── Updating.java │ └── resources │ └── log4j.properties ├── nodejs ├── bulkES6.js ├── cloud.js ├── connecting-cert-auth.js ├── connecting-ssl.js ├── connecting.js ├── counter.js ├── durability.js ├── expiration.js ├── field-encryption.js ├── query-create-index.js ├── query-criteria.js ├── query-placeholders.js ├── query-prepared.js ├── retrieving.js ├── subdoc.js ├── subdocES6.js └── updating.js ├── php ├── bulk-operations.php ├── cache-curl-request.php ├── cas-replace.php ├── cas.php ├── cloud.php ├── connecting-cert-auth.php ├── connecting-ssl.php ├── connecting.php ├── counter.php ├── durability.php ├── encryption │ ├── .gitignore │ ├── README.md │ ├── composer.json │ ├── demo-asymmetric.php │ └── demo-symmetric.php ├── expiration.php ├── query-consistency.php ├── query-criteria.php ├── query-placeholders.php ├── retrieving.php ├── transcoders.php └── updating.php ├── python ├── bulk-operations.py ├── cas.py ├── cloud.py ├── connecting-ssl.py ├── connecting.py ├── counter.py ├── create-remove-bucket.py ├── durability.py ├── encryption │ ├── __init__.py │ └── field-encryption.py ├── expiration.py ├── flush.py ├── fts-basic.py ├── n1ql-create-primary-index.py ├── n1ql-update-delete.py ├── query-atplus.py ├── query-consistency.py ├── query-criteria.py ├── query-placeholders.py ├── retrieving.py ├── subdoc-retrieving.py ├── subdoc-updating.py └── updating.py └── spring ├── spring-boot-demo ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── couchbase │ │ │ └── demos │ │ │ └── springbootdemo │ │ │ ├── AirlinesController.java │ │ │ ├── AirportsController.java │ │ │ ├── DatabaseConfig.java │ │ │ └── SpringBootDemoApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── couchbase │ └── demos │ └── springbootdemo │ └── SpringBootDemoApplicationTests.java └── spring-data-demo ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── couchbase │ │ └── demos │ │ └── springdatademo │ │ ├── Airport.java │ │ ├── AirportsController.java │ │ ├── AirportsRepository.java │ │ ├── DatabaseConfig.java │ │ └── SpringDataDemoApplication.java └── resources │ └── application.properties └── test └── java └── com └── couchbase └── demos └── springdatademo └── SpringDataDemoApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | java/.idea 2 | python/.idea 3 | java/devguide.iml 4 | java/target 5 | -------------------------------------------------------------------------------- /c/.clang-format: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml; -*- 2 | 3 | BasedOnStyle: LLVM 4 | IndentWidth: 4 5 | BreakBeforeBraces: Linux 6 | ColumnLimit: 120 7 | AllowShortFunctionsOnASingleLine: Empty 8 | SortIncludes: false 9 | IndentCaseLabels: true 10 | SpacesInAngles: true 11 | -------------------------------------------------------------------------------- /c/.gitignore: -------------------------------------------------------------------------------- 1 | *.dSYM 2 | bulk-get 3 | bulk-store 4 | cas 5 | connecting 6 | connecting-cert-auth 7 | connecting-ssl 8 | counter 9 | create-remove-bucket 10 | durability 11 | expiration 12 | flush 13 | fts-basic 14 | n1ql-create-primary-index 15 | query-atplus 16 | query-consistency 17 | query-create-index 18 | query-criteria 19 | query-placeholders 20 | retrieving 21 | subdoc-retrieving 22 | subdoc-updating 23 | updating 24 | -------------------------------------------------------------------------------- /c/Makefile: -------------------------------------------------------------------------------- 1 | CPPFLAGS=-Wall -g 2 | LDLIBS=-lcouchbase -pthread 3 | 4 | PROGS = \ 5 | bulk-get \ 6 | bulk-store \ 7 | cas \ 8 | connecting \ 9 | connecting-cert-auth \ 10 | connecting-ssl \ 11 | counter \ 12 | create-remove-bucket \ 13 | durability \ 14 | expiration \ 15 | flush \ 16 | fts-basic \ 17 | n1ql-create-primary-index \ 18 | query-atplus \ 19 | query-consistency \ 20 | query-create-index \ 21 | query-criteria \ 22 | query-placeholders \ 23 | retrieving \ 24 | subdoc-retrieving \ 25 | subdoc-updating \ 26 | updating \ 27 | 28 | 29 | all: $(PROGS) 30 | 31 | clean: 32 | rm -f $(PROGS) 33 | rm -rf *.dSYM 34 | -------------------------------------------------------------------------------- /c/README.md: -------------------------------------------------------------------------------- 1 | # C SDK Examples 2 | 3 | Most of these examples should be platform-independent. Some may use POSIX 4 | functionality. 5 | 6 | On POSIX systems you can simply run `make` and the examples will be built 7 | (assuming you have the library itself installed). 8 | 9 | Change the connection string (typically by just changing the hostname) to 10 | have the example work locally. 11 | -------------------------------------------------------------------------------- /c/bincoding/.gitignore: -------------------------------------------------------------------------------- 1 | bincoding 2 | *.html 3 | -------------------------------------------------------------------------------- /c/bincoding/Makefile: -------------------------------------------------------------------------------- 1 | LDFLAGS=-lcouchbase -lm -lcrypto 2 | CFLAGS=-g 3 | 4 | bincoding: bincoding.c cJSON.c base64.c 5 | -------------------------------------------------------------------------------- /c/bincoding/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates how to write custom transcoders for structs in C. 2 | 3 | Here we store user profile with embedded avatar as document in Couchbase, and retrieve it back to render as HTML. 4 | Note, that encoding of the `struct Profile` remains friendly to Couchbase indexers, and data could be retrieven using any of queries (N1QL, FTS etc). 5 | 6 | To try the example, use Makefile to build the binary and then execute it: 7 | 8 | $ make 9 | $ ./bincoding couchbase://localhost password Administrator profile.html 10 | 11 | The rendered HTML should look like this 12 | 13 | ![demo](demo.png) 14 | -------------------------------------------------------------------------------- /c/bincoding/base64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | char *base64(const char *in, int in_len, int *out_len) 7 | { 8 | BIO *buf, *b64; 9 | char *ptr, *out; 10 | long len; 11 | 12 | buf = BIO_new(BIO_s_mem()); 13 | BIO_set_close(buf, BIO_CLOSE); 14 | 15 | b64 = BIO_new(BIO_f_base64()); 16 | BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 17 | BIO_push(b64, buf); 18 | 19 | BIO_write(b64, in, in_len); 20 | BIO_flush(b64); 21 | 22 | len = BIO_get_mem_data(buf, &ptr); 23 | out = malloc((len + 1) * sizeof(char)); 24 | memcpy(out, ptr, len); 25 | out[len] = '\0'; 26 | *out_len = len + 1; 27 | 28 | BIO_free_all(b64); 29 | return out; 30 | } 31 | 32 | char *unbase64(const char *in, int in_len, int *out_len) 33 | { 34 | BIO *buf, *b64; 35 | char *out; 36 | long len; 37 | 38 | buf = BIO_new_mem_buf(in, in_len); 39 | BIO_set_close(buf, BIO_CLOSE); 40 | 41 | b64 = BIO_new(BIO_f_base64()); 42 | BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 43 | BIO_push(b64, buf); 44 | 45 | out = malloc((in_len + 1) * sizeof(char)); 46 | len = BIO_read(b64, out, in_len); 47 | out[len] = '\0'; 48 | *out_len = len; 49 | 50 | BIO_free_all(b64); 51 | return out; 52 | } 53 | -------------------------------------------------------------------------------- /c/bincoding/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_H 2 | #define BASE64_H 3 | 4 | char *base64(const char *in, int in_len, int *out_len); 5 | char *unbase64(const char *in, int in_len, int *out_len); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /c/bincoding/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/couchbaselabs/devguide-examples/c9373a004375a62500cdcde2c56801dbbf794af4/c/bincoding/demo.png -------------------------------------------------------------------------------- /c/bulk-get.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Result { 7 | lcb_error_t rc; 8 | std::string key; 9 | std::string value; 10 | lcb_CAS cas; 11 | 12 | explicit Result(const lcb_RESPBASE *rb) 13 | : rc(rb->rc), key(reinterpret_cast< const char * >(rb->key), rb->nkey), cas(rb->cas) 14 | { 15 | } 16 | }; 17 | 18 | typedef std::vector< Result > ResultList; 19 | 20 | static void op_callback(lcb_t, int cbtype, const lcb_RESPBASE *rb) 21 | { 22 | ResultList *results = reinterpret_cast< ResultList * >(rb->cookie); 23 | Result res(rb); 24 | 25 | if (cbtype == LCB_CALLBACK_GET && rb->rc == LCB_SUCCESS) { 26 | const lcb_RESPGET *rg = reinterpret_cast< const lcb_RESPGET * >(rb); 27 | res.value.assign(reinterpret_cast< const char * >(rg->value), rg->nvalue); 28 | } 29 | results->push_back(res); 30 | } 31 | 32 | int main(int argc, char **argv) 33 | { 34 | lcb_t instance; 35 | lcb_create_st crst = {}; 36 | lcb_error_t rc; 37 | 38 | crst.version = 3; 39 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 40 | crst.v.v3.username = "testuser"; 41 | crst.v.v3.passwd = "password"; 42 | rc = lcb_create(&instance, &crst); 43 | rc = lcb_connect(instance); 44 | lcb_wait(instance); 45 | rc = lcb_get_bootstrap_status(instance); 46 | if (rc != LCB_SUCCESS) { 47 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 48 | exit(1); 49 | } 50 | 51 | lcb_install_callback3(instance, LCB_CALLBACK_GET, op_callback); 52 | 53 | // Make a list of keys to store initially 54 | std::vector< std::string > toGet; 55 | toGet.push_back("foo"); 56 | toGet.push_back("bar"); 57 | toGet.push_back("baz"); 58 | 59 | ResultList results; 60 | 61 | lcb_sched_enter(instance); 62 | std::vector< std::string >::const_iterator its = toGet.begin(); 63 | for (; its != toGet.end(); ++its) { 64 | lcb_CMDGET gcmd = {}; 65 | LCB_CMD_SET_KEY(&gcmd, its->c_str(), its->size()); 66 | rc = lcb_get3(instance, &results, &gcmd); 67 | if (rc != LCB_SUCCESS) { 68 | fprintf(stderr, "Couldn't schedule item %s: %s\n", its->c_str(), lcb_strerror(NULL, rc)); 69 | 70 | // Unschedules all operations since the last scheduling context 71 | // (created by lcb_sched_enter) 72 | lcb_sched_fail(instance); 73 | break; 74 | } 75 | } 76 | lcb_sched_leave(instance); 77 | lcb_wait(instance); 78 | 79 | ResultList::iterator itr; 80 | for (itr = results.begin(); itr != results.end(); ++itr) { 81 | printf("%s: ", itr->key.c_str()); 82 | if (itr->rc != LCB_SUCCESS) { 83 | printf("Failed (%s)\n", lcb_strerror(NULL, itr->rc)); 84 | } else { 85 | printf("Value=%.*s. CAS=%llu\n", (int)itr->value.size(), itr->value.c_str(), (unsigned long long)itr->cas); 86 | } 87 | } 88 | 89 | lcb_destroy(instance); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /c/bulk-store.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Result { 8 | lcb_error_t rc; 9 | std::string key; 10 | std::string value; 11 | lcb_CAS cas; 12 | 13 | explicit Result(const lcb_RESPBASE *rb) 14 | : rc(rb->rc), key(reinterpret_cast< const char * >(rb->key), rb->nkey), cas(rb->cas) 15 | { 16 | } 17 | }; 18 | 19 | typedef std::vector< Result > ResultList; 20 | 21 | static void op_callback(lcb_t, int cbtype, const lcb_RESPBASE *rb) 22 | { 23 | ResultList *results = reinterpret_cast< ResultList * >(rb->cookie); 24 | Result res(rb); 25 | 26 | if (cbtype == LCB_CALLBACK_GET && rb->rc == LCB_SUCCESS) { 27 | const lcb_RESPGET *rg = reinterpret_cast< const lcb_RESPGET * >(rb); 28 | res.value.assign(reinterpret_cast< const char * >(rg->value), rg->nvalue); 29 | } 30 | results->push_back(res); 31 | } 32 | 33 | int main(int argc, char **argv) 34 | { 35 | lcb_t instance; 36 | lcb_create_st crst = {}; 37 | lcb_error_t rc; 38 | 39 | crst.version = 3; 40 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 41 | crst.v.v3.username = "testuser"; 42 | crst.v.v3.passwd = "password"; 43 | rc = lcb_create(&instance, &crst); 44 | rc = lcb_connect(instance); 45 | lcb_wait(instance); 46 | rc = lcb_get_bootstrap_status(instance); 47 | if (rc != LCB_SUCCESS) { 48 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 49 | exit(1); 50 | } 51 | 52 | lcb_install_callback3(instance, LCB_CALLBACK_STORE, op_callback); 53 | 54 | // Make a list of keys to store initially 55 | std::map< std::string, std::string > toStore; 56 | toStore["foo"] = "{\"value\":\"fooValue\"}"; 57 | toStore["bar"] = "{\"value\":\"barValue\"}"; 58 | toStore["baz"] = "{\"value\":\"bazValue\"}"; 59 | 60 | ResultList results; 61 | 62 | lcb_sched_enter(instance); 63 | std::map< std::string, std::string >::const_iterator its = toStore.begin(); 64 | for (; its != toStore.end(); ++its) { 65 | lcb_CMDSTORE scmd = {}; 66 | LCB_CMD_SET_KEY(&scmd, its->first.c_str(), its->first.size()); 67 | LCB_CMD_SET_VALUE(&scmd, its->second.c_str(), its->second.size()); 68 | scmd.operation = LCB_SET; 69 | rc = lcb_store3(instance, &results, &scmd); 70 | if (rc != LCB_SUCCESS) { 71 | fprintf(stderr, "Couldn't schedule item %s: %s\n", its->first.c_str(), lcb_strerror(NULL, rc)); 72 | 73 | // Unschedules all operations since the last scheduling context 74 | // (created by lcb_sched_enter) 75 | lcb_sched_fail(instance); 76 | break; 77 | } 78 | } 79 | lcb_sched_leave(instance); 80 | lcb_wait(instance); 81 | 82 | ResultList::iterator itr; 83 | for (itr = results.begin(); itr != results.end(); ++itr) { 84 | printf("%s: ", itr->key.c_str()); 85 | if (itr->rc != LCB_SUCCESS) { 86 | printf("Failed (%s)\n", lcb_strerror(NULL, itr->rc)); 87 | } else { 88 | printf("Stored. CAS=%llu\n", (unsigned long long)itr->cas); 89 | } 90 | } 91 | 92 | lcb_destroy(instance); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /c/cloud.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include //this code sample is for libcouchbase 2.10 & later 3 | #include 4 | 5 | static void 6 | opCallback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb) { 7 | fprintf(stderr, "%.*s: %s... ", (int)rb->nkey, rb->key, lcb_strcbtype(cbtype)); 8 | if (rb->rc != LCB_SUCCESS) { 9 | fprintf(stderr, "%s\n", lcb_strerror(NULL, rb->rc)); 10 | } else { 11 | fprintf(stderr, "OK"); 12 | if (cbtype == LCB_CALLBACK_GET) { 13 | const lcb_RESPGET *rg = (const lcb_RESPGET *)rb; 14 | fprintf(stderr, "... Value: %.*s\n", (int)rg->nvalue, rg->value); 15 | } else { 16 | fprintf(stderr, "\n"); 17 | } 18 | } 19 | } 20 | 21 | int main(int argc, char **argv) 22 | { 23 | lcb_t instance = NULL; 24 | struct lcb_create_st crst = {0}; 25 | memset(&crst, 0, sizeof crst); 26 | // Note that version 3 here refers to the internal API/ABI, not the version of the library supporting 27 | // that API/ABI. This allows extension within a libcouchbase version with forward compatibility 28 | crst.version = 3; 29 | 30 | /* User input starts here; see note on v3 above */ 31 | crst.v.v3.connstr = "couchbases://cb..dp.cloud.couchbase.com/couchbasecloudbucket?ssl=no_verify"; 32 | crst.v.v3.username = "user"; 33 | crst.v.v3.passwd = "password"; 34 | /* User input ends here */ 35 | 36 | lcb_create(&instance, &crst); 37 | lcb_connect(instance); 38 | 39 | 40 | /* This function is required to actually schedule the operations on the network */ 41 | lcb_wait(instance); 42 | 43 | /* Determines if the bootstrap/connection succeeded */ 44 | lcb_error_t rc; 45 | rc = lcb_get_bootstrap_status(instance); 46 | if (rc != LCB_SUCCESS) { 47 | fprintf(stderr, "%s failed. (0x%x, %s)\n", "bootstrap failure", rc, lcb_strerror(NULL, rc)); 48 | exit(1); 49 | } else { 50 | printf("Connection succeeded. Cluster has %d nodes\n", lcb_get_num_nodes(instance)); 51 | } 52 | 53 | lcb_install_callback3(instance, LCB_CALLBACK_GET, opCallback); 54 | lcb_install_callback3(instance, LCB_CALLBACK_STORE, opCallback); 55 | 56 | lcb_CMDSTORE scmd = { 0 }; 57 | LCB_CMD_SET_KEY(&scmd, "key", 3); 58 | LCB_CMD_SET_VALUE(&scmd, "true", 4); 59 | scmd.operation = LCB_SET; 60 | lcb_store3(instance, NULL, &scmd); 61 | lcb_wait(instance); 62 | 63 | lcb_CMDGET gcmd = { 0 }; 64 | LCB_CMD_SET_KEY(&gcmd, "key", 3); 65 | lcb_get3(instance, NULL, &gcmd); 66 | lcb_wait(instance); 67 | lcb_destroy(instance); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /c/connecting-cert-auth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static void die(lcb_error_t rc, const char *msg) 6 | { 7 | fprintf(stderr, "%s failed. (0x%x, %s)\n", msg, rc, lcb_strerror(NULL, rc)); 8 | exit(EXIT_FAILURE); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | lcb_t instance; 14 | struct lcb_create_st cropts; 15 | lcb_error_t rc; 16 | 17 | memset(&cropts, 0, sizeof cropts); 18 | cropts.version = 3; 19 | cropts.v.v3.connstr = "couchbases://127.0.0.1/default" 20 | "?truststorepath=../etc/x509-cert/SSLCA/clientdir/trust.pem" 21 | "&certpath=../etc/x509-cert/SSLCA/clientdir/client.pem" 22 | "&keypath=../etc/x509-cert/SSLCA/clientdir/client.key"; 23 | 24 | rc = lcb_create(&instance, &cropts); 25 | if (rc != LCB_SUCCESS) { 26 | die(rc, "Creating instance"); 27 | } 28 | 29 | rc = lcb_connect(instance); 30 | if (rc != LCB_SUCCESS) { 31 | die(rc, "Connection scheduling"); 32 | } 33 | 34 | /* This function required to actually schedule the operations on the network */ 35 | lcb_wait(instance); 36 | 37 | /* Determines if the bootstrap/connection succeeded */ 38 | rc = lcb_get_bootstrap_status(instance); 39 | if (rc != LCB_SUCCESS) { 40 | die(rc, "Connection bootstraping"); 41 | } else { 42 | printf("Connection succeeded. Cluster has %d nodes\n", lcb_get_num_nodes(instance)); 43 | } 44 | 45 | /* SSL connections use different ports. For example, the REST API 46 | * connection will use port 18091 rather than 8091 when using SSL */ 47 | const char *node = lcb_get_node(instance, LCB_NODE_HTCONFIG, 0); 48 | printf("First node address for REST API: %s\n", node); 49 | 50 | lcb_destroy(instance); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /c/connecting-ssl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static void die(lcb_error_t rc, const char *msg) 6 | { 7 | fprintf(stderr, "%s failed. (0x%x, %s)\n", msg, rc, lcb_strerror(NULL, rc)); 8 | exit(EXIT_FAILURE); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | lcb_t instance; 14 | struct lcb_create_st cropts = {0}; 15 | lcb_error_t rc; 16 | 17 | cropts.version = 3; 18 | cropts.v.v3.connstr = "couchbases://127.0.0.1/default?certpath=../etc/x509-cert/SSLCA/clientdir/trust.pem"; 19 | cropts.v.v3.username = "testuser"; 20 | cropts.v.v3.passwd = "password"; 21 | 22 | rc = lcb_create(&instance, &cropts); 23 | if (rc != LCB_SUCCESS) { 24 | die(rc, "Creating instance"); 25 | } 26 | 27 | rc = lcb_connect(instance); 28 | if (rc != LCB_SUCCESS) { 29 | die(rc, "Connection scheduling"); 30 | } 31 | 32 | /* This function required to actually schedule the operations on the network */ 33 | lcb_wait(instance); 34 | 35 | /* Determines if the bootstrap/connection succeeded */ 36 | rc = lcb_get_bootstrap_status(instance); 37 | if (rc != LCB_SUCCESS) { 38 | die(rc, "Connection bootstraping"); 39 | } else { 40 | printf("Connection succeeded. Cluster has %d nodes\n", lcb_get_num_nodes(instance)); 41 | } 42 | 43 | /* SSL connections use different ports. For example, the REST API 44 | * connection will use port 18091 rather than 8091 when using SSL */ 45 | const char *node = lcb_get_node(instance, LCB_NODE_HTCONFIG, 0); 46 | printf("First node address for REST API: %s\n", node); 47 | 48 | lcb_destroy(instance); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /c/connecting.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static void die(lcb_error_t rc, const char *msg) 6 | { 7 | fprintf(stderr, "%s failed. (0x%x, %s)\n", msg, rc, lcb_strerror(NULL, rc)); 8 | exit(EXIT_FAILURE); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | lcb_t instance; 14 | struct lcb_create_st cropts = {0}; 15 | lcb_error_t rc; 16 | 17 | cropts.version = 3; 18 | cropts.v.v3.connstr = "couchbase://127.0.0.1/default"; 19 | cropts.v.v3.username = "testuser"; 20 | cropts.v.v3.passwd = "password"; 21 | 22 | rc = lcb_create(&instance, &cropts); 23 | if (rc != LCB_SUCCESS) { 24 | die(rc, "Creating instance"); 25 | } 26 | 27 | rc = lcb_connect(instance); 28 | if (rc != LCB_SUCCESS) { 29 | die(rc, "Connection scheduling"); 30 | } 31 | 32 | /* This function required to actually schedule the operations on the network */ 33 | lcb_wait(instance); 34 | 35 | /* Determines if the bootstrap/connection succeeded */ 36 | rc = lcb_get_bootstrap_status(instance); 37 | if (rc != LCB_SUCCESS) { 38 | die(rc, "Connection bootstraping"); 39 | } else { 40 | printf("Connection succeeded. Cluster has %d nodes\n", lcb_get_num_nodes(instance)); 41 | } 42 | 43 | lcb_destroy(instance); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /c/counter.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static void counter_callback(lcb_t, int, const lcb_RESPBASE *rb) 6 | { 7 | const lcb_RESPCOUNTER *resp = reinterpret_cast< const lcb_RESPCOUNTER * >(rb); 8 | if (resp->rc != LCB_SUCCESS) { 9 | fprintf(stderr, "Couldn't perform counter operation!\n"); 10 | fprintf(stderr, "Error code 0x%x (%s)\n", resp->rc, lcb_strerror(NULL, resp->rc)); 11 | return; 12 | } 13 | 14 | printf("Current counter value is %llu\n", (unsigned long long)resp->value); 15 | } 16 | 17 | // Removes the counter. This is optional, but is helpful for demonstrative 18 | // purposes so that we always start off with a fresh counter 19 | static void remove_counter(lcb_t instance, const char *docid) 20 | { 21 | lcb_CMDREMOVE cmd = {}; 22 | LCB_CMD_SET_KEY(&cmd, docid, strlen(docid)); 23 | lcb_sched_enter(instance); 24 | lcb_remove3(instance, NULL, &cmd); 25 | lcb_sched_leave(instance); 26 | lcb_wait(instance); 27 | } 28 | 29 | int main(int, char **) 30 | { 31 | lcb_t instance; 32 | lcb_create_st crst = {}; 33 | lcb_error_t rc; 34 | 35 | crst.version = 3; 36 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 37 | crst.v.v3.username = "testuser"; 38 | crst.v.v3.passwd = "password"; 39 | 40 | rc = lcb_create(&instance, &crst); 41 | rc = lcb_connect(instance); 42 | lcb_wait(instance); 43 | rc = lcb_get_bootstrap_status(instance); 44 | if (rc != LCB_SUCCESS) { 45 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 46 | exit(1); 47 | } 48 | 49 | lcb_install_callback3(instance, LCB_CALLBACK_COUNTER, counter_callback); 50 | 51 | lcb_sched_enter(instance); 52 | 53 | const char *docid = "docid"; 54 | remove_counter(instance, docid); 55 | 56 | lcb_CMDCOUNTER cmd = {}; 57 | LCB_CMD_SET_KEY(&cmd, docid, strlen(docid)); 58 | cmd.initial = 100; 59 | cmd.delta = 20; 60 | cmd.create = 1; 61 | 62 | rc = lcb_counter3(instance, NULL, &cmd); 63 | lcb_sched_leave(instance); 64 | lcb_wait(instance); 65 | 66 | lcb_sched_enter(instance); 67 | cmd.delta = 1; 68 | rc = lcb_counter3(instance, NULL, &cmd); 69 | lcb_sched_leave(instance); 70 | lcb_wait(instance); 71 | 72 | lcb_sched_enter(instance); 73 | cmd.delta = -50; 74 | rc = lcb_counter3(instance, NULL, &cmd); 75 | lcb_sched_leave(instance); 76 | lcb_wait(instance); 77 | 78 | lcb_destroy(instance); 79 | } 80 | -------------------------------------------------------------------------------- /c/create-remove-bucket.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static void http_callback(lcb_t, int, const lcb_RESPHTTP *resp) 7 | { 8 | printf("Operation completed with HTTP code: %d\n", resp->htstatus); 9 | printf("Payload: %.*s\n", (int)resp->nbody, (char *)resp->body); 10 | } 11 | 12 | int main(int, char **) 13 | { 14 | lcb_create_st crst = {}; 15 | lcb_t instance; 16 | 17 | crst.version = 3; 18 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 19 | crst.v.v3.username = "testuser"; 20 | crst.v.v3.passwd = "password"; 21 | 22 | lcb_create(&instance, &crst); 23 | lcb_connect(instance); 24 | lcb_wait(instance); 25 | assert(lcb_get_bootstrap_status(instance) == LCB_SUCCESS); 26 | lcb_install_callback3(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback); 27 | 28 | // Create the required parameters according to the Couchbase REST API 29 | std::string path("/pools/default/buckets"); 30 | 31 | std::string params; 32 | params += "name=newBucket&"; 33 | params += "bucketType=couchbase&"; 34 | 35 | // authType should always be SASL. You can leave the saslPassword field 36 | // empty if you don't want to protect this bucket. 37 | params += "authType=sasl&saslPassword=&"; 38 | params += "ramQuotaMB=100"; 39 | printf("Using %s\n", params.c_str()); 40 | 41 | lcb_CMDHTTP htcmd = {}; 42 | LCB_CMD_SET_KEY(&htcmd, path.c_str(), path.size()); 43 | htcmd.body = params.c_str(); 44 | htcmd.nbody = params.size(); 45 | htcmd.content_type = "application/x-www-form-urlencoded"; 46 | htcmd.method = LCB_HTTP_METHOD_POST; 47 | htcmd.type = LCB_HTTP_TYPE_MANAGEMENT; 48 | htcmd.username = "Administrator"; 49 | htcmd.password = "password"; 50 | lcb_http3(instance, NULL, &htcmd); 51 | lcb_wait(instance); 52 | 53 | // now remove the bucket 54 | memset(&htcmd, 0, sizeof htcmd); 55 | path = "/pools/default/buckets/newBucket"; 56 | LCB_CMD_SET_KEY(&htcmd, path.c_str(), path.size()); 57 | htcmd.method = LCB_HTTP_METHOD_DELETE; 58 | htcmd.type = LCB_HTTP_TYPE_MANAGEMENT; 59 | htcmd.username = "Administrator"; 60 | htcmd.password = "password"; 61 | lcb_http3(instance, NULL, &htcmd); 62 | lcb_wait(instance); 63 | 64 | lcb_destroy(instance); 65 | } 66 | -------------------------------------------------------------------------------- /c/encryption/.gitignore: -------------------------------------------------------------------------------- 1 | openssl_asymmetric_decrypt 2 | openssl_asymmetric_encrypt 3 | openssl_symmetric_decrypt 4 | openssl_symmetric_encrypt 5 | -------------------------------------------------------------------------------- /c/encryption/Makefile: -------------------------------------------------------------------------------- 1 | LDFLAGS=-lcouchbase -lm 2 | CFLAGS=-g 3 | 4 | OPENSSL_LDFLAGS=$(shell pkg-config --libs openssl) ${LDFLAGS} 5 | OPENSSL_CFLAGS=$(shell pkg-config --cflags openssl) ${CFLAGS} 6 | 7 | all: openssl_symmetric_encrypt openssl_symmetric_decrypt \ 8 | openssl_asymmetric_encrypt openssl_asymmetric_decrypt 9 | 10 | openssl_symmetric_encrypt: openssl_symmetric_encrypt.c openssl_symmetric_provider.c common_provider.c 11 | ${CC} ${OPENSSL_CFLAGS} ${OPENSSL_LDFLAGS} -o $@ $^ 12 | 13 | openssl_symmetric_decrypt: openssl_symmetric_decrypt.c openssl_symmetric_provider.c common_provider.c 14 | ${CC} ${OPENSSL_CFLAGS} ${OPENSSL_LDFLAGS} -o $@ $^ 15 | 16 | 17 | openssl_asymmetric_encrypt: openssl_asymmetric_encrypt.c openssl_asymmetric_provider.c common_provider.c 18 | ${CC} ${OPENSSL_CFLAGS} ${OPENSSL_LDFLAGS} -o $@ $^ 19 | 20 | openssl_asymmetric_decrypt: openssl_asymmetric_decrypt.c openssl_asymmetric_provider.c common_provider.c 21 | ${CC} ${OPENSSL_CFLAGS} ${OPENSSL_LDFLAGS} -o $@ $^ 22 | -------------------------------------------------------------------------------- /c/encryption/common_provider.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | /* 3 | * Copyright 2018 Couchbase, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef _COMMON_PROVIDER_H 19 | #define _COMMON_PROVIDER_H 20 | 21 | #include 22 | 23 | extern char * common_aes256_key_id; 24 | 25 | #define AES256_KEY_SIZE 32 26 | #define AES256_IV_SIZE 16 27 | 28 | extern uint8_t common_aes256_key[AES256_KEY_SIZE]; 29 | extern uint8_t common_aes256_iv[AES256_IV_SIZE]; 30 | 31 | extern uint8_t *common_hmac_sha256_key; 32 | 33 | extern char *common_rsa_private_key; 34 | extern char *common_rsa_public_key; 35 | 36 | extern char *common_rsa_private_key_id; 37 | extern char *common_rsa_public_key_id; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /c/encryption/openssl_asymmetric_provider.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | /* 3 | * Copyright 2018 Couchbase, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef _OPENSSL_SYMMETRIC_PROVIDER_H 19 | #define _OPENSSL_SYMMETRIC_PROVIDER_H 20 | 21 | #include 22 | #include 23 | 24 | #include "common_provider.h" 25 | 26 | void oap_initialize(); 27 | lcbcrypto_PROVIDER *oap_create(); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /c/encryption/openssl_symmetric_provider.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | /* 3 | * Copyright 2018 Couchbase, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef _OPENSSL_SYMMETRIC_PROVIDER_H 19 | #define _OPENSSL_SYMMETRIC_PROVIDER_H 20 | 21 | #include 22 | #include 23 | 24 | #include "common_provider.h" 25 | 26 | void osp_initialize(); 27 | lcbcrypto_PROVIDER *osp_create(); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /c/flush.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void flush_callback(lcb_t, int, const lcb_RESPCBFLUSH *resp) 5 | { 6 | if (resp->rc != LCB_SUCCESS) { 7 | fprintf(stderr, "Couldn't flush bucket: %s.\nCheck if flush enabled for the bucket\n", 8 | lcb_strerror(NULL, resp->rc)); 9 | } else { 10 | printf("Flush successful\n"); 11 | } 12 | } 13 | 14 | int main(int, char **) 15 | { 16 | lcb_t instance; 17 | lcb_create_st crst = {}; 18 | crst.version = 3; 19 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 20 | crst.v.v3.username = "testuser"; 21 | crst.v.v3.passwd = "password"; 22 | 23 | lcb_create(&instance, &crst); 24 | lcb_connect(instance); 25 | lcb_wait(instance); 26 | if (lcb_get_bootstrap_status(instance) != LCB_SUCCESS) { 27 | printf("Couldn't bootstrap!\n"); 28 | } 29 | lcb_install_callback3(instance, LCB_CALLBACK_CBFLUSH, flush_callback); 30 | 31 | lcb_CMDCBFLUSH cmd = {}; 32 | 33 | /** 34 | * NOTE: 35 | * there is also an lcb_flush3() - that is a deprecated function and 36 | * should not be used. 37 | */ 38 | lcb_cbflush3(instance, NULL, &cmd); 39 | lcb_wait(instance); 40 | lcb_destroy(instance); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /c/fts-basic.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static void rowCallback(lcb_t, int, const lcb_RESPFTS *resp) 9 | { 10 | if (resp->rflags & LCB_RESP_F_FINAL) { 11 | printf("Status: %d\n", resp->rc); 12 | printf("Meta: %.*s\n", (int)resp->nrow, resp->row); 13 | if (resp->htresp && resp->htresp->nbody) { 14 | printf("HTTP Response: %.*s\n", (int)resp->htresp->nbody, (char *)resp->htresp->body); 15 | } 16 | } else { 17 | printf("Row: %.*s\n", (int)resp->nrow, resp->row); 18 | } 19 | } 20 | 21 | int main(int, char **) 22 | { 23 | lcb_t instance; 24 | lcb_create_st crst = {}; 25 | crst.version = 3; 26 | crst.v.v3.connstr = "couchbase://127.0.0.1/beer-sample"; 27 | crst.v.v3.username = "testuser"; 28 | crst.v.v3.passwd = "password"; 29 | 30 | lcb_error_t rc = lcb_create(&instance, &crst); 31 | assert(rc == LCB_SUCCESS); 32 | lcb_cntl_string(instance, "detailed_errcodes", "true"); 33 | lcb_connect(instance); 34 | lcb_wait(instance); 35 | assert(lcb_get_bootstrap_status(instance) == LCB_SUCCESS); 36 | 37 | // Be sure to include the indexName within the request payload 38 | std::string encodedQuery("{\"query\":{\"match\":\"hoppy\"},\"indexName\":\"beer-search\",\"size\":10}"); 39 | lcb_CMDFTS cmd = {}; 40 | cmd.callback = rowCallback; 41 | cmd.query = encodedQuery.c_str(); 42 | cmd.nquery = encodedQuery.size(); 43 | rc = lcb_fts_query(instance, NULL, &cmd); 44 | assert(rc == LCB_SUCCESS); 45 | 46 | lcb_wait(instance); 47 | lcb_destroy(instance); 48 | } 49 | -------------------------------------------------------------------------------- /c/n1ql-create-primary-index.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void ixmgmt_callback(lcb_t, int, const lcb_RESPN1XMGMT *resp) 5 | { 6 | if (resp->rc == LCB_SUCCESS) { 7 | printf("Operation successful!\n"); 8 | } else if (resp->rc == LCB_KEY_EEXISTS) { 9 | printf("Index already exists!\n"); 10 | } else { 11 | printf("Operation failed: %s\n", lcb_strerror(NULL, resp->rc)); 12 | } 13 | } 14 | 15 | int main(int, char **) 16 | { 17 | lcb_t instance; 18 | lcb_create_st crst = {}; 19 | crst.version = 3; 20 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 21 | crst.v.v3.username = "testuser"; 22 | crst.v.v3.passwd = "password"; 23 | 24 | lcb_create(&instance, &crst); 25 | lcb_connect(instance); 26 | lcb_wait(instance); 27 | 28 | if (lcb_get_bootstrap_status(instance) != LCB_SUCCESS) { 29 | printf("Couldn't bootstrap: %s\n", lcb_strerror(NULL, lcb_get_bootstrap_status(instance))); 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | const char *bktname; 34 | lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bktname); 35 | 36 | lcb_CMDN1XMGMT cmd = {}; 37 | cmd.spec.flags = LCB_N1XSPEC_F_PRIMARY; 38 | cmd.spec.keyspace = bktname; 39 | cmd.spec.nkeyspace = strlen(bktname); 40 | cmd.callback = ixmgmt_callback; 41 | lcb_n1x_create(instance, NULL, &cmd); 42 | lcb_wait(instance); 43 | lcb_destroy(instance); 44 | } 45 | -------------------------------------------------------------------------------- /c/query-create-index.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" { 5 | static void query_callback(lcb_t, int, const lcb_RESPN1QL *resp) 6 | { 7 | // This might also fail if the index is already created! 8 | if (resp->rc != LCB_SUCCESS) { 9 | fprintf(stderr, "N1QL query failed (%s)\n", lcb_strerror(NULL, resp->rc)); 10 | } 11 | printf("Result text: %.*s\n", (int)resp->nrow, resp->row); 12 | } 13 | } 14 | 15 | int main(int, char **) 16 | { 17 | lcb_t instance; 18 | struct lcb_create_st crst = {}; 19 | lcb_error_t rc; 20 | lcb_CMDN1QL cmd = {}; 21 | lcb_N1QLPARAMS *params; 22 | 23 | crst.version = 3; 24 | crst.v.v3.connstr = "couchbase://127.0.0.1/travel-sample"; 25 | crst.v.v3.username = "testuser"; 26 | crst.v.v3.passwd = "password"; 27 | rc = lcb_create(&instance, &crst); // Check rc 28 | rc = lcb_connect(instance); // Check rc 29 | lcb_wait(instance); 30 | rc = lcb_get_bootstrap_status(instance); 31 | if (rc != LCB_SUCCESS) { 32 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 33 | exit(1); 34 | } 35 | 36 | params = lcb_n1p_new(); 37 | rc = lcb_n1p_setstmtz(params, "CREATE PRIMARY INDEX ON `travel-sample`"); 38 | 39 | cmd.callback = query_callback; 40 | lcb_n1p_mkcmd(params, &cmd); 41 | rc = lcb_n1ql_query(instance, NULL, &cmd); // Check RC 42 | lcb_wait(instance); 43 | 44 | lcb_n1p_free(params); 45 | lcb_destroy(instance); 46 | } 47 | -------------------------------------------------------------------------------- /c/query-criteria.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Rows { 8 | std::vector< std::string > rows; 9 | std::string metadata; 10 | lcb_error_t rc; 11 | short htcode; 12 | Rows() : rc(LCB_ERROR), htcode(0) {} 13 | }; 14 | 15 | static void query_callback(lcb_t, int, const lcb_RESPN1QL *resp) 16 | { 17 | Rows *rows = reinterpret_cast< Rows * >(resp->cookie); 18 | 19 | // Check if this is the last invocation 20 | if (resp->rflags & LCB_RESP_F_FINAL) { 21 | rows->rc = resp->rc; 22 | 23 | // Assign the metadata (usually not needed) 24 | rows->metadata.assign(resp->row, resp->nrow); 25 | 26 | } else { 27 | rows->rows.push_back(std::string(resp->row, resp->nrow)); 28 | } 29 | } 30 | 31 | int main(int, char **) 32 | { 33 | lcb_t instance; 34 | lcb_create_st crst; 35 | lcb_error_t rc; 36 | lcb_N1QLPARAMS *params; 37 | lcb_CMDN1QL cmd = {}; 38 | Rows rows; 39 | 40 | crst.version = 3; 41 | crst.v.v3.connstr = "couchbase://127.0.0.1/travel-sample"; 42 | crst.v.v3.username = "testuser"; 43 | crst.v.v3.passwd = "password"; 44 | rc = lcb_create(&instance, &crst); 45 | rc = lcb_connect(instance); 46 | lcb_wait(instance); 47 | rc = lcb_get_bootstrap_status(instance); 48 | if (rc != LCB_SUCCESS) { 49 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 50 | exit(1); 51 | } 52 | 53 | params = lcb_n1p_new(); 54 | rc = lcb_n1p_setstmtz(params, "SELECT airportname, city, country FROM `travel-sample` " 55 | "WHERE type=\"airport\" AND city=\"Reno\""); 56 | cmd.callback = query_callback; 57 | rc = lcb_n1p_mkcmd(params, &cmd); 58 | rc = lcb_n1ql_query(instance, &rows, &cmd); 59 | lcb_wait(instance); 60 | 61 | if (rows.rc == LCB_SUCCESS) { 62 | std::cout << "Query successful!" << std::endl; 63 | std::vector< std::string >::iterator ii; 64 | for (ii = rows.rows.begin(); ii != rows.rows.end(); ++ii) { 65 | std::cout << *ii << std::endl; 66 | } 67 | } else { 68 | std::cerr << "Query failed!"; 69 | std::cerr << "(" << int(rows.rc) << "). "; 70 | std::cerr << lcb_strerror(NULL, rows.rc) << std::endl; 71 | } 72 | lcb_n1p_free(params); 73 | lcb_destroy(instance); 74 | } 75 | -------------------------------------------------------------------------------- /c/query-placeholders.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Rows { 8 | std::vector< std::string > rows; 9 | std::string metadata; 10 | lcb_error_t rc; 11 | short htcode; 12 | Rows() : rc(LCB_ERROR), htcode(0) {} 13 | }; 14 | 15 | // Copy/pasted from query-criteria.cc 16 | static void query_callback(lcb_t, int, const lcb_RESPN1QL *resp) 17 | { 18 | Rows *rows = reinterpret_cast< Rows * >(resp->cookie); 19 | 20 | // Check if this is the last invocation 21 | if (resp->rflags & LCB_RESP_F_FINAL) { 22 | rows->rc = resp->rc; 23 | 24 | // Assign the metadata (usually not needed) 25 | rows->metadata.assign(resp->row, resp->nrow); 26 | 27 | } else { 28 | rows->rows.push_back(std::string(resp->row, resp->nrow)); 29 | } 30 | } 31 | 32 | void dump_results(const Rows &rows) 33 | { 34 | if (rows.rc == LCB_SUCCESS) { 35 | std::cout << "Query successful!" << std::endl; 36 | std::vector< std::string >::const_iterator ii; 37 | for (ii = rows.rows.begin(); ii != rows.rows.end(); ++ii) { 38 | std::cout << *ii << std::endl; 39 | } 40 | } else { 41 | std::cerr << "Query failed!"; 42 | std::cerr << "(" << int(rows.rc) << "). "; 43 | std::cerr << lcb_strerror(NULL, rows.rc) << std::endl; 44 | } 45 | } 46 | 47 | static void query_city(lcb_t instance, const char *city) 48 | { 49 | lcb_N1QLPARAMS *params = lcb_n1p_new(); 50 | lcb_error_t rc; 51 | lcb_CMDN1QL cmd = {}; 52 | Rows rows; 53 | 54 | // Need to make this properly formatted JSON 55 | std::string city_str; 56 | city_str += '"'; 57 | city_str += city; 58 | city_str += '"'; 59 | 60 | rc = lcb_n1p_setstmtz(params, "SELECT airportname FROM `travel-sample` " 61 | "WHERE city=$1 AND type=\"airport\""); 62 | rc = lcb_n1p_posparam(params, city_str.c_str(), city_str.size()); 63 | 64 | cmd.callback = query_callback; 65 | 66 | // To enable using prepared (optimized) statements, you can use 67 | // the LCB_CMDN1QL_F_PREPCACHE flag. This is equivalent to setting 68 | // 'adhoc=False' in other SDKs 69 | cmd.cmdflags |= LCB_CMDN1QL_F_PREPCACHE; 70 | 71 | rc = lcb_n1p_mkcmd(params, &cmd); 72 | rc = lcb_n1ql_query(instance, &rows, &cmd); 73 | if (rc != LCB_SUCCESS) { 74 | printf("Unable to schedule N1QL query: %s\n", lcb_strerror_short(rc)); 75 | exit(1); 76 | } 77 | lcb_wait(instance); 78 | 79 | std::cout << "Results for " << city << std::endl; 80 | dump_results(rows); 81 | lcb_n1p_free(params); 82 | } 83 | 84 | int main(int, char **) 85 | { 86 | lcb_t instance; 87 | lcb_create_st crst = {}; 88 | lcb_error_t rc; 89 | 90 | crst.version = 3; 91 | crst.v.v3.connstr = "couchbase://127.0.0.1/travel-sample"; 92 | crst.v.v3.username = "testuser"; 93 | crst.v.v3.passwd = "password"; 94 | rc = lcb_create(&instance, &crst); 95 | rc = lcb_connect(instance); 96 | lcb_wait(instance); 97 | rc = lcb_get_bootstrap_status(instance); 98 | if (rc != LCB_SUCCESS) { 99 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 100 | exit(1); 101 | } 102 | 103 | query_city(instance, "Reno"); 104 | query_city(instance, "Dallas"); 105 | query_city(instance, "Los Angeles"); 106 | 107 | lcb_destroy(instance); 108 | } 109 | -------------------------------------------------------------------------------- /c/retrieving.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Result { 8 | std::string value; 9 | lcb_error_t status; 10 | 11 | Result() : status(LCB_SUCCESS) {} 12 | }; 13 | 14 | extern "C" { 15 | static void get_callback(lcb_t, int, const lcb_RESPBASE *rb) 16 | { 17 | // "cast" to specific callback type 18 | const lcb_RESPGET *resp = reinterpret_cast< const lcb_RESPGET * >(rb); 19 | Result *my_result = reinterpret_cast< Result * >(rb->cookie); 20 | 21 | my_result->status = resp->rc; 22 | my_result->value.clear(); // Remove any prior value 23 | if (resp->rc == LCB_SUCCESS) { 24 | my_result->value.assign(reinterpret_cast< const char * >(resp->value), resp->nvalue); 25 | } 26 | } 27 | } 28 | 29 | int main(int, char **) 30 | { 31 | lcb_create_st crst = {}; 32 | lcb_t instance; 33 | lcb_error_t rc; 34 | 35 | crst.version = 3; 36 | crst.v.v3.connstr = "couchbase://127.0.0.1/travel-sample"; 37 | crst.v.v3.username = "testuser"; 38 | crst.v.v3.passwd = "password"; 39 | 40 | lcb_create(&instance, &crst); 41 | lcb_connect(instance); 42 | lcb_wait(instance); 43 | rc = lcb_get_bootstrap_status(instance); 44 | if (rc != LCB_SUCCESS) { 45 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 46 | exit(1); 47 | } 48 | 49 | // Store a key first, so we know it will exist later on. In real production 50 | // environments, we'd also want to install a callback for storage operations 51 | // so we know if they succeeded 52 | lcb_CMDSTORE scmd = {}; 53 | const char *key = "a_key"; 54 | const char *value = "{\"some\":\"json\"}"; 55 | LCB_CMD_SET_KEY(&scmd, key, strlen(key)); 56 | LCB_CMD_SET_VALUE(&scmd, value, strlen(value)); 57 | scmd.operation = LCB_SET; // Upsert 58 | 59 | lcb_sched_enter(instance); 60 | lcb_store3(instance, NULL, &scmd); 61 | lcb_sched_leave(instance); 62 | lcb_wait(instance); 63 | 64 | // Install the callback for GET operations. Note this can be done at any 65 | // time before the operation is scheduled 66 | lcb_install_callback3(instance, LCB_CALLBACK_GET, get_callback); 67 | 68 | Result my_result; 69 | lcb_CMDGET gcmd = {}; 70 | LCB_CMD_SET_KEY(&gcmd, key, strlen(key)); 71 | lcb_sched_enter(instance); 72 | lcb_get3(instance, &my_result, &gcmd); 73 | lcb_sched_leave(instance); 74 | lcb_wait(instance); 75 | 76 | std::cout << "Status for getting " << key << ": "; 77 | std::cout << lcb_strerror(NULL, my_result.status); 78 | std::cout << ". Value: " << my_result.value << std::endl; 79 | 80 | // Let's see what happens if we get a key that isn't yet stored: 81 | key = "non-exist-key"; 82 | LCB_CMD_SET_KEY(&gcmd, key, strlen(key)); 83 | 84 | lcb_sched_enter(instance); 85 | lcb_get3(instance, &my_result, &gcmd); 86 | lcb_sched_leave(instance); 87 | lcb_wait(instance); 88 | std::cout << "Status for getting " << key << ": "; 89 | std::cout << lcb_strerror(NULL, my_result.status) << std::endl; 90 | 91 | lcb_destroy(instance); 92 | } 93 | -------------------------------------------------------------------------------- /c/updating.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | lcb_error_t rc; 8 | lcb_cas_t cas; 9 | } my_OPINFO; 10 | 11 | static void update_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *resp) 12 | { 13 | my_OPINFO *info = resp->cookie; 14 | info->rc = resp->rc; 15 | info->cas = resp->cas; 16 | } 17 | 18 | int main(int argc, char **argv) 19 | { 20 | lcb_t instance; 21 | struct lcb_create_st crst = {}; 22 | lcb_error_t rc; 23 | lcb_CMDSTORE cmd = {0}; 24 | const char *key, *value; 25 | my_OPINFO info; 26 | 27 | crst.version = 3; 28 | crst.v.v3.connstr = "couchbase://127.0.0.1/default"; 29 | crst.v.v3.username = "testuser"; 30 | crst.v.v3.passwd = "password"; 31 | 32 | /* See connecting.c for error checking */ 33 | lcb_create(&instance, &crst); 34 | lcb_connect(instance); 35 | lcb_wait(instance); 36 | rc = lcb_get_bootstrap_status(instance); 37 | if (rc != LCB_SUCCESS) { 38 | printf("Unable to bootstrap cluster: %s\n", lcb_strerror_short(rc)); 39 | exit(1); 40 | } 41 | 42 | /* Set global storage callback */ 43 | lcb_install_callback3(instance, LCB_CALLBACK_STORE, update_callback); 44 | 45 | key = "docid"; 46 | value = "{\"property\":\"value\"}"; 47 | 48 | LCB_CMD_SET_KEY(&cmd, key, strlen(key)); 49 | LCB_CMD_SET_VALUE(&cmd, value, strlen(value)); 50 | 51 | lcb_sched_enter(instance); 52 | /* Schedule unconditional upsert (LCB_SET). Should always succeed */ 53 | cmd.operation = LCB_SET; 54 | rc = lcb_store3(instance, &info, &cmd); 55 | if (rc != LCB_SUCCESS) { 56 | printf("Couldn't schedule store operation: %s\n", lcb_strerror_short(rc)); 57 | exit(EXIT_FAILURE); 58 | } 59 | 60 | lcb_sched_leave(instance); 61 | lcb_wait(instance); 62 | 63 | printf("Upsert for %s got code %s (0 is success)\n", key, lcb_strerror_short(info.rc)); 64 | 65 | /* Preserve the operation structure, just changing the operation type */ 66 | lcb_sched_enter(instance); 67 | /* Do an insert (LCB_ADD). This will fail since the item already exists */ 68 | cmd.operation = LCB_ADD; 69 | lcb_store3(instance, &info, &cmd); 70 | lcb_sched_leave(instance); 71 | lcb_wait(instance); 72 | 73 | printf("Insert for %s got code %s (0 is success). Failure expected\n", key, lcb_strerror_short(info.rc)); 74 | 75 | /* Do a replace (LCB_REPLACE) */ 76 | cmd.operation = LCB_REPLACE; 77 | lcb_sched_enter(instance); 78 | lcb_store3(instance, &info, &cmd); 79 | lcb_sched_leave(instance); 80 | lcb_wait(instance); 81 | 82 | printf("Replace for %s got code %s\n", key, lcb_strerror_short(info.rc)); 83 | 84 | lcb_destroy(instance); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /dotnet/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /dotnet/AsyncBatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Couchbase; 7 | 8 | namespace DevGuide 9 | { 10 | class AsyncBatch : ConnectionBase 11 | { 12 | static void Main(string[] args) 13 | { 14 | new AsyncBatch().ExecuteAsync().Wait(); 15 | Console.Read(); 16 | } 17 | 18 | public override async Task ExecuteAsync() 19 | { 20 | var ids = new List { "doc1", "doc2", "doc4" }; 21 | await PrintAllDocumentsAsync(ids); 22 | } 23 | 24 | public async Task PrintAllDocumentsAsync(List ids) 25 | { 26 | var tasks = new List>>(); 27 | ids.ForEach(x => tasks.Add(_bucket.GetDocumentAsync(x))); 28 | 29 | var results = await Task.WhenAll(tasks); 30 | results.ToList().ForEach(doc => Console.WriteLine(doc.Status)); 31 | } 32 | } 33 | } 34 | 35 | #region [ License information ] 36 | 37 | /* ************************************************************ 38 | * 39 | * @author Couchbase 40 | * @copyright 2015 Couchbase, Inc. 41 | * 42 | * Licensed under the Apache License, Version 2.0 (the "License"); 43 | * you may not use this file except in compliance with the License. 44 | * You may obtain a copy of the License at 45 | * 46 | * http://www.apache.org/licenses/LICENSE-2.0 47 | * 48 | * Unless required by applicable law or agreed to in writing, software 49 | * distributed under the License is distributed on an "AS IS" BASIS, 50 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 51 | * See the License for the specific language governing permissions and 52 | * limitations under the License. 53 | * 54 | * ************************************************************/ 55 | 56 | #endregion 57 | -------------------------------------------------------------------------------- /dotnet/AsyncExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace DevGuide 6 | { 7 | public class AsyncExample : ConnectionBase 8 | { 9 | static void Main(string[] args) 10 | { 11 | Console.WriteLine("Before calling PrintDocumentAsync on thread {0}.", 12 | Thread.CurrentThread.ManagedThreadId); 13 | 14 | new AsyncExample().ExecuteAsync().Wait(); 15 | 16 | Console.WriteLine("After calling PrintDocumentAsync on thread {0}.", 17 | Thread.CurrentThread.ManagedThreadId); 18 | } 19 | 20 | public override async Task ExecuteAsync() 21 | { 22 | //call it asynchronously with await 23 | await PrintDocumentAsync("somekey"); 24 | } 25 | 26 | public async Task PrintDocumentAsync(string id) 27 | { 28 | Console.WriteLine("Before awaiting GetDocumentAsync on thread {0}.", 29 | Thread.CurrentThread.ManagedThreadId); 30 | 31 | var doc = await _bucket.GetDocumentAsync(id); 32 | 33 | Console.WriteLine("After awaiting GetDocumentAsync on thread {0}.", 34 | Thread.CurrentThread.ManagedThreadId); 35 | 36 | Console.WriteLine(doc.Content); 37 | } 38 | } 39 | } 40 | 41 | #region [ License information ] 42 | 43 | /* ************************************************************ 44 | * 45 | * @author Couchbase 46 | * @copyright 2015 Couchbase, Inc. 47 | * 48 | * Licensed under the Apache License, Version 2.0 (the "License"); 49 | * you may not use this file except in compliance with the License. 50 | * You may obtain a copy of the License at 51 | * 52 | * http://www.apache.org/licenses/LICENSE-2.0 53 | * 54 | * Unless required by applicable law or agreed to in writing, software 55 | * distributed under the License is distributed on an "AS IS" BASIS, 56 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 | * See the License for the specific language governing permissions and 58 | * limitations under the License. 59 | * 60 | * ************************************************************/ 61 | 62 | #endregion 63 | -------------------------------------------------------------------------------- /dotnet/BulkGet.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class BulkGet : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | // Call BulkInsert to generate some data 15 | await new BulkInsert().ExecuteAsync(); 16 | 17 | // Generate the keys to retrieve 18 | var keys = Enumerable.Range(1, 100).Select(i => "dotnetDevguideExample-" + i).ToList(); 19 | 20 | 21 | // Option 1a: use Get with a IList of document keys to retrieve 22 | // Note: There is no GetAsync overload that takes multiple keys (yet) 23 | // which is why this example wraps the synchronized method in a new Task. 24 | // If your code is fully synchronous, you can simply call _bucket.Get(...) 25 | var bulkResult = await Task.Run(() => _bucket.Get(keys)); 26 | 27 | var successCount = bulkResult.Where(r => r.Value.Success).Count(); 28 | Console.WriteLine("Got {0} values", bulkResult.Count); 29 | 30 | // Option 1b: Specify ParallelOptions to customize how the client parallelizes the gets 31 | var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 32 }; 32 | var bulkResult2 = await Task.Run(() => _bucket.Get(keys, parallelOptions)); 33 | 34 | successCount = bulkResult2.Where(r => r.Value.Success).Count(); 35 | Console.WriteLine("Got {0} values", successCount); 36 | 37 | // Option 2: Spawn multiple Upsert tasks and wait on for all to complete 38 | var bulkTasks = keys.Select(key => _bucket.GetAsync(key)); 39 | var bulkResults = await Task.WhenAll(bulkTasks); 40 | 41 | successCount = bulkResults.Where(r => r.Success).Count(); 42 | Console.WriteLine("Got {0} values", successCount); 43 | 44 | } 45 | 46 | static void Main(string[] args) 47 | { 48 | new BulkGet().ExecuteAsync().Wait(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dotnet/BulkInsert.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class BulkInsert : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | // Create 100 Data objects 15 | var data = Enumerable.Range(1, 100).Select(i => new Data { Number = i }); 16 | 17 | // Option 1a: use Upsert with an IDictionary of documents in upsert 18 | var bulkData = data.ToDictionary(d => "dotnetDevguideExample-" + d.Number); 19 | // Note: There is no UpsertAsync overload that takes multiple values (yet) 20 | // which is why this example wraps the synchronized method in a new Task. 21 | // If your code is fully synchronous, you can simply call _bucket.Upsert(...) 22 | var bulkResult = await Task.Run(() => _bucket.Upsert(bulkData)); 23 | 24 | var successCount = bulkResult.Where(r => r.Value.Success).Count(); 25 | Console.WriteLine("Upserted {0} values", bulkResult.Count); 26 | 27 | // Option 1b: Specify ParallelOptions to customize how the client parallelizes the upserts 28 | var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 32 }; 29 | var bulkResult2 = await Task.Run(() => _bucket.Upsert(bulkData, parallelOptions)); 30 | 31 | successCount = bulkResult2.Where(r => r.Value.Success).Count(); 32 | Console.WriteLine("Upserted {0} values", successCount); 33 | 34 | // Option 2: Spawn multiple Upsert tasks and wait on for all to complete 35 | var bulkTasks = bulkData.Select(d => _bucket.UpsertAsync(d.Key, d.Value)); 36 | var bulkResults = await Task.WhenAll(bulkTasks); 37 | 38 | successCount = bulkResults.Where(r => r.Success).Count(); 39 | Console.WriteLine("Upserted {0} values", successCount); 40 | } 41 | 42 | static void Main(string[] args) 43 | { 44 | new BulkInsert().ExecuteAsync().Wait(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dotnet/ConnectionBase.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using Couchbase.Configuration.Client; 3 | using Couchbase.Core; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | /// 11 | /// For an example of configuring the Couchbase connection through App.config/Web.config 12 | /// see the ConnectionConfig class 13 | /// 14 | public class ConnectionBase 15 | { 16 | protected ICluster _cluster; 17 | protected IBucket _bucket; 18 | 19 | public ConnectionBase() 20 | { 21 | Connect(); 22 | } 23 | 24 | private void Connect() 25 | { 26 | var config = GetConnectionConfig(); 27 | 28 | _cluster = new Cluster(config); 29 | _cluster.Authenticate("Administrator", "password"); 30 | 31 | _bucket = _cluster.OpenBucket(); 32 | } 33 | 34 | protected virtual ClientConfiguration GetConnectionConfig() 35 | { 36 | return new ClientConfiguration 37 | { 38 | Servers = new List { 39 | new Uri("http://localhost:8091/pools") 40 | }, 41 | BucketConfigs = new Dictionary 42 | { 43 | { "default", new BucketConfiguration 44 | { 45 | BucketName = "default", 46 | UseSsl = false, 47 | Password = "", 48 | DefaultOperationLifespan = 2000, 49 | PoolConfiguration = new PoolConfiguration 50 | { 51 | MaxSize = 10, 52 | MinSize = 5, 53 | SendTimeout = 12000 54 | } 55 | }} 56 | } 57 | }; 58 | } 59 | 60 | private void Disconnect() 61 | { 62 | _cluster.CloseBucket(_bucket); 63 | _bucket.Dispose(); 64 | _bucket = null; 65 | _cluster.Dispose(); 66 | _cluster = null; 67 | } 68 | 69 | public virtual async Task ExecuteAsync() 70 | { 71 | Console.WriteLine("Connected to bucket '{0}'", _bucket.Name); 72 | } 73 | 74 | static void Main(string[] args) 75 | { 76 | new ConnectionBase().ExecuteAsync().Wait(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /dotnet/ConnectionConfig.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using Couchbase.Core; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace DevGuide 7 | { 8 | public class ConnectionConfig 9 | { 10 | protected ICluster _cluster; 11 | protected IBucket _bucket; 12 | 13 | public ConnectionConfig() 14 | { 15 | Connect(); 16 | } 17 | 18 | private void Connect() 19 | { 20 | _cluster = new Cluster("couchbaseClients/couchbase"); 21 | _bucket = _cluster.OpenBucket(); 22 | } 23 | 24 | private void Disconnect() 25 | { 26 | _cluster.CloseBucket(_bucket); 27 | _bucket.Dispose(); 28 | _bucket = null; 29 | _cluster.Dispose(); 30 | _cluster = null; 31 | } 32 | 33 | public virtual async Task ExecuteAsync() 34 | { 35 | Console.WriteLine("Connected to bucket '{0}'", _bucket.Name); 36 | } 37 | 38 | static void Main(string[] args) 39 | { 40 | new ConnectionConfig().ExecuteAsync().Wait(); 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dotnet/Counter.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class Counter : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | var key = "dotnetDevguideExampleCounter-" + DateTime.Now.Ticks; 15 | 16 | // Try to increment a counter that doesn't exist. 17 | // This will create the counter with an initial value of 1 regardless of delta specified 18 | var counter = await _bucket.IncrementAsync(key, 10); 19 | Console.WriteLine("Initial value = N/A, Increment = 10, Counter value: " + counter.Value); 20 | 21 | // Remove the counter so we can try again 22 | await _bucket.RemoveAsync(key); 23 | Console.WriteLine("Trying again."); 24 | 25 | // Create a counter with an initial value of 13. Again, delta is ignored in this case. 26 | var counter2 = await _bucket.IncrementAsync(key, 10, 13); 27 | Console.WriteLine("Initial value = 13, Increment = 10, Counter value: " + counter2.Value); 28 | 29 | // Increment the counter by 10. If the counter exists, the inital value is ignored. 30 | var counter3 = await _bucket.IncrementAsync(key, 10, 13); 31 | Console.WriteLine("Initial value = 13, Increment = 10, Counter value: " + counter3.Value); 32 | 33 | // Decrement the counter by 20. 34 | var counter4 = await _bucket.DecrementAsync(key, 20, 13); 35 | Console.WriteLine("Initial value = 13, Decrement = 20, Counter value: " + counter4.Value); 36 | } 37 | 38 | static void Main(string[] args) 39 | { 40 | new Counter().ExecuteAsync().Wait(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dotnet/Data.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DevGuide 8 | { 9 | public class Data 10 | { 11 | public int Number { get; set; } 12 | public string Text { get; set; } 13 | public DateTime Date { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dotnet/DevGuide.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevGuide", "DevGuide.csproj", "{4B57140E-8E54-4A19-8BFC-DDAEC128AE4D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4B57140E-8E54-4A19-8BFC-DDAEC128AE4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4B57140E-8E54-4A19-8BFC-DDAEC128AE4D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4B57140E-8E54-4A19-8BFC-DDAEC128AE4D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4B57140E-8E54-4A19-8BFC-DDAEC128AE4D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /dotnet/Durability.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using Couchbase.IO; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace DevGuide 7 | { 8 | public class Durability : ConnectionBase 9 | { 10 | public override async Task ExecuteAsync() 11 | { 12 | var key = "dotnetDevguideExampleDurability-" + DateTime.Now.Ticks; 13 | var data = new Data 14 | { 15 | Number = 42, 16 | Text = "Life, the Universe, and Everything", 17 | Date = DateTime.UtcNow 18 | }; 19 | 20 | // The ReplicateTo parameter must be less than or equal to the number of replicas 21 | // you have configured. Assuming that 3 replicas are configured, the following call 22 | // waits for replication to 3 replicas and persistence to 4 nodes in total. 23 | var result = await _bucket.UpsertAsync(key, data, ReplicateTo.Three, PersistTo.Four); 24 | Console.WriteLine("Durability status: " + result.Durability); 25 | 26 | if(!result.Success) 27 | { 28 | if (result.Status == ResponseStatus.NoReplicasFound) 29 | Console.WriteLine("Write failed - not enough replicas configured to satisfy durability requirements"); 30 | else 31 | Console.WriteLine("An error has occured: {0}\r\n{1}", result.Message, result.Exception.ToString()); 32 | } 33 | else 34 | { 35 | // It's possible for a write to succeed, but not satisfy durability. 36 | // For example, writing with PersistTo.Two and ReplicateTo.Zero on a 1-node cluster. 37 | if (result.Durability == Couchbase.IO.Operations.Durability.NotSatisfied) 38 | Console.WriteLine("Write succeeded, but some durability requirements were not satisfied."); 39 | } 40 | 41 | // Wait for the write to be persisted to disk on one (normally the master) node. 42 | var result2 = await _bucket.UpsertAsync(key, data, ReplicateTo.Zero, PersistTo.One); 43 | Console.WriteLine("Durability status: " + result.Durability); 44 | } 45 | 46 | static void Main(string[] args) 47 | { 48 | new Durability ().ExecuteAsync().Wait(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dotnet/Expiration.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class Expiration : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | var key = "dotnetDevguideExampleExpiration-" + DateTime.Now.Ticks; 15 | 16 | // Creating a document with an time-to-live (expiration) of 2 seconds 17 | await _bucket.UpsertAsync(key, "Hello world!", TimeSpan.FromSeconds(2)); 18 | 19 | // Retrieving immediately 20 | var result = await _bucket.GetAsync(key); 21 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, result.Value, result.Status); 22 | 23 | // Waiting 4 seconds 24 | await Task.Delay(4000); 25 | 26 | // Retrieving after a 4 second delay 27 | var result2 = await _bucket.GetAsync(key); 28 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, result2.Value, result2.Status); 29 | 30 | 31 | // Creating an item with 1 second TTL 32 | await _bucket.UpsertAsync(key, "Hello world!", TimeSpan.FromSeconds(1)); 33 | 34 | // Retrieving the item and extending the TTL to 2 seconds with getAndTouch 35 | var result3 = await _bucket.GetAndTouchAsync(key, TimeSpan.FromSeconds(2)); 36 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, result3.Value, result3.Status); 37 | 38 | // Waiting 4 seconds again 39 | await Task.Delay(4000); 40 | 41 | var result4 = await _bucket.GetAsync(key); 42 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, result4.Value, result4.Status); 43 | 44 | 45 | // Creating an item without expiration 46 | await _bucket.UpsertAsync(key, "Hello world!"); 47 | 48 | // Updating the TTL with Touch 49 | var result5 = await _bucket.TouchAsync(key, TimeSpan.FromSeconds(2)); 50 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, "N/A", result5.Status); 51 | 52 | // Waiting 4 seconds yet again 53 | await Task.Delay(4000); 54 | 55 | var result6 = await _bucket.GetAsync(key); 56 | Console.WriteLine("[{0:HH:mm:ss.fff}] Got: '{1}', Status: {2}", DateTime.Now, result6.Value, result6.Status); 57 | } 58 | 59 | static void Main(string[] args) 60 | { 61 | new Expiration().ExecuteAsync().Wait(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dotnet/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DevGuide 8 | { 9 | public class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | Task.Run(() => AllExamples()); 14 | 15 | Console.ReadLine(); 16 | } 17 | 18 | private static async void AllExamples() 19 | { 20 | await new ConnectionBase().ExecuteAsync(); 21 | await new ConnectionConfig().ExecuteAsync(); 22 | await new Retrieve().ExecuteAsync(); 23 | await new Update().ExecuteAsync(); 24 | await new BulkInsert().ExecuteAsync(); 25 | await new BulkGet().ExecuteAsync(); 26 | await new FieldEncryptionAes().ExecuteAsync(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dotnet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DevGuide")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DevGuide")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4b57140e-8e54-4a19-8bfc-ddaec128ae4d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dotnet/Retrieve.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class Retrieve : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | var key = "dotnetDevguideExampleRetrieve-" + DateTime.Now.Ticks; 15 | var data = new Data 16 | { 17 | Number = 42, 18 | Text = "Life, the Universe, and Everything", 19 | Date = DateTime.UtcNow 20 | }; 21 | 22 | // Get non-existent document. 23 | // Note that it's enough to check the Status property, 24 | // We're only checking all three to show they exist. 25 | var notFound = await _bucket.GetAsync(key); 26 | if (!notFound.Success && 27 | notFound.Status == Couchbase.IO.ResponseStatus.KeyNotFound && 28 | notFound.Value == null) 29 | Console.WriteLine("Document doesn't exist!"); 30 | 31 | 32 | // Prepare a string value 33 | await _bucket.UpsertAsync(key, "Hello Couchbase!"); 34 | 35 | // Get a string value 36 | var nonDocResult = await _bucket.GetAsync(key); 37 | Console.WriteLine("Found: " + nonDocResult.Value); 38 | 39 | // Prepare a JSON document value 40 | await _bucket.UpsertAsync(key, data); 41 | 42 | // Get a JSON document string value 43 | var docResult = await _bucket.GetAsync(key); 44 | Console.WriteLine("Found: " + docResult.Value); 45 | } 46 | 47 | static void Main(string[] args) 48 | { 49 | new Retrieve().ExecuteAsync().Wait(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /dotnet/SyncExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace DevGuide 6 | { 7 | public class SyncExample : ConnectionBase 8 | { 9 | static void Main(string[] args) 10 | { 11 | Console.WriteLine("Before calling PrintDocumentAsync on thread {0}.", 12 | Thread.CurrentThread.ManagedThreadId); 13 | 14 | new SyncExample().ExecuteAsync().Wait(); 15 | 16 | 17 | Console.WriteLine("After calling PrintDocumentAsync on thread {0}.", 18 | Thread.CurrentThread.ManagedThreadId); 19 | } 20 | 21 | public override Task ExecuteAsync() 22 | { 23 | //call it synchronously with no await 24 | PrintDocumentAsync("somekey").Wait(); 25 | 26 | return Task.FromResult(0); 27 | } 28 | 29 | public Task PrintDocumentAsync(string id) 30 | { 31 | Console.WriteLine("Before awaiting GetDocumentAsync on thread {0}.", 32 | Thread.CurrentThread.ManagedThreadId); 33 | 34 | var doc = _bucket.GetDocumentAsync(id).Result; 35 | 36 | Console.WriteLine("After awaiting GetDocumentAsync on thread {0}.", 37 | Thread.CurrentThread.ManagedThreadId); 38 | 39 | Console.WriteLine(doc.Content); 40 | 41 | return Task.FromResult(0); 42 | } 43 | } 44 | } 45 | 46 | #region [ License information ] 47 | 48 | /* ************************************************************ 49 | * 50 | * @author Couchbase 51 | * @copyright 2015 Couchbase, Inc. 52 | * 53 | * Licensed under the Apache License, Version 2.0 (the "License"); 54 | * you may not use this file except in compliance with the License. 55 | * You may obtain a copy of the License at 56 | * 57 | * http://www.apache.org/licenses/LICENSE-2.0 58 | * 59 | * Unless required by applicable law or agreed to in writing, software 60 | * distributed under the License is distributed on an "AS IS" BASIS, 61 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 62 | * See the License for the specific language governing permissions and 63 | * limitations under the License. 64 | * 65 | * ************************************************************/ 66 | 67 | #endregion 68 | -------------------------------------------------------------------------------- /dotnet/Update.cs: -------------------------------------------------------------------------------- 1 | using Couchbase; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DevGuide 9 | { 10 | public class Update : ConnectionBase 11 | { 12 | public override async Task ExecuteAsync() 13 | { 14 | var key = "dotnetDevguideExampleUpdate-" + DateTime.Now.Ticks; 15 | var data = new Data 16 | { 17 | Number = 42, 18 | Text = "Life, the Universe, and Everything", 19 | Date = DateTime.UtcNow 20 | }; 21 | 22 | // Prepare the document 23 | // Note that upsert works whether the document exists or not 24 | await _bucket.UpsertAsync(key, data); 25 | 26 | // Change the data 27 | data.Number++; 28 | data.Text = "What's 7 * 6 + 1?"; 29 | data.Date = DateTime.UtcNow; 30 | 31 | 32 | // Try to insert under the same key should fail 33 | var insertResult = await _bucket.InsertAsync(key, data); 34 | if (!insertResult.Success) 35 | Console.WriteLine("Inserting under an existing key fails as expected."); 36 | 37 | 38 | // Replace existing document 39 | // Note this only works if the key already exists 40 | var replaceResult = await _bucket.ReplaceAsync(key, data); 41 | 42 | 43 | // Check that the data was updated 44 | var newDocument = await _bucket.GetAsync(key); 45 | Console.WriteLine("Got: " + data.Text); 46 | } 47 | 48 | static void Main(string[] args) 49 | { 50 | new Update().ExecuteAsync().Wait(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dotnet/etc/person.json: -------------------------------------------------------------------------------- 1 | { 2 | "password": "ssloBeD12345", 3 | "firstName": "Ted", 4 | "lastName": "DeBloss", 5 | "userName": null, 6 | "age": 33 7 | } -------------------------------------------------------------------------------- /dotnet/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /etc/field-level-encryption/.gitignore: -------------------------------------------------------------------------------- 1 | *.cer 2 | *.key 3 | *.pfx 4 | -------------------------------------------------------------------------------- /etc/field-level-encryption/create-cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | set -e 4 | 5 | # generate an RSA private key 6 | openssl genrsa -out private.key 2048 7 | 8 | # optionally remove the password 9 | # openssl rsa -in private.key -out private-nokey.pem 10 | 11 | # generate a new x509 certificate from the private key 12 | openssl req -new -x509 -key private.key -out publickey.cer -days 365 13 | 14 | # export the private key and the x509 certificate into a .pfx uisng a password: 15 | openssl pkcs12 -export -out public_privatekey.pfx -inkey private.key -in publickey.cer 16 | -------------------------------------------------------------------------------- /etc/x509-cert/.gitignore: -------------------------------------------------------------------------------- 1 | SSLCA 2 | -------------------------------------------------------------------------------- /etc/x509-cert/create-keystore-for-java.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # Create keystore file and import ROOT/INTERMEDIATE/CLIENT cert 4 | # This is specific to Java SDK 5 | 6 | export ROOT_CA=ca 7 | export INTERMEDIATE=int 8 | export TOPDIR=SSLCA 9 | export ROOT_DIR=rootdir 10 | export INT_DIR=intdir 11 | export KEYSTORE_DIR=keystore 12 | 13 | export USERNAME=testuser 14 | export KEYSTORE_FILE=keystore.jks 15 | export STOREPASS=123456 16 | 17 | 18 | cd ${TOPDIR} 19 | mkdir -p ${KEYSTORE_DIR} 20 | cd ${KEYSTORE_DIR} 21 | 22 | keytool -genkey -keyalg RSA -alias selfsigned -keystore ${KEYSTORE_FILE} -storepass ${STOREPASS} -validity 360 -keysize 2048 -noprompt \ 23 | -dname "CN=${USERNAME}, OU=None, O=None, L=None, S=None, C=US" \ 24 | -keypass ${STOREPASS} -storetype pkcs12 25 | 26 | keytool -certreq -alias selfsigned -keyalg RSA -file my.csr -keystore ${KEYSTORE_FILE} -storepass ${STOREPASS} -noprompt -storetype pkcs12 27 | openssl x509 -req -in my.csr -CA ../${INT_DIR}/${INTERMEDIATE}.pem -CAkey ../${INT_DIR}/${INTERMEDIATE}.key -CAcreateserial -out clientcert.pem -days 365 28 | 29 | # Add ROOT CA 30 | keytool -import -trustcacerts -file ../${ROOT_DIR}/${ROOT_CA}.pem -alias root -keystore ${KEYSTORE_FILE} -storepass ${STOREPASS} -noprompt -storetype pkcs12 31 | # Add Intermediate 32 | keytool -import -trustcacerts -file ../${INT_DIR}/${INTERMEDIATE}.pem -alias int -keystore ${KEYSTORE_FILE} -storepass ${STOREPASS} -noprompt -storetype pkcs12 33 | keytool -import -keystore ${KEYSTORE_FILE} -file clientcert.pem -alias selfsigned -storepass ${STOREPASS} -noprompt -storetype pkcs12 34 | -------------------------------------------------------------------------------- /etc/x509-cert/create-pfx-for-net.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | export PFX_DIR=pfx 4 | export TOPDIR=SSLCA 5 | export CLIENT_DIR=clientdir 6 | 7 | export CLIENT=client 8 | export CHAIN=chain 9 | 10 | 11 | 12 | cd ${TOPDIR} 13 | mkdir -p ${PFX_DIR} 14 | cd ${PFX_DIR} 15 | 16 | openssl pkcs12 -export -inkey ../${ROOT_DIR}/${ROOT_CA}.key -inkey ../${INT_DIR}/${INTERMEDIATE}.key -inkey ../${CLIENT_DIR}/${CLIENT}.key -in ../${CLIENT_DIR}/chain.pem -out client.pfx 17 | 18 | #On windows, double click on pfx file and Install pfx file on Local Machine section. Location should be "Trusted Root Certification Authorities" 19 | -------------------------------------------------------------------------------- /etc/x509-cert/generate-new-client-cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | export CB_ROOT=/opt/couchbase 4 | # export CB_ROOT=${HOME}/code/couchbase/server/install 5 | 6 | # Create environment variables for the naming of a directory-structure, within 7 | # which will reside the certificates you create for root, intermediate, and 8 | # node. 9 | # 10 | # Note that in cases where multiple intermediate and/or node certificates are 11 | # to be included in the certificate-chain, multiple intermediate and/or 12 | # directories are required — one for each intermediate or certificate. 13 | export TOPDIR=SSLCA 14 | export ROOT_DIR=rootdir 15 | export CLIENT_DIR=clientdir 16 | export INT_DIR=intdir 17 | 18 | # Create environment variables for each of the certificate-files to be created. 19 | # 20 | # Note that in cases where multiple intermediate and/or node certificates are 21 | # to be included in the certificate-chain, additional environment-variable 22 | # definitions — one for each of the additional intermediate and/or node 23 | # certificates — are required. 24 | export ROOT_CA=ca 25 | export INTERMEDIATE=int 26 | export CLIENT=client 27 | export CHAIN=chain 28 | export TRUST=trust 29 | 30 | # Create environment variables for the administrator-credentials to be used for 31 | # certificate-management, the IP address at which the Couchbase Server-node is 32 | # located, and the username required for role-based access to a particular 33 | # resource. 34 | # 35 | # Note that in this example, the username is specified as travel-sample, which 36 | # is typically associated with the Bucket Full Access role, on the bucket 37 | # travel-sample. For access to be fully tested, ensure that the travel-sample 38 | # user has indeed been defined on the Couchbase Server-node, and is associated 39 | # with the Bucket Full Access role. (See Authorization for more information on 40 | # RBAC.) 41 | export ADMINCRED=Administrator:password 42 | export ip=127.0.0.1 43 | export USERNAME=testuser 44 | 45 | cd ${TOPDIR} 46 | 47 | mkdir -p ${CLIENT_DIR} 48 | 49 | cd ${CLIENT_DIR} 50 | openssl genrsa -out ${CLIENT}.key 2048 51 | openssl req -new -key ${CLIENT}.key -out ${CLIENT}.csr -subj "/CN=${USERNAME}/OU=None/O=None/L=None/S=None/C=US" 52 | openssl x509 -req -in ${CLIENT}.csr -CA ../${INT_DIR}/${INTERMEDIATE}.pem \ 53 | -CAkey ../${INT_DIR}/${INTERMEDIATE}.key -CAcreateserial \ 54 | -CAserial ../${INT_DIR}/intermediateCA.srl -out ${CLIENT}.pem -days 365 -extfile ../openssl.cnf -extensions 'v3_req' 55 | 56 | cat ../${INT_DIR}/${INTERMEDIATE}.pem ../${ROOT_DIR}/${ROOT_CA}.pem > ./${TRUST}.pem 57 | cat ./${CLIENT}.pem ../${INT_DIR}/${INTERMEDIATE}.pem ../${ROOT_DIR}/${ROOT_CA}.pem > ./${CHAIN}.pem 58 | 59 | set +x 60 | echo "ROOT CA: $(realpath ../${ROOT_DIR}/${ROOT_CA}.pem)" 61 | echo "INTERMEDIATE CA: $(realpath ../${INT_DIR}/${INTERMEDIATE}.pem)" 62 | echo "TRUSTSTORE CA (ROOT+INTERMEDIATE): $(realpath ./${TRUST}.pem)" 63 | echo "CHAINED: $(realpath ./${CHAIN}.pem)" 64 | echo "CLIENT CERT: $(realpath ./${CLIENT}.pem)" 65 | -------------------------------------------------------------------------------- /go/bulk-get.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | 7 | "gopkg.in/couchbase/gocb.v1" 8 | ) 9 | 10 | // bucket reference - reuse as bucket reference in the application 11 | var bucket *gocb.Bucket 12 | 13 | func main() { 14 | // Connect to Cluster 15 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 16 | if err != nil { 17 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 18 | } 19 | 20 | // Open Bucket 21 | bucket, err = cluster.OpenBucket("travel-sample", "") 22 | if err != nil { 23 | fmt.Println("ERROR OPENING BUCKET:", err) 24 | } 25 | 26 | // Create a JSON document 27 | type Doc struct { 28 | Item string `json:"item"` 29 | } 30 | key := "goDevguideExampleBulkInsert" 31 | val := Doc{"A bulk insert test value"} 32 | 33 | // Create Array of BulkOps for Insert, and one for Get 34 | var items []gocb.BulkOp 35 | var itemsGet []gocb.BulkOp 36 | 37 | // Add 10 items to the array that will be performed as a bulk operation 38 | for i := 0; i < 10; i++ { 39 | items = append(items, &gocb.InsertOp{Key: key + "_" + strconv.Itoa(i), Value: &val}) 40 | } 41 | 42 | // Perform the bulk operation to Insert 43 | err = bucket.Do(items) 44 | if err != nil { 45 | fmt.Println("ERROR PERFORMING BULK INSERT:", err) 46 | } 47 | 48 | // Retrieve 10 items to the array that will be performed as a bulk operation 49 | for i := 0; i < 10; i++ { 50 | itemsGet = append(itemsGet, &gocb.GetOp{Key: key + "_" + strconv.Itoa(i), Value: &Doc{}}) 51 | } 52 | 53 | // Perform the bulk operation to Get 54 | err = bucket.Do(itemsGet) 55 | if err != nil { 56 | fmt.Println("ERROR PERFORMING BULK GET:", err) 57 | } 58 | 59 | // Print the output 60 | for i := 0; i < len(itemsGet); i++ { 61 | fmt.Println(itemsGet[i].(*gocb.GetOp).Key, itemsGet[i].(*gocb.GetOp).Value.(*Doc).Item) 62 | } 63 | 64 | // Exiting 65 | fmt.Println("Example Successful - Exiting") 66 | } 67 | -------------------------------------------------------------------------------- /go/bulk-insert.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | 7 | "gopkg.in/couchbase/gocb.v1" 8 | ) 9 | 10 | // bucket reference - reuse as bucket reference in the application 11 | var bucket *gocb.Bucket 12 | 13 | func main() { 14 | // Connect to Cluster 15 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 16 | if err != nil { 17 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 18 | } 19 | 20 | // Open Bucket 21 | bucket, err = cluster.OpenBucket("travel-sample", "") 22 | if err != nil { 23 | fmt.Println("ERROR OPENING BUCKET:", err) 24 | } 25 | 26 | // Create a JSON document 27 | type Doc struct { 28 | Item string `json:"item"` 29 | } 30 | key := "goDevguideExampleBulkInsert" 31 | val := Doc{"A bulk insert test value"} 32 | 33 | // Create an Array of BulkOps for Insert 34 | var items []gocb.BulkOp 35 | 36 | // Add 10 items to the array that will be performed as a bulk operation 37 | for i := 0; i < 10; i++ { 38 | items = append(items, &gocb.InsertOp{Key: key + "_" + strconv.Itoa(i), Value: &val}) 39 | } 40 | 41 | // Perform the bulk operation 42 | err = bucket.Do(items) 43 | if err != nil { 44 | fmt.Println("ERROR PERFORMING BULK INSERT:", err) 45 | } 46 | 47 | // Exiting 48 | fmt.Println("Example Successful - Exiting") 49 | } 50 | -------------------------------------------------------------------------------- /go/cloud.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "gopkg.in/couchbase/gocb.v1" 8 | ) 9 | 10 | func main() { 11 | // Uncomment following line to enable logging 12 | // gocb.SetLogger(gocb.VerboseStdioLogger()) 13 | endpoint := "cb.e493356f-f395-4561-a6b5-a3a1ec0aaa29.dp.cloud.couchbase.com" 14 | bucketName := "couchbasecloudbucket" 15 | username := "user" 16 | password := "password" 17 | 18 | // Initialize the Connection 19 | cluster, err := gocb.Connect("couchbases://" + endpoint + "?ssl=no_verify") 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | _ = cluster.Authenticate(gocb.PasswordAuthenticator{ 25 | Username: username, 26 | Password: password, 27 | }) 28 | 29 | bucket, err := cluster.OpenBucket(bucketName, "") 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | fmt.Println("Connected..") 34 | 35 | // Create a N1QL Primary Index (but ignore if it exists) 36 | err = bucket.Manager("", "").CreatePrimaryIndex("", true, false) 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | 41 | type User struct { 42 | Name string `json:"name"` 43 | Email string `json:"email"` 44 | Interests []string `json:"interests"` 45 | } 46 | 47 | // Create and store a Document 48 | _, err = bucket.Upsert("u:kingarthur", 49 | User{ 50 | Name: "Arthur", 51 | Email: "kingarthur@couchbase.com", 52 | Interests: []string{"Holy Grail", "African Swallows"}, 53 | }, 0) 54 | if err != nil { 55 | log.Fatal(err) 56 | } 57 | 58 | // Get the document back 59 | var inUser User 60 | _, err = bucket.Get("u:kingarthur", &inUser) 61 | if err != nil { 62 | log.Fatal(err) 63 | } 64 | fmt.Printf("User: %v\n", inUser) 65 | 66 | // Perform a N1QL Query 67 | query := gocb.NewN1qlQuery(fmt.Sprintf("SELECT name FROM `%s` WHERE $1 IN interests", bucketName)) 68 | rows, err := bucket.ExecuteN1qlQuery(query, []interface{}{"African Swallows"}) 69 | if err != nil { 70 | log.Fatal(err) 71 | } 72 | 73 | // Print each found Row 74 | var row interface{} 75 | for rows.Next(&row) { 76 | fmt.Printf("Row: %v", row) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /go/connecting-cca.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | func main() { 10 | // Connect to the cluster using certificates and node key, note: couchbases 11 | cluster, err := gocb.Connect("couchbases://10.111.175.101?" + 12 | "cacertpath=../x509/ca.pem&" + 13 | "certpath=../x509/chain.pem&" + 14 | "keypath=../x509/pkey.key") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | 19 | // Use the CertificateAuthenticator to authenticate 20 | cluster.Authenticate(gocb.CertificateAuthenticator{}) 21 | 22 | // Open the bucket 23 | _, err = cluster.OpenBucket("travel-sample", "") 24 | if err != nil { 25 | fmt.Println("ERROR OPENING BUCKET:", err) 26 | } 27 | 28 | fmt.Println("Example Successful - Exiting") 29 | 30 | } 31 | -------------------------------------------------------------------------------- /go/connecting.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | fmt.Println("Example Successful - Exiting") 24 | } 25 | -------------------------------------------------------------------------------- /go/counter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Create a document and assign it to 10 - counter works atomically by 25 | // first creating a document if it doesn't exist. If it exists, the 26 | // same method will increment/decrement per the "delta" parameter 27 | key := "goDevguideExampleCounter" 28 | curKeyValue, _, err := bucket.Counter(key, 2, 10, 0) 29 | if err != nil { 30 | fmt.Println("ERROR CREATING KEY:", err) 31 | } 32 | 33 | // Should Print 10 34 | fmt.Println("Initialized Counter:", curKeyValue) 35 | 36 | // Issue same operation, increment value by 2, to 12 37 | curKeyValue, _, err = bucket.Counter(key, 2, 10, 0) 38 | if err != nil { 39 | fmt.Println("ERROR CREATING KEY:", err) 40 | } 41 | 42 | // Should Print 12 43 | fmt.Println("Incremented Counter:", curKeyValue) 44 | 45 | // Exiting 46 | fmt.Println("Example Successful - Exiting") 47 | } 48 | -------------------------------------------------------------------------------- /go/durability.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "gopkg.in/couchbase/gocb.v1" 8 | ) 9 | 10 | // bucket reference - reuse as bucket reference in the application 11 | var bucket *gocb.Bucket 12 | 13 | func main() { 14 | // Connect to Cluster 15 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 16 | if err != nil { 17 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 18 | } 19 | // Open Bucket 20 | bucket, err = cluster.OpenBucket("travel-sample", "") 21 | if err != nil { 22 | fmt.Println("ERROR OPENING BUCKET:", err) 23 | } 24 | // Set Durability Timeout to 3 seconds, default is 40 seconds 25 | bucket.SetDurabilityTimeout(3 * time.Second) 26 | 27 | // Create a document and assign a "Persist To" value of 1 node. 28 | // Should Always Succeed, even on single node cluster. 29 | // NOTICE the function signature: 30 | // Bucket.UpsertDura(key, value, expiry, replicateTo, _PERSIST_TO_) 31 | key := "goDevguideExamplePersistTo" 32 | val := "Durabilty PersistTo Test Value" 33 | _, err = bucket.UpsertDura(key, &val, 0, 0, 1) 34 | if err != nil { 35 | fmt.Println("ERROR, DURABILITY Persist Example:", err) 36 | } 37 | 38 | // Retrieve Value Persist To 39 | var retValue interface{} 40 | _, err = bucket.Get(key, &retValue) 41 | if err != nil { 42 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 43 | } 44 | fmt.Println("Document Retrieved:", retValue) 45 | 46 | // Create a document and assign a "Replicate To" value of 1 node. 47 | // Should Fail on a single node cluster, succeed on a multi node 48 | // cluster of 3 or more nodes with at least one replica enabled. 49 | // NOTICE the function signature: 50 | // Bucket.UpsertDura(key, value, expiry, _REPLICATE_TO_, persistTo) 51 | 52 | key = "goDevguideExampleReplicateTo" 53 | val = "Durabilty ReplicateTo Test Value" 54 | _, err = bucket.UpsertDura(key, &val, 0, 1, 0) 55 | if err != nil { 56 | fmt.Println("ERROR, DURABILITY Replicate Example:", err) 57 | } 58 | 59 | // Retrieve Value Replicate To 60 | // Should succeed even if durability fails, as the document was 61 | // still written. 62 | _, err = bucket.Get(key, &retValue) 63 | if err != nil { 64 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 65 | } 66 | fmt.Println("Document Retrieved:", retValue) 67 | 68 | // Create a document and assign a "Replicate To" and a "Persist TO" 69 | // value of 1 node. Should Fail on a single node cluster, succeed on 70 | // a multi node cluster of 3 or more nodes with at least one replica 71 | // enabled. 72 | // NOTICE the function signature: 73 | // Bucket.UpsertDura(key, value, expiry, _REPLICATE_TO_, _PERSIST_TO_) 74 | 75 | key = "goDevguideExampleReplicateToAndPersistTo" 76 | val = "Durabilty ReplicateTo and PersistTo Test Value" 77 | _, err = bucket.UpsertDura(key, &val, 0, 1, 1) 78 | if err != nil { 79 | fmt.Println("ERROR, DURABILITY Replicate and Persist Example:", err) 80 | } 81 | 82 | // Retrieve Value Replicate To and Persist To 83 | // Should succeed even if durability fails, as the document was 84 | // still written. 85 | _, err = bucket.Get(key, &retValue) 86 | if err != nil { 87 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 88 | } 89 | fmt.Println("Document Retrieved:", retValue) 90 | 91 | // Exiting 92 | fmt.Println("Example Complete - Exiting") 93 | } 94 | -------------------------------------------------------------------------------- /go/expiration.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "gopkg.in/couchbase/gocb.v1" 8 | ) 9 | 10 | // bucket reference - reuse as bucket reference in the application 11 | var bucket *gocb.Bucket 12 | 13 | func main() { 14 | // Connect to Cluster 15 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 16 | if err != nil { 17 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 18 | } 19 | // Open Bucket 20 | bucket, err = cluster.OpenBucket("travel-sample", "") 21 | if err != nil { 22 | fmt.Println("ERROR OPENING BUCKET:", err) 23 | } 24 | 25 | // Create a document and assign an expiration of 2 seconds 26 | key := "goDevguideExampleExpiration" 27 | val := "Expiration Test Value" 28 | _, err = bucket.Upsert(key, &val, 2) 29 | if err != nil { 30 | fmt.Println("ERROR CREATING DOCUMENT:", err) 31 | } 32 | 33 | // Retrieve Value Right Away 34 | var retValue interface{} 35 | _, err = bucket.Get(key, &retValue) 36 | if err != nil { 37 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 38 | } 39 | fmt.Println("Document Not Yet Expired:", retValue) 40 | 41 | // Sleep for 4 seconds 42 | time.Sleep(4 * time.Second) 43 | 44 | // Try to retrieve document when Expired 45 | _, err = bucket.Get(key, &retValue) 46 | if err != nil { 47 | fmt.Println("Document Expired:", err) 48 | } 49 | 50 | // Create a document with no expiration, and add an expiry using 51 | // touch after the document is created of 2 seconds 52 | _, err = bucket.Upsert(key, &val, 2) 53 | if err != nil { 54 | fmt.Println("ERROR CREATING DOCUMENT:", err) 55 | } 56 | 57 | // Add an expiry 58 | _, err = bucket.Touch(key, 0, 2) 59 | if err != nil { 60 | fmt.Println("ERROR TOUCHING DOCUMENT:", err) 61 | } 62 | 63 | // Retrieve Document 64 | _, err = bucket.Get(key, &retValue) 65 | if err != nil { 66 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 67 | } 68 | fmt.Println("Document Not Yet Expired:", retValue) 69 | 70 | // Sleep for 4 seconds 71 | time.Sleep(4 * time.Second) 72 | 73 | // Try to retrieve document when Expired 74 | _, err = bucket.Get(key, &retValue) 75 | if err != nil { 76 | fmt.Println("Document Expired:", err) 77 | } 78 | 79 | // Exiting 80 | fmt.Println("Example Successful - Exiting") 81 | } 82 | -------------------------------------------------------------------------------- /go/field-encryption.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/couchbaselabs/gocbfieldcrypt" 5 | "gopkg.in/couchbase/gocb.v1" 6 | "log" 7 | ) 8 | 9 | type Person struct { 10 | Password string `json:"password" cbcrypt:"aes256,publickey,mysecret"` 11 | FirstName string 12 | LastName string 13 | UserName string 14 | Age int 15 | } 16 | 17 | var bucket *gocb.Bucket 18 | 19 | func main() { 20 | // Connect to the cluster 21 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 22 | if err != nil { 23 | panic(err) 24 | } 25 | 26 | cluster.Authenticate(gocb.PasswordAuthenticator{ 27 | Username: "Administrator", 28 | Password: "password", 29 | }) 30 | 31 | bucket, err := cluster.OpenBucket("default", "") 32 | if err != nil { 33 | panic(err) 34 | } 35 | 36 | // Set up our key store 37 | publicKey := "!mysecretkey#9^5usdk39d&dlf)03sL" 38 | signingKey := "myauthpassword" 39 | keyStore := &gocbfieldcrypt.InsecureKeystore{ 40 | Keys: map[string][]byte{ 41 | "publickey": []byte(publicKey), 42 | "mysecret": []byte(signingKey), 43 | }, 44 | } 45 | 46 | // Set up our bucket to transcode via the field level encryption library 47 | bucket.SetTranscoder(&gocbfieldcrypt.Transcoder{ 48 | KeyStore: keyStore, 49 | }) 50 | 51 | // The Password field will be encrypted - see the definition of the 52 | // People struct above for reference of how to annotate the property 53 | teddy := Person{ 54 | Age: 33, 55 | FirstName: "Ted", 56 | LastName: "DeBloss", 57 | Password: "ssloBeD12345", 58 | } 59 | 60 | //Password field will be encrypted in transport and at rest in the database 61 | _, err = bucket.Upsert("person::1", teddy, 0) 62 | if err != nil { 63 | panic(err) 64 | } 65 | 66 | // If the document is fetched without using the struct it will by-pass decryption so we 67 | // can see how the document is stored within Couchbase without triggering decryption 68 | var encryptedDoc interface{} 69 | _, err = bucket.Get("person::1", &encryptedDoc) 70 | if err != nil { 71 | panic(err) 72 | } 73 | 74 | log.Printf("Encrypted: %+v", encryptedDoc) 75 | 76 | // Fetching the document will reverse the encryption process so Password at the 77 | // application only will be in plaintext. In transport and in storage it will encrypted. 78 | var decryptedDoc Person 79 | _, err = bucket.Get("person::1", &decryptedDoc) 80 | if err != nil { 81 | panic(err) 82 | } 83 | 84 | log.Printf("Decrypted: %+v", encryptedDoc) 85 | } 86 | -------------------------------------------------------------------------------- /go/query-create-index.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Setup a new query for building an index 25 | myQuery := gocb.NewN1qlQuery("CREATE PRIMARY INDEX ON `travel-sample`") 26 | rows, err := bucket.ExecuteN1qlQuery(myQuery, nil) 27 | if err != nil { 28 | fmt.Println("ERROR EXECUTING N1QL QUERY:", err) 29 | } 30 | 31 | // Iterate through rows and print output 32 | var row interface{} 33 | for rows.Next(&row) { 34 | fmt.Printf("Results: %+v\n", row) 35 | } 36 | 37 | // Exiting 38 | fmt.Println("Example Successful - Exiting") 39 | } 40 | -------------------------------------------------------------------------------- /go/query-criteria.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Setup a new query 25 | myQuery := gocb.NewN1qlQuery("SELECT airportname, city, country FROM `travel-sample` " + 26 | "WHERE type='airport' AND city='Reno' ") 27 | rows, err := bucket.ExecuteN1qlQuery(myQuery, nil) 28 | if err != nil { 29 | fmt.Println("ERROR EXECUTING N1QL QUERY:", err) 30 | } 31 | 32 | // Iterate through rows and print output 33 | var row interface{} 34 | for rows.Next(&row) { 35 | fmt.Printf("Results: %+v\n", row) 36 | } 37 | 38 | // Exiting 39 | fmt.Println("Example Successful - Exiting") 40 | } 41 | -------------------------------------------------------------------------------- /go/query-placeholders.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Setup a new query with a placeholder 25 | myQuery := gocb.NewN1qlQuery("SELECT airportname, city, country FROM `travel-sample` " + 26 | "WHERE type='airport' AND city=$1 ") 27 | 28 | // Setup an array for parameters 29 | var myParams []interface{} 30 | myParams = append(myParams, "Reno") 31 | 32 | // Execute Query 33 | rows, err := bucket.ExecuteN1qlQuery(myQuery, myParams) 34 | if err != nil { 35 | fmt.Println("ERROR EXECUTING N1QL QUERY:", err) 36 | } 37 | 38 | // Iterate through rows and print output 39 | var row interface{} 40 | for rows.Next(&row) { 41 | fmt.Printf("Results: %+v\n", row) 42 | } 43 | 44 | // Exiting 45 | fmt.Println("Example Successful - Exiting") 46 | } 47 | -------------------------------------------------------------------------------- /go/retrieving.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Create a document 25 | key := "goDevguideExampleRetrieve" 26 | val := "Retrieve Test Value" 27 | _, err = bucket.Upsert(key, &val, 0) 28 | if err != nil { 29 | fmt.Println("ERROR CREATING DOCUMENT:", err) 30 | } 31 | 32 | // Retrieve Document 33 | var retValue interface{} 34 | _, err = bucket.Get(key, &retValue) 35 | if err != nil { 36 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 37 | } 38 | fmt.Println("Document Retrieved:", retValue) 39 | 40 | // Exiting 41 | fmt.Println("Example Successful - Exiting") 42 | } 43 | -------------------------------------------------------------------------------- /go/updating.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "gopkg.in/couchbase/gocb.v1" 7 | ) 8 | 9 | // bucket reference - reuse as bucket reference in the application 10 | var bucket *gocb.Bucket 11 | 12 | func main() { 13 | // Connect to Cluster 14 | cluster, err := gocb.Connect("couchbase://127.0.0.1") 15 | if err != nil { 16 | fmt.Println("ERROR CONNECTING TO CLUSTER:", err) 17 | } 18 | // Open Bucket 19 | bucket, err = cluster.OpenBucket("travel-sample", "") 20 | if err != nil { 21 | fmt.Println("ERROR OPENING BUCKET:", err) 22 | } 23 | 24 | // Create a document 25 | key := "goDevguideExampleUpdate" 26 | val := "Retrieve Test Value" 27 | _, err = bucket.Upsert(key, &val, 0) 28 | if err != nil { 29 | fmt.Println("ERROR CREATING DOCUMENT:", err) 30 | } 31 | 32 | // Retrieve Document 33 | var retValue interface{} 34 | _, err = bucket.Get(key, &retValue) 35 | if err != nil { 36 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 37 | } 38 | fmt.Println("Document Retrieved:", retValue) 39 | 40 | // Add something to the value 41 | retValue = retValue.(string) + " with Additional Test Value" 42 | 43 | // Replace the existing document 44 | _, err = bucket.Replace(key, &retValue, 0, 0) 45 | if err != nil { 46 | fmt.Println("ERROR REPLACING DOCUMENT:", err) 47 | } 48 | 49 | // Retrieve updated document 50 | _, err = bucket.Get(key, &retValue) 51 | if err != nil { 52 | fmt.Println("ERROR RETURNING DOCUMENT:", err) 53 | } 54 | fmt.Println("Document Retrieved:", retValue) 55 | 56 | // Exiting 57 | fmt.Println("Example Successful - Exiting") 58 | } 59 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.couchbase 5 | devguide 6 | 1.0-SNAPSHOT 7 | 8 | 9 | 1.8 10 | 1.8 11 | 12 | 13 | 14 | 15 | com.couchbase.client 16 | java-client 17 | 2.7.9 18 | 19 | 20 | com.couchbase.client 21 | encryption 22 | 2.0.1 23 | 24 | 25 | log4j 26 | log4j 27 | 1.2.17 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.apache.maven.plugins 35 | maven-compiler-plugin 36 | 3.8.1 37 | 38 | 1.8 39 | 1.8 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/ConnectingCertAuth.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.Bucket; 4 | import com.couchbase.client.java.Cluster; 5 | import com.couchbase.client.java.CouchbaseCluster; 6 | import com.couchbase.client.java.env.CouchbaseEnvironment; 7 | import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; 8 | 9 | /** 10 | * This example shows how to connect to a couchbase server EE cluster using 11 | * client certificate authentication. 12 | * 13 | * Please make sure to follow the proper server side documentation on how to 14 | * import the certifactes into the server and set up the Java keystore. 15 | * 16 | * https://developer.couchbase.com/documentation/server/current/security/security-x509certsintro.html 17 | */ 18 | public class ConnectingCertAuth { 19 | 20 | public static void main(String... args) { 21 | CouchbaseEnvironment environment = DefaultCouchbaseEnvironment.builder() 22 | .sslEnabled(true) 23 | .certAuthEnabled(true) 24 | .sslKeystoreFile("/path/to/keystore") 25 | .sslKeystorePassword("password") 26 | .sslTruststoreFile("/path/to/truststore") // you can also pack it all in just the keystore 27 | .sslTruststorePassword("password") 28 | .build(); 29 | 30 | Cluster cluster = CouchbaseCluster.create(environment, "127.0.0.1"); 31 | // IMPORTANT: do NOT call cluster.authenticate() since this is part of the cert auth 32 | Bucket bucket = cluster.openBucket("travel-sample"); 33 | 34 | // perform operations here... 35 | bucket.get("mydoc"); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/ConnectingSsl.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.couchbase.client.java.Bucket; 7 | import com.couchbase.client.java.Cluster; 8 | import com.couchbase.client.java.CouchbaseCluster; 9 | import com.couchbase.client.java.env.CouchbaseEnvironment; 10 | import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; 11 | import org.apache.log4j.Logger; 12 | 13 | public class ConnectingSsl { 14 | 15 | protected static final Logger LOGGER = Logger.getLogger("devguide"); 16 | 17 | protected final Cluster cluster; 18 | protected final Bucket bucket; 19 | protected final CouchbaseEnvironment env; 20 | 21 | //=== EDIT THESE TO ADAPT TO YOUR COUCHBASE INSTALLATION === 22 | public static final String bucketName = "default"; 23 | public static final String bucketPassword = ""; 24 | public static final List nodes = Arrays.asList("127.0.0.1"); 25 | 26 | //=== You need to correctly set up your JVM keystore first! === 27 | //see instructions in http://developer.couchbase.com/documentation/server/4.0/sdks/java-2.2/managing-connections.html#story-h2-5 28 | 29 | protected ConnectingSsl() { 30 | //configure the SDK to use SSL and point it to the keystore 31 | env = DefaultCouchbaseEnvironment.builder() 32 | .sslEnabled(true) 33 | .sslKeystoreFile("/path/tokeystore") 34 | .sslKeystorePassword("password") 35 | .build(); 36 | 37 | //connect to the cluster using the SSL configuration, by hitting one of the given nodes 38 | cluster = CouchbaseCluster.create(env, nodes); 39 | 40 | //get a Bucket reference from the cluster to the configured bucket 41 | bucket = cluster.openBucket(bucketName, bucketPassword); 42 | } 43 | 44 | private void disconnect() { 45 | //release shared resources and close all open buckets 46 | cluster.disconnect(); 47 | 48 | //also release the environment since we created it ourselves (notice this is an async operation so we block on it) 49 | env.shutdownAsync().toBlocking().first(); 50 | } 51 | 52 | public void execute() { 53 | //connection has been done in the constructor 54 | doWork(); 55 | disconnect(); 56 | } 57 | 58 | /** 59 | * Override this method to showcase specific examples. 60 | * Make them executable by adding a main method calling new ExampleClass().execute(); 61 | */ 62 | protected void doWork() { 63 | //this one just showcases connection methods, see constructor and shutdown() 64 | LOGGER.info("Connected to the cluster, opened bucket " + bucketName); 65 | } 66 | 67 | public static void main(String[] args) { 68 | new ConnectingSsl().execute(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/ConnectionBase.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.couchbase.client.java.Bucket; 7 | import com.couchbase.client.java.Cluster; 8 | import com.couchbase.client.java.CouchbaseCluster; 9 | import com.couchbase.client.java.env.CouchbaseEnvironment; 10 | import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; 11 | import org.apache.log4j.Logger; 12 | 13 | public class ConnectionBase { 14 | 15 | protected static final Logger LOGGER = Logger.getLogger("devguide"); 16 | 17 | protected final Cluster cluster; 18 | protected final Bucket bucket; 19 | 20 | //=== EDIT THESE TO ADAPT TO YOUR COUCHBASE INSTALLATION === 21 | public static final String bucketName = "default"; 22 | public static final String bucketPassword = ""; 23 | public static final List nodes = Arrays.asList("127.0.0.1"); 24 | public static CouchbaseEnvironment environment = DefaultCouchbaseEnvironment.create(); 25 | 26 | public ConnectionBase() { 27 | //connect to the cluster by hitting one of the given nodes 28 | cluster = CouchbaseCluster.create(environment, nodes); 29 | //get a Bucket reference from the cluster to the configured bucket 30 | bucket = cluster.openBucket(bucketName, bucketPassword); 31 | } 32 | 33 | private void disconnect() { 34 | //release shared resources and close all open buckets 35 | cluster.disconnect(); 36 | } 37 | 38 | public void execute() { 39 | //connection has been done in the constructor 40 | doWork(); 41 | disconnect(); 42 | } 43 | 44 | /** 45 | * Override this method to showcase specific examples. 46 | * Make them executable by adding a main method calling new ExampleClass().execute(); 47 | */ 48 | protected void doWork() { 49 | //this one just showcases connection methods, see constructor and shutdown() 50 | LOGGER.info("Connected to the cluster, opened bucket " + bucketName); 51 | } 52 | 53 | public static void main(String[] args) { 54 | new ConnectionBase().execute(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/Counter.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.JsonLongDocument; 4 | import com.couchbase.client.java.error.DocumentDoesNotExistException; 5 | 6 | /** 7 | * Example of Counters in Java for the Couchbase Developer Guide. 8 | */ 9 | public class Counter extends ConnectionBase { 10 | 11 | @Override 12 | protected void doWork() { 13 | String key = "javaDevguideExampleCounter"; 14 | // Remove document so we have predictable behavior in this example 15 | try { 16 | bucket.remove(key); 17 | } catch (DocumentDoesNotExistException e) { 18 | //do nothing, the document is already not here 19 | } 20 | 21 | try { 22 | bucket.counter(key, 20); 23 | } catch (DocumentDoesNotExistException e) { 24 | LOGGER.info("The counter method failed because the counter doesn't exist yet and no initial value was provided"); 25 | } 26 | 27 | JsonLongDocument rv = bucket.counter(key, 20, 100); 28 | LOGGER.info("Delta=20, Initial=100. Current value is: " + rv.content()); 29 | 30 | 31 | rv = bucket.counter(key, 1); 32 | LOGGER.info("Delta=1. Current value is: " + rv.content()); 33 | 34 | rv = bucket.counter(key, -50); 35 | LOGGER.info("Delta=-50. Current value is: " + rv.content()); 36 | } 37 | 38 | public static void main(String[] args) { 39 | new Counter().execute(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/Durability.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.TimeoutException; 5 | 6 | import com.couchbase.client.core.ReplicaNotAvailableException; 7 | import com.couchbase.client.core.ReplicaNotConfiguredException; 8 | import com.couchbase.client.java.PersistTo; 9 | import com.couchbase.client.java.ReplicateTo; 10 | import com.couchbase.client.java.document.JsonLongDocument; 11 | import com.couchbase.client.java.document.JsonStringDocument; 12 | import com.couchbase.client.java.error.DocumentDoesNotExistException; 13 | import com.couchbase.client.java.error.DurabilityException; 14 | 15 | /** 16 | * Example of Durability in Java for the Couchbase Developer Guide. 17 | */ 18 | public class Durability extends ConnectionBase { 19 | 20 | @Override 21 | protected void doWork() { 22 | String key = "javaDevguideExampleDurability"; 23 | JsonStringDocument doc = JsonStringDocument.create(key, "a String is valid JSON"); 24 | 25 | LOGGER.info("Storing with maximum factor"); 26 | // In the Java SDK you must specify a factor matching the number of replicas you have configured 27 | // if you want "maximum" persistence or replication 28 | // Here we expect 3 replicas configured so we can wait for persistence on 4 nodes total, replication on 3 replicas. 29 | try { 30 | bucket.upsert(doc, PersistTo.FOUR, ReplicateTo.THREE); 31 | } catch (DurabilityException e) { //if the durability cannot be met 32 | if (e.getCause() instanceof ReplicaNotConfiguredException) { 33 | //this exception is a fail fast if not enough replicas are configured on the bucket 34 | LOGGER.info("Couldn't persist to FOUR nor replicate to THREE, not enough replicas configured"); 35 | } else if (e.getCause() instanceof ReplicaNotAvailableException) { 36 | //this exception occurs if enough replica are configured on the bucket but currently not enough are online 37 | //eg. during a failover 38 | LOGGER.info("Couldn't persist/replicate on 1 replica, not enough replicas online"); 39 | } else { 40 | LOGGER.error("Durability Exception", e); 41 | } 42 | } 43 | 44 | // Store with persisting to master node 45 | LOGGER.info("Storing with waiting for persistence on MASTER"); 46 | bucket.upsert(doc, PersistTo.MASTER); 47 | 48 | LOGGER.info("Storing with waiting for persistence on any two nodes, replication on one replica node"); 49 | try { 50 | bucket.upsert(doc, PersistTo.TWO, ReplicateTo.ONE); 51 | } catch (DurabilityException e) { 52 | //if the durability cannot be met (eg. if the cluster detected that the replica wasn't available due to failover) 53 | LOGGER.error("Durability Exception", e); 54 | } catch (RuntimeException e) { 55 | if (e.getCause() instanceof TimeoutException) { 56 | //if one of the nodes isn't responsive, a TimeoutException rather than DurabilityException may occur 57 | LOGGER.warn("The replica didn't notify us in time"); 58 | } 59 | } 60 | } 61 | 62 | public static void main(String[] args) { 63 | new Durability().execute(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/Expiration.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.JsonDocument; 4 | import com.couchbase.client.java.document.json.JsonObject; 5 | import com.couchbase.client.java.error.DocumentAlreadyExistsException; 6 | 7 | /** 8 | * Example of Expiry/TTL in Java for the Couchbase Developer Guide. 9 | */ 10 | public class Expiration extends ConnectionBase { 11 | 12 | @Override 13 | protected void doWork() { 14 | String key = "javaDevguideExampleExpiration"; 15 | //create content 16 | JsonObject content = JsonObject.create().put("some", "value"); 17 | 18 | LOGGER.info("Storing with an expiration of 2 seconds"); 19 | bucket.upsert(JsonDocument.create(key, 2, content)); 20 | 21 | LOGGER.info("Getting item back immediately"); 22 | LOGGER.info(bucket.get(key).content()); 23 | 24 | LOGGER.info("Sleeping for 4 seconds..."); 25 | sleepSeconds(4); 26 | LOGGER.info("Getting key again..."); 27 | 28 | //get returns null if the key doesn't exist 29 | if (bucket.get(key) == null) { 30 | LOGGER.info("Get failed because item has expired"); 31 | } 32 | 33 | LOGGER.info("Storing item again (without expiry)"); 34 | bucket.upsert(JsonDocument.create(key, content)); 35 | 36 | LOGGER.info("Using get-and-touch to retrieve key and modify expiry"); 37 | JsonDocument rv = bucket.getAndTouch(key, 2); 38 | LOGGER.info("Value is:" + rv.content()); 39 | 40 | LOGGER.info("Sleeping for 4 seconds again"); 41 | sleepSeconds(4); 42 | LOGGER.info("Getting key again (should fail)"); 43 | if (bucket.get(key) == null) { 44 | LOGGER.info("Failed (not found)"); 45 | } 46 | 47 | LOGGER.info("Storing key again..."); 48 | bucket.upsert(JsonDocument.create(key, content)); 49 | LOGGER.info("Using touch (without get). Setting expiry for 1 second"); 50 | bucket.touch(key, 1); 51 | 52 | LOGGER.info("Sleeping for 4 seconds..."); 53 | sleepSeconds(4); 54 | LOGGER.info("Will try to get item again... (should fail)"); 55 | if (bucket.get(key) == null) { 56 | LOGGER.info("Get failed because key has expired"); 57 | } 58 | } 59 | 60 | private void sleepSeconds(int seconds) { 61 | try { 62 | Thread.sleep(seconds * 1000); 63 | } catch (InterruptedException e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | 68 | public static void main(String[] args) { 69 | new Expiration().execute(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/FieldEncryptionAES.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | import com.couchbase.client.encryption.AES128CryptoProvider; 6 | import com.couchbase.client.encryption.AES256CryptoProvider; 7 | import com.couchbase.client.encryption.CryptoManager; 8 | import com.couchbase.client.encryption.JceksKeyStoreProvider; 9 | import com.couchbase.client.java.document.EntityDocument; 10 | import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; 11 | import com.couchbase.client.java.repository.annotation.EncryptedField; 12 | import com.couchbase.client.java.repository.annotation.Id; 13 | 14 | public class FieldEncryptionAES extends ConnectionBase { 15 | 16 | static { 17 | try { 18 | JceksKeyStoreProvider kp = new JceksKeyStoreProvider("secret"); 19 | kp.publicKeyName("mypublickey"); 20 | kp.storeKey("mypublickey", "!mysecretkey#9^5usdk39d&dlf)03sL".getBytes(Charset.forName("UTF-8"))); 21 | kp.signingKeyName("HMACsecret"); 22 | kp.storeKey("HMACsecret", "myauthpassword".getBytes(Charset.forName("UTF-8"))); 23 | AES256CryptoProvider aes256CryptoProvider = new AES256CryptoProvider(kp); 24 | CryptoManager cryptoManager = new CryptoManager(); 25 | cryptoManager.registerProvider("MyAESProvider", aes256CryptoProvider); 26 | environment = DefaultCouchbaseEnvironment.builder().cryptoManager(cryptoManager).build(); 27 | } catch (Exception ex) { 28 | ex.printStackTrace(); 29 | System.exit(1); 30 | } 31 | } 32 | 33 | @Override 34 | protected void doWork() { 35 | Person person = new Person(); 36 | person.id = "johnd"; 37 | person.password = "secret"; 38 | person.firstName = "John"; 39 | person.lastName = "Doe"; 40 | person.userName = "jdoe"; 41 | person.age = 20; 42 | 43 | EntityDocument document = EntityDocument.create(person); 44 | bucket.repository().upsert(document); 45 | EntityDocument stored = bucket.repository().get(person.id, Person.class); 46 | System.out.println("Password: " + stored.content().password); 47 | } 48 | 49 | public static class Person { 50 | 51 | @Id 52 | public String id; 53 | 54 | @EncryptedField(provider = "MyAESProvider") 55 | public String password; 56 | 57 | //The rest will be transported and stored unencrypted 58 | public String firstName; 59 | public String lastName; 60 | public String userName; 61 | public int age; 62 | } 63 | 64 | public static void main(String[] args) { 65 | new FieldEncryptionAES().execute(); 66 | } 67 | } -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/QueryCriteria.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import static com.couchbase.client.java.query.dsl.Expression.i; 4 | import static com.couchbase.client.java.query.dsl.Expression.s; 5 | import static com.couchbase.client.java.query.dsl.Expression.x; 6 | 7 | import com.couchbase.client.java.query.N1qlQuery; 8 | import com.couchbase.client.java.query.N1qlQueryResult; 9 | import com.couchbase.client.java.query.N1qlQueryRow; 10 | import com.couchbase.client.java.query.Select; 11 | import com.couchbase.client.java.query.Statement; 12 | 13 | /** 14 | * Example of Querying with N1QL in Java for the Couchbase Developer Guide. 15 | */ 16 | public class QueryCriteria extends ConnectionBase { 17 | 18 | @Override 19 | protected void doWork() { 20 | String statement = "SELECT airportname, city, country FROM `travel-sample` WHERE type=\"airport\" AND city=\"Reno\""; 21 | N1qlQuery query = N1qlQuery.simple(statement); 22 | 23 | LOGGER.info("Results from a simple statement:"); 24 | LOGGER.info(statement); 25 | N1qlQueryResult result = bucket.query(query); 26 | for (N1qlQueryRow row : result) { 27 | LOGGER.info("\t" + row.value()); 28 | } 29 | 30 | //when there is a server-side error, the server will feed errors in the result.error() collection 31 | //you can find that out by checking finalSuccess() == false 32 | //alternatively, syntax errors are also detected early and for them you can check parseSuccess() 33 | N1qlQueryResult errorResult = bucket.query(N1qlQuery.simple("SELECTE * FROM `travel-sample` LIMIT 3")); 34 | LOGGER.info("With bad syntax, parseSuccess = " + errorResult.parseSuccess() 35 | + ", finalSuccess = " + errorResult.finalSuccess() + ", errors: " + errorResult.errors()); 36 | 37 | //there is also a fluent API to construct N1QL statements, generally import static the Select.select method 38 | Statement fluentStatement = 39 | Select.select("airportname", "city", "country") 40 | //Expression.i escapes an expression with backticks 41 | .from(i("travel-sample")) 42 | //Expression.x creates an expression token that can be manipulated 43 | //Expression.s creates a string literal 44 | .where(x("type").eq(s("airport")) 45 | .and(x("city").eq(s("Reno"))) 46 | ); 47 | 48 | LOGGER.info("Results from a fluent-API statement:"); 49 | LOGGER.info(fluentStatement.toString()); 50 | N1qlQueryResult fluentResult = bucket.query(N1qlQuery.simple(fluentStatement)); 51 | for (N1qlQueryRow row : fluentResult) { 52 | LOGGER.info("\t" + row.value()); 53 | } 54 | 55 | //the result also contains metrics sent by the server 56 | LOGGER.info("Metrics: " + fluentResult.info()); 57 | 58 | } 59 | 60 | public static void main(String[] args) { 61 | new QueryCriteria().execute(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/QueryPlaceholders.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.json.JsonArray; 4 | import com.couchbase.client.java.query.N1qlQuery; 5 | import com.couchbase.client.java.query.N1qlQueryResult; 6 | import com.couchbase.client.java.query.N1qlQueryRow; 7 | import com.couchbase.client.java.query.ParameterizedN1qlQuery; 8 | 9 | /** 10 | * Example of Querying using placeholders with N1QL in Java for the Couchbase Developer Guide. 11 | */ 12 | public class QueryPlaceholders extends ConnectionBase { 13 | 14 | private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$1 AND type=\"airport\""; 15 | 16 | private N1qlQueryResult queryCity(String city) { 17 | //the placeholder values can be provided as a JSON array (if using $1 syntax) 18 | // or map-like JSON object (if using $name syntax) 19 | JsonArray placeholderValues = JsonArray.from(city); 20 | 21 | ParameterizedN1qlQuery query = N1qlQuery.parameterized(PLACEHOLDER_STATEMENT, placeholderValues); 22 | return bucket.query(query); 23 | } 24 | 25 | @Override 26 | protected void doWork() { 27 | LOGGER.info("Airports in Reno: "); 28 | for (N1qlQueryRow row : queryCity("Reno")) { 29 | LOGGER.info("\t" + row); 30 | } 31 | 32 | LOGGER.info("Airports in Dallas: "); 33 | for (N1qlQueryRow row : queryCity("Dallas")) { 34 | LOGGER.info("\t" + row); 35 | } 36 | 37 | LOGGER.info("Airports in Los Angeles: "); 38 | for (N1qlQueryRow row : queryCity("Los Angeles")) { 39 | LOGGER.info("\t" + row); 40 | } 41 | } 42 | 43 | public static void main(String[] args) { 44 | new QueryPlaceholders().execute(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/QueryPrepared.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.json.JsonObject; 4 | import com.couchbase.client.java.query.N1qlParams; 5 | import com.couchbase.client.java.query.N1qlQuery; 6 | import com.couchbase.client.java.query.N1qlQueryResult; 7 | import com.couchbase.client.java.query.N1qlQueryRow; 8 | import com.couchbase.client.java.query.ParameterizedN1qlQuery; 9 | 10 | /** 11 | * Example of Querying with N1QL and its Prepared Statement feature, in Java for the Couchbase Developer Guide. 12 | */ 13 | public class QueryPrepared extends ConnectionBase { 14 | 15 | private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$city AND type=\"airport\""; 16 | 17 | private N1qlQueryResult queryCity(String city, boolean optimize) { 18 | //the placeholder values can be provided as a JSON array (if using $1 syntax) 19 | // or map-like JSON object (if using $name syntax) 20 | JsonObject placeholderValues = JsonObject.create().put("city", city); 21 | 22 | //the N1qlParams.adhoc(false) is used to trigger server-side optimizations, namely preparing 23 | // the query and reusing the prepared data on subsequent calls 24 | N1qlParams params = N1qlParams.build().adhoc(!optimize); 25 | 26 | ParameterizedN1qlQuery query = N1qlQuery.parameterized(PLACEHOLDER_STATEMENT, placeholderValues, params); 27 | return bucket.query(query); 28 | } 29 | 30 | @Override 31 | protected void doWork() { 32 | LOGGER.info("Airports in Reno: "); 33 | N1qlQueryResult result = queryCity("Reno", true); 34 | for (N1qlQueryRow row : result) { 35 | LOGGER.info("\t" + row); 36 | } 37 | LOGGER.info("1st query took " + result.info().executionTime()); 38 | 39 | result = queryCity("Dallas", true); 40 | LOGGER.info("\nAirports in Dallas: "); 41 | for (N1qlQueryRow row : result) { 42 | LOGGER.info("\t" + row); 43 | } 44 | LOGGER.info("2nd query took " + result.info().executionTime()); 45 | 46 | LOGGER.info("\nAirports in Los Angeles: "); 47 | result = queryCity("Los Angeles", true); 48 | for (N1qlQueryRow row : result) { 49 | LOGGER.info("\t" + row); 50 | } 51 | LOGGER.info("3rd query took " + result.info().executionTime()); 52 | 53 | LOGGER.info("\nCompare with unprepared (adhoc) query for Los Angeles: "); 54 | LOGGER.info(queryCity("Los Angeles", false).info().executionTime()); 55 | 56 | //invalidateQueryCache empties the local cache of optimized statements, returning the previous count 57 | //of such statements. 58 | LOGGER.info("\nThe SDK prepared " + bucket.invalidateQueryCache() + " queries"); 59 | } 60 | 61 | public static void main(String[] args) { 62 | new QueryPrepared().execute(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/Retrieving.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.JsonDocument; 4 | import com.couchbase.client.java.document.json.JsonObject; 5 | 6 | /** 7 | * Example of Retrieving in Java for the Couchbase Developer Guide. 8 | */ 9 | public class Retrieving extends ConnectionBase { 10 | 11 | @Override 12 | protected void doWork() { 13 | String key = "javaDevguideExampleRetrieving"; 14 | LOGGER.info("Getting non-existent key. Should fail.."); 15 | JsonDocument nonExistentDocument = bucket.get("non-exist-document"); 16 | if (nonExistentDocument == null) { 17 | LOGGER.info("Got null for missing document, it doesn't exist!"); 18 | } 19 | 20 | LOGGER.info("Upserting..."); 21 | JsonDocument document = JsonDocument.create(key, JsonObject.create().put("foo", "bar")); 22 | bucket.upsert(document); 23 | LOGGER.info("Getting..."); 24 | LOGGER.info(bucket.get(key)); 25 | } 26 | 27 | public static void main(String[] args) { 28 | new Retrieving().execute(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/src/main/java/com/couchbase/devguide/Updating.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.devguide; 2 | 3 | import com.couchbase.client.java.document.JsonDocument; 4 | import com.couchbase.client.java.document.json.JsonObject; 5 | import com.couchbase.client.java.error.DocumentAlreadyExistsException; 6 | 7 | /** 8 | * Example of Updating/Storing in Java for the Couchbase Developer Guide. 9 | */ 10 | public class Updating extends ConnectionBase { 11 | 12 | @Override 13 | protected void doWork() { 14 | String key = "javaDevguideExampleUpdating"; 15 | //create content 16 | JsonObject content = JsonObject.create().put("topic", "storing").put("mutation", true); 17 | 18 | //create document 19 | JsonDocument document = JsonDocument.create(key, content); 20 | LOGGER.info("Prepared document " + document); 21 | 22 | //store the document (upsert will always work whether or not a value is already associated to the key) 23 | document = bucket.upsert(document); 24 | LOGGER.info("Document after upsert: " + document); //notice the CAS changed (the returned document is updated with correct CAS) 25 | 26 | //prepare an update 27 | document.content().put("update", "something"); 28 | //see that inserting it fails because it already exists 29 | try { 30 | bucket.insert(document); 31 | } catch (DocumentAlreadyExistsException e) { 32 | LOGGER.warn("Couldn't insert it, DocumentAlreadyExists... Let's try to replace it"); 33 | } 34 | 35 | //on the other hand, updating works (it would have failed if the key was not in database) 36 | document = bucket.replace(document); 37 | LOGGER.info("Replaced the old document by the new one: " + document); //notice the document's CAS changed again... 38 | 39 | LOGGER.info("Got the following from database: " + bucket.get(key)); //... which is consistent with a get (RYOW) 40 | } 41 | 42 | public static void main(String[] args) { 43 | new Updating().execute(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /java/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=INFO, stdout 3 | log4j.logger.devguide=INFO, shortstdout 4 | log4j.additivity.devguide=false 5 | 6 | # Direct log messages to stdout 7 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 8 | log4j.appender.stdout.Target=System.out 9 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 10 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p %c{1}:%L - %m%n 11 | 12 | # Short version of the above 13 | log4j.appender.shortstdout=org.apache.log4j.ConsoleAppender 14 | log4j.appender.shortstdout.Target=System.out 15 | log4j.appender.shortstdout.layout=org.apache.log4j.PatternLayout 16 | log4j.appender.shortstdout.layout.ConversionPattern=%d{HH:mm:ss} %m%n -------------------------------------------------------------------------------- /nodejs/cloud.js: -------------------------------------------------------------------------------- 1 | var couchbase = require('couchbase'); 2 | 3 | var N1qlQuery = couchbase.N1qlQuery; 4 | 5 | // Update this to your cluster 6 | const endpoint = 'cb.e207a530-a469-492f-89d4-a5392e265c10.dp.cloud.couchbase.com' 7 | const username = 'user' 8 | const password = 'password' 9 | const bucketName = 'couchbasecloudbucket' 10 | // User Input ends here. 11 | 12 | // Initialize the Connection 13 | var cluster = new couchbase.Cluster('couchbases://' +endpoint+'?ssl=no_verify', {username: username, password: password}); 14 | var bucket = cluster.openBucket(bucketName); 15 | 16 | // Create a N1QL Primary Index (but ignore if it exists) 17 | bucket.manager().createPrimaryIndex({ignoreExists: true}, function() { 18 | // Create and store a document 19 | bucket.upsert('user:king_arthur', { 20 | 'name': 'Arthur', 'email': 'kingarthur@couchbase.com', 'interests': ['Holy Grail', 'African Swallows'] 21 | }, 22 | function (err, result) { 23 | // Load the Document and print it 24 | // Prints Content and Metadata of the stored Document 25 | bucket.get('user:king_arthur', function (err, result) { 26 | console.log('Got result: %j', result.value); 27 | 28 | // Perform a N1QL Query 29 | bucket.query( 30 | N1qlQuery.fromString('SELECT name FROM '+ bucketName + ' WHERE $1 in interests LIMIT 1'), 31 | ['African Swallows'], 32 | function (err, rows) { 33 | // Print the result 34 | console.log('Got rows: %j', rows); 35 | }); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /nodejs/connecting-cert-auth.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster( 6 | 'couchbases://127.0.0.1/' + 7 | '?truststorepath=../etc/x509-cert/SSLCA/clientdir/trust.pem' + 8 | '&certpath=../etc/x509-cert/SSLCA/clientdir/client.pem' + 9 | '&keypath=../etc/x509-cert/SSLCA/clientdir/client.key'); 10 | 11 | // Authenticate with the cluster 12 | cluster.authenticate(new couchbase.CertAuthenticator()); 13 | 14 | // Setup Bucket object to be reused within the code 15 | var bucket = cluster.openBucket('travel-sample'); 16 | 17 | console.log('Example Successful - Exiting'); 18 | process.exit(0); 19 | -------------------------------------------------------------------------------- /nodejs/connecting-ssl.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | /* 5 | * Put Self-Signed Cluster Certificate from the cluster 6 | * to /tmp/couchbase-ssl-certificate.pem: 7 | * 8 | * $ curl http://localhost:8091/pools/default/certificate > /tmp/couchbase-ssl-certificate.pem 9 | */ 10 | 11 | // Setup Cluster Connection Object 12 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1?certpath=/tmp/couchbase-ssl-certificate.pem'); 13 | 14 | // Authenticate with the cluster 15 | cluster.authenticate('Administrator', 'password'); 16 | 17 | // Setup Bucket object to be reused within the code 18 | var bucket = cluster.openBucket('travel-sample'); 19 | 20 | console.log('Example Successful - Exiting'); 21 | process.exit(0); 22 | -------------------------------------------------------------------------------- /nodejs/connecting.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Authenticate with the cluster 8 | cluster.authenticate('Administrator', 'password'); 9 | 10 | // Setup Bucket object to be reused within the code 11 | var bucket = cluster.openBucket('travel-sample'); 12 | 13 | console.log('Example Successful - Exiting'); 14 | process.exit(0); 15 | -------------------------------------------------------------------------------- /nodejs/counter.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup a new key, initialize as 10, add 2, and retreive it 11 | var key = "nodeDevguideExampleCounter"; 12 | bucket.counter(key, 2, {initial: 10}, function(err, res) { 13 | if (err) throw err; 14 | 15 | console.log('Initialized Counter:', res.value); 16 | 17 | bucket.counter(key, 2, {initial: 10}, function(err, res) { 18 | if (err) throw err; 19 | 20 | console.log('Incremented Counter:', res.value); 21 | 22 | console.log('Example Successful - Exiting'); 23 | process.exit(0); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /nodejs/expiration.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup a new Document, with 2 second expiry and store in in the Bucket 11 | // - note - API uses unix epoch time in seconds 12 | var key = "nodeDevguideExampleExpiry"; 13 | bucket.insert(key, {test:"Some Test Value"}, {expiry: 2}, function(err, res) { 14 | if (err) throw err; 15 | 16 | if(res){ 17 | 18 | console.log('Initialized Document With Expiry'); 19 | 20 | // Get Document before Expiry 21 | bucket.get(key, function(err, resPre) { 22 | if (err) throw err; 23 | 24 | if(resPre) { 25 | 26 | console.log('Retreived Document Before Expiry:', resPre.value); 27 | 28 | // Wait 4 seconds, and try to retrieve Document again 29 | setTimeout(function () { 30 | bucket.get(key, function (err, resExp) { 31 | if (err){ 32 | 33 | // Document expired, and should throw an error of not found 34 | console.log('Document Expired:', err.message) 35 | console.log('Example Successful - Exiting'); 36 | process.exit(0); 37 | } 38 | }); 39 | }, 4000); 40 | } 41 | }); 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /nodejs/field-encryption.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var couchbase = require('couchbase'); 4 | var cbfieldcrypt = require('couchbase-encryption'); 5 | 6 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 7 | cluster.authenticate('Administrator', 'password'); 8 | var bucket = cluster.openBucket('default'); 9 | 10 | 11 | var publicKey = '!mysecretkey#9^5usdk39d&dlf)03sL'; 12 | var signingKey = 'myauthpassword'; 13 | 14 | var keyStore = new cbfieldcrypt.InsecureKeyStore(); 15 | keyStore.addKey('publickey', publicKey); 16 | keyStore.addKey('mysecret', signingKey); 17 | 18 | var personCryptFields = { 19 | password: new cbfieldcrypt.AesCryptoProvider(keyStore, 'publickey', 'mysecret') 20 | }; 21 | 22 | // The Password field will be encrypted - see the definition of the 23 | // People object encrypted fields above. 24 | var teddy = { 25 | age: 33, 26 | firstName: 'Ted', 27 | lastName: 'DeBloss', 28 | password: 'ssloBeD12345' 29 | }; 30 | 31 | //Password field will be encrypted in transport and at rest in the database 32 | var encryptedTeddy = cbfieldcrypt.encryptFields(teddy, personCryptFields); 33 | bucket.upsert('person::1', encryptedTeddy, function(err, res) { 34 | if (err) { 35 | throw err; 36 | } 37 | 38 | bucket.get('person::1', function(err, res) { 39 | if (err) { 40 | throw err; 41 | } 42 | 43 | // Inspecting the data before performing decryption allows us to see 44 | // how the document is stored in Couchbase. 45 | var encryptedData = res.value; 46 | console.log('Encrypted:', encryptedData); 47 | 48 | // Performing decryption on the document will reverse the encryption 49 | // process applied above and allow you to view the password in plain-text. 50 | var decryptedData = 51 | cbfieldcrypt.decryptFields(encryptedData, personCryptFields); 52 | console.log('Decrypted:', decryptedData); 53 | 54 | process.exit(0); 55 | }); 56 | }); 57 | 58 | -------------------------------------------------------------------------------- /nodejs/query-create-index.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup Query 11 | var N1qlQuery = couchbase.N1qlQuery; 12 | 13 | // Make a N1QL specific Query to Create a Primary Index or Secondary Index 14 | var query = N1qlQuery.fromString("CREATE PRIMARY INDEX ON `travel-sample`"); 15 | 16 | // Issue Query to Create the Index 17 | bucket.query(query,function(err,result){ 18 | if (err) throw err; 19 | 20 | // Print Results 21 | console.log("Result:",result); 22 | 23 | console.log('Example Successful - Exiting'); 24 | process.exit(0); 25 | }); 26 | -------------------------------------------------------------------------------- /nodejs/query-criteria.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup Query 11 | var N1qlQuery = couchbase.N1qlQuery; 12 | 13 | // Make a N1QL specific Query 14 | var query = N1qlQuery.fromString("SELECT airportname, city, country FROM `travel-sample` " + 15 | "WHERE type='airport' AND city='Reno' "); 16 | 17 | // Issue Query 18 | bucket.query(query,function(err,result){ 19 | if (err) throw err; 20 | 21 | // Print Results 22 | console.log("Result:",result); 23 | 24 | console.log('Example Successful - Exiting'); 25 | process.exit(0); 26 | }); 27 | -------------------------------------------------------------------------------- /nodejs/query-placeholders.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup Query 11 | var N1qlQuery = couchbase.N1qlQuery; 12 | 13 | // Make a N1QL specific Query 14 | var query = N1qlQuery.fromString("SELECT airportname, city, country FROM `travel-sample` " + 15 | "WHERE type=$1 AND city=$2"); 16 | 17 | // Issue Query with parameters passed in array 18 | bucket.query(query,["airport","Reno"],function(err,result){ 19 | if (err) throw err; 20 | 21 | // Print Results 22 | console.log("Result:",result); 23 | 24 | console.log('Example Successful - Exiting'); 25 | process.exit(0); 26 | }); 27 | -------------------------------------------------------------------------------- /nodejs/query-prepared.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup Query 11 | var N1qlQuery = couchbase.N1qlQuery; 12 | 13 | // Make a N1QL specific Query, telling Couchbase this will be a prepared statement 14 | var query = N1qlQuery.fromString("SELECT airportname, city, country FROM `travel-sample` " + 15 | "WHERE type=$1 AND city=$2").adhoc(false); 16 | 17 | // Timing Variables to compare execution times 18 | var t1,t2,t3,t4; 19 | 20 | // QUERY 1 - PREPARE AND EXECUTE 21 | // Issue Query with parameters passed in array, running as a prepared statement 22 | bucket.query(query,["airport","London"],function(err,result,meta){ 23 | if (err) throw err; 24 | 25 | // Print Results 26 | console.log("Result:",result); 27 | console.log("Time Query1:",meta.metrics.elapsedTime); 28 | t1=meta.metrics.elapsedTime; 29 | 30 | // QUERY 2 - EXECUTE THE IDENTICAL QUERY. 31 | // Try a the same query, again. It should have a shorter elapsed time. 32 | bucket.query(query,["airport","London"],function(err,result,meta){ 33 | if(err) throw err; 34 | 35 | // Print Results 36 | console.log("Result:",result); 37 | console.log("Time Query 2:",meta.metrics.elapsedTime); 38 | t2=meta.metrics.elapsedTime; 39 | 40 | // QUERY 3 - EXECUTE THE PLAN 41 | // Try the same query, with different parameters. It should also be fast. 42 | bucket.query(query,["airport","Seattle"],function(err,result,meta) { 43 | if (err) throw err; 44 | 45 | // Print Results 46 | console.log("Result:", result); 47 | console.log("Time Query 3:", meta.metrics.elapsedTime); 48 | t3=meta.metrics.elapsedTime; 49 | 50 | // QUERY 4 - EXECUTE THE ORIGINAL. 51 | // Try the original query, again. 52 | bucket.query(query,["airport","London"],function(err,result,meta) { 53 | if (err) throw err; 54 | 55 | // Print Results 56 | console.log("Result:", result); 57 | console.log("Time Query 2:", meta.metrics.elapsedTime); 58 | t4 = meta.metrics.elapsedTime; 59 | 60 | console.log("====="); 61 | console.log("Query 1 - prepare, execute :", t1); 62 | console.log("Query 2 - execute, same params:", t2); 63 | console.log("Query 3 - execute, new params :", t3); 64 | console.log("Query 4 - execute, og params :", t4); 65 | console.log("====="); 66 | console.log('Example Successful - Exiting'); 67 | process.exit(0); 68 | }); 69 | }); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /nodejs/retrieving.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup a Document and store in the bucket. 11 | var key = "nodeDevguideExampleRetrieve"; 12 | bucket.insert(key, {test:"Some Test Value"},function(err, res) { 13 | if (err) throw err; 14 | 15 | console.log('Initialized Document, stored to bucket'); 16 | 17 | // Get Document 18 | bucket.get(key, function (err, resRead) { 19 | if (err) throw err; 20 | 21 | // Print Document Value 22 | console.log("Retrieved Document:", resRead.value); 23 | 24 | console.log('Example Successful - Exiting'); 25 | process.exit(0); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /nodejs/updating.js: -------------------------------------------------------------------------------- 1 | // Require Couchbase Module 2 | var couchbase = require('couchbase'); 3 | 4 | // Setup Cluster Connection Object 5 | var cluster = new couchbase.Cluster('couchbase://127.0.0.1'); 6 | 7 | // Setup Bucket object to be reused within the code 8 | var bucket = cluster.openBucket('travel-sample'); 9 | 10 | // Setup a new Document and store in the bucket 11 | var key = "nodeDevguideExampleReplace"; 12 | bucket.insert(key, {test:"Some Test Value"},function(err, res) { 13 | if (err) throw err; 14 | 15 | console.log('Initialized Document, stored to bucket'); 16 | 17 | // Get Document 18 | bucket.get(key, function (err, resRead) { 19 | if (err) throw err; 20 | 21 | // Print Document Value 22 | console.log("Retrieved Document:", resRead.value); 23 | 24 | // Add to value, and replace 25 | resRead.value.test2='Some More Test Values'; 26 | var updatedVal=JSON.stringify(resRead.value); 27 | bucket.replace(key,updatedVal,function(req,resUpdated){ 28 | if (err) throw err; 29 | 30 | // Get Replaced Document Value 31 | bucket.get(key, function (err, resReadUpdated) { 32 | if (err) throw err; 33 | 34 | // Print Document Value 35 | console.log("Retrieved Document:", resReadUpdated.value); 36 | 37 | console.log('Example Successful - Exiting'); 38 | process.exit(0); 39 | }); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /php/bulk-operations.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 4 | 5 | $results = $bucket->upsert(array( 6 | 'foo' => array('value' => array('email' => 'foo@foo.com')), 7 | 'bar' => array('value' => array('email' => 'bar@bar.com')), 8 | 'baz' => array('value' => array('email' => 'baz@baz.com')) 9 | )); 10 | print_r($results); 11 | 12 | // Get them back again 13 | $results = $bucket->get(array('foo', 'bar', 'baz')); 14 | foreach ($results as $docid => $metadoc) { 15 | // Each document itself has a 'propname' 16 | echo "Result for $docid\n"; 17 | var_dump($metadoc->value); 18 | echo "\n"; 19 | } -------------------------------------------------------------------------------- /php/cache-curl-request.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 19 | 20 | 21 | /* 22 | * Lets define a function which can wrap executing the curl request and 23 | * handling the cache in one. 24 | */ 25 | function cached_curl_request($path) { 26 | global $db; 27 | 28 | /* 29 | * Lets define a key to use for storing out cached request into. We 30 | * base this key directly on the path so that we can support caching 31 | * many different URIs. We also add a prefix for good measure. 32 | */ 33 | $cache_key = 'cache_' . $path; 34 | 35 | /* 36 | * First we make an attempt to retrieve the data from our cache key, 37 | * if the request fails, an exception will be thrown and we will perform 38 | * some additional logic rather than returning the value directly. 39 | */ 40 | try { 41 | return $db->get($cache_key); 42 | } catch (Exception $e) { 43 | } 44 | 45 | /* 46 | * Since our attempts to retrieve the data we want from our cache failed, 47 | * we will have to perform the request ourselves. The following blurb 48 | * simply executes an HTTP request and stores the result (in json decoded 49 | * format) into $result. 50 | */ 51 | $curl = curl_init(); 52 | curl_setopt_array($curl, array( 53 | CURLOPT_RETURNTRANSFER => 1, 54 | CURLOPT_USERAGENT => 'Couchbase-Example-App', 55 | CURLOPT_URL => $path 56 | )); 57 | $result = json_decode(curl_exec($curl)); 58 | curl_close($curl); 59 | 60 | /* 61 | * Now that we've managed to execute the request, we wil attempt to store 62 | * this data onto Couchbase Server for the next request to read rather than 63 | * performing another HTTP request. We perform an insert or update store 64 | * store the data into our cache key document, we ignore any failures that 65 | * occur since we already have performed the request and are just caching. 66 | */ 67 | try { 68 | $db->upsert('cache_' . $path, $result, array('expiry'=>5)); 69 | } catch (Exception $e) { 70 | // Ignore errors, since we are only caching data anyways. 71 | } 72 | 73 | /* 74 | * Return the result we retrieved earlier 75 | */ 76 | return $result; 77 | } 78 | 79 | /* 80 | * Lets set up a URI to test on. 81 | */ 82 | $testUri = 'https://api.github.com/users/couchbaselabs/events'; 83 | 84 | /* 85 | * Now we use our caching request function to perform the request and dumb 86 | * the results to the page or console. 87 | */ 88 | $pageval = cached_curl_request($testUri); 89 | var_dump($pageval); 90 | -------------------------------------------------------------------------------- /php/cas-replace.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 16 | 17 | /* 18 | * Now insert a document with id 'foo' 19 | */ 20 | $foo1 = $bucket->upsert('foo', array('val' => 1)); 21 | /* 22 | * The CAS value encoded as opaque string, i.e. you are free to pass it around, 23 | * but shouldn't try to interpret it or perform any operations (e.g. encoding 24 | * conversion or other string-related functions). 25 | */ 26 | assert('is_string($foo1->cas)'); 27 | 28 | try { 29 | /* 30 | * Now lets see what happens if we use incorrect CAS with replace operation. 31 | */ 32 | $bucket->replace('foo', array('val' => 2), array('cas' => 'fakecas')); 33 | } catch (CouchbaseException $ex) { 34 | /* 35 | * As expected it throws exception telling about CAS mismatch. 36 | */ 37 | assert('preg_match("/CAS value different than specified/", $ex->getMessage())'); 38 | } 39 | /* 40 | * But works, if we specify correct CAS (the actual value associated with it on server) 41 | */ 42 | $bucket->replace('foo', array('val' => 2), array('cas' => $foo1->cas)); 43 | 44 | /* 45 | * Each document modification also updates CAS, and the code below proves it. 46 | */ 47 | $foo2 = $bucket->get('foo'); 48 | assert('is_string($foo2->cas)'); 49 | assert('$foo1->cas != $foo2->cas'); -------------------------------------------------------------------------------- /php/cloud.php: -------------------------------------------------------------------------------- 1 | username($username)->password($password); 14 | $myCluster->authenticate($authenticator); 15 | $myBucket = $myCluster->openBucket($bucketName); 16 | 17 | // Create a N1QL Primary Index (but ignore if it exists) 18 | $myBucket->manager()->createN1qlPrimaryIndex("", true, false); 19 | 20 | // Store a Document 21 | $result = $myBucket->upsert("u:king_arthur", array( 22 | "name" => "Arthur", 23 | "email" => "kingarthur@couchbase.com", 24 | "interests" => array("Holy Grail", "African Swallows") 25 | )); 26 | 27 | # Load the Document and print it 28 | $result = $myBucket->get("u:king_arthur"); 29 | var_dump($result->value); 30 | 31 | # Perform a N1QL Query 32 | $query = CouchbaseN1qlQuery::fromString("SELECT * FROM `$bucketName` WHERE \$1 IN interests"); 33 | $query->positionalParams(array("African Swallows")); 34 | 35 | # Print each found Row 36 | $rows = $myBucket->query($query); 37 | echo "Results:\n"; 38 | var_dump($rows); -------------------------------------------------------------------------------- /php/connecting-cert-auth.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 11 | -------------------------------------------------------------------------------- /php/connecting-ssl.php: -------------------------------------------------------------------------------- 1 | /tmp/couchbase-ssl-certificate.pem 8 | * 9 | * In spite of libcouchbase linked with SSL itself, when using in PHP context, module php_openssl 10 | * have to be loaded before php_couchbase, or it might cause segfaults if other SSL-extensions also 11 | * loaded. For example, php_curl + php_couchbase without php_openssl loaded will trigger segfault 12 | * on php_curl unloading. 13 | */ 14 | $cluster = new \Couchbase\Cluster('couchbases://localhost?certpath=/tmp/couchbase-ssl-certificate.pem'); 15 | $cluster->authenticateAs('Administrator', 'password'); 16 | $bucket = $cluster->openBucket('default'); 17 | -------------------------------------------------------------------------------- /php/connecting.php: -------------------------------------------------------------------------------- 1 | authenticateAs('Administrator', 'password'); 5 | $bucket = $cluster->openBucket('default'); 6 | $protectedBucket = $cluster->openBucket('protected'); 7 | -------------------------------------------------------------------------------- /php/counter.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 4 | 5 | // Remove the document first so we can have predictable behavior 6 | try { 7 | $bucket->remove('docid'); 8 | } catch (CouchbaseException $ex) { 9 | } 10 | 11 | $result = $bucket->counter('docid', 20, array('initial' => 100)); 12 | echo 'Delta=20, Initial=100. Current value is: ' . $result->value . "\n"; 13 | 14 | $result = $bucket->counter('docid', 1); 15 | echo 'Delta=1. Current value is: ' . $result->value . "\n"; 16 | 17 | $result = $bucket->counter('docid', -50); 18 | echo 'Delta=-50. Current value is: ' . $result->value . "\n"; -------------------------------------------------------------------------------- /php/durability.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 9 | 10 | /* 11 | * In the PHP SDK you can specify "maximum" persistence and 12 | * replication by specifying -1 for either valie 13 | */ 14 | $bucket->upsert('docid', ['some' => 'value'], ['persist_to' => -1, 'replicate_to' => -1]); 15 | 16 | // Store with persisting to master node 17 | $bucket->upsert('docid', ['some' => 'value'], ['persist_to' => 1]); 18 | 19 | // Note, this will fail if there are no replicas online 20 | $bucket->upsert('docid', ['some' => 'value'], ['persist_to' => 1, 'replicate_to' => 1]); 21 | -------------------------------------------------------------------------------- /php/encryption/.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | -------------------------------------------------------------------------------- /php/encryption/README.md: -------------------------------------------------------------------------------- 1 | This is the demo of field-level encryption extension to Couchbase PHP SDK. 2 | 3 | Either download the contents of this directory, or `git clone` all of the devguide examples, then cd into the encryption directory and run the following: 4 | 5 | pecl install couchbase # make sure couchbase 2.4.6+ SDK installed 6 | composer install 7 | composer demo-symmetric 8 | composer demo-asymmetric 9 | 10 | The extension release page: 11 | https://packagist.org/packages/couchbase/couchbase-encryption 12 | -------------------------------------------------------------------------------- /php/encryption/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "couchbase/encryption-demo", 3 | "description": "Demonstration of field-level encryption extension to Couchbase SDK", 4 | "type": "project", 5 | "require": { 6 | "couchbase/couchbase-encryption": "^0.7.2" 7 | }, 8 | "license": "Apache-2.0", 9 | "authors": [ 10 | { 11 | "name": "Sergey Avseyev", 12 | "email": "sergey@couchbase.com" 13 | } 14 | ], 15 | "minimum-stability": "stable", 16 | "scripts": { 17 | "demo-symmetric": "@php ./demo-symmetric.php", 18 | "demo-asymmetric": "@php ./demo-asymmetric.php" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /php/encryption/demo-asymmetric.php: -------------------------------------------------------------------------------- 1 | authenticateAs('Administrator', 'password'); 28 | $bucket = $cluster->openBucket('default'); 29 | $bucket->registerCryptoProvider( 30 | 'RSA-2048-OAEP-SHA1', 31 | new Aes256HmacSha256Provider(new InsecureKeyProvider(), "MyPublicKeyName", "MyPrivateKeyName") 32 | ); 33 | 34 | 35 | // source document, which contains some sensitive data 36 | $document = [ 37 | 'message' => 'The old grey goose jumped over the wrickety gate.' 38 | ]; 39 | 40 | // lets encrypt everything stored in the 'message' property using key with ID 41 | // 'mypyblickey' and our crypto provider. 42 | $encrypted = $bucket->encryptFields( 43 | $document, 44 | [ 45 | [ 46 | 'name' => 'message', 47 | 'alg' => 'RSA-2048-OAEP-SHA1' 48 | ] 49 | ] 50 | ); 51 | 52 | // now we are ready to persist document with encrypted field using regular APIs 53 | $bucket->upsert('secret-1', $encrypted); 54 | 55 | // the database does not have our encryption keys, and cannot see the plain contents 56 | $document = $bucket->get('secret-1')->value; 57 | var_dump($document); 58 | // the output should be similar to following: 59 | // => object(stdClass)#9 (1) { 60 | // ["__crypt_message"]=> 61 | // object(stdClass)#8 (5) { 62 | // ["alg"]=> 63 | // string(18) "RSA-2048-OAEP-SHA1" 64 | // ["ciphertext"]=> 65 | // string(88) "uY14lwNqKQSZCNPc23h8dXgLbkj6hrWG5wA+9swPJQmuqOXUUr4YI9IE6a5vplG8z7XUnrmrpeG2y/85hu2zDg==" 66 | // ["iv"]=> 67 | // string(24) "n+ijNQiRYaTyguGoh7plCQ==" 68 | // ["kid"]=> 69 | // string(15) "MyPublicKeyName" 70 | // ["sig"]=> 71 | // string(44) "PJGt++Yz74QcMclan0p97l1dkBlMuCidH2OlSpYrBeU=" 72 | // } 73 | // } 74 | 75 | $decrypted = $bucket->decryptFields( 76 | $document, 77 | [ 78 | [ 79 | 'name' => 'message', 80 | 'alg' => 'RSA-2048-OAEP-SHA1' 81 | ] 82 | ] 83 | ); 84 | var_dump($decrypted); 85 | // now we have our document readable 86 | // => array(1) { 87 | // ["message"]=> 88 | // string(49) "The old grey goose jumped over the wrickety gate." 89 | // } 90 | -------------------------------------------------------------------------------- /php/encryption/demo-symmetric.php: -------------------------------------------------------------------------------- 1 | authenticateAs('Administrator', 'password'); 27 | $bucket = $cluster->openBucket('default'); 28 | $bucket->registerCryptoProvider( 29 | 'AES-256-HMAC-SHA256', 30 | new Aes256HmacSha256Provider(new InsecureKeyProvider(), "mypublickey", "HMAC_KEY_ID") 31 | ); 32 | 33 | 34 | // source document, which contains some sensitive data 35 | $document = [ 36 | 'message' => 'The old grey goose jumped over the wrickety gate.' 37 | ]; 38 | 39 | // lets encrypt everything stored in the 'message' property using key with ID 40 | // 'mypyblickey' and our crypto provider. 41 | $encrypted = $bucket->encryptFields( 42 | $document, 43 | [ 44 | [ 45 | 'name' => 'message', 46 | 'alg' => 'AES-256-HMAC-SHA256' 47 | ] 48 | ] 49 | ); 50 | 51 | // now we are ready to persist document with encrypted field using regular APIs 52 | $bucket->upsert('secret-1', $encrypted); 53 | 54 | // the database does not have our encryption keys, and cannot see the plain contents 55 | $document = $bucket->get('secret-1')->value; 56 | var_dump($document); 57 | // the output should be similar to following: 58 | // => object(stdClass)#9 (1) { 59 | // ["__crypt_message"]=> 60 | // object(stdClass)#8 (5) { 61 | // ["alg"]=> 62 | // string(19) "AES-256-HMAC-SHA256" 63 | // ["ciphertext"]=> 64 | // string(88) "aK1RxvZkP4YWyMapQTpiRKvAG6V1MsFWUJwNfY7TXh3d5DdFO3jwmQu3rFMN6p98Y4ziM+pQNkrB/Cc7GP9/yw==" 65 | // ["iv"]=> 66 | // string(24) "1tzdgObtNJmNOrgSImzdKg==" 67 | // ["kid"]=> 68 | // string(11) "mypublickey" 69 | // ["sig"]=> 70 | // string(44) "qStQ7U28A05nz/ZP5SKDSMQuMofy1K9QHX8nYALLwOo=" 71 | // } 72 | // } 73 | 74 | $decrypted = $bucket->decryptFields( 75 | $document, 76 | [ 77 | [ 78 | 'name' => 'message', 79 | 'alg' => 'AES-256-HMAC-SHA256' 80 | ] 81 | ] 82 | 83 | ); 84 | var_dump($decrypted); 85 | // now we have our document readable 86 | // => array(1) { 87 | // ["message"]=> 88 | // string(49) "The old grey goose jumped over the wrickety gate." 89 | // } 90 | -------------------------------------------------------------------------------- /php/expiration.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 5 | 6 | echo "Storing with an expiration of 2 seconds\n"; 7 | $bucket->upsert('docid', 'value', array('expiry' => 2)); 8 | 9 | echo "Getting item back immediately... " . $bucket->get('docid')->value . "\n"; 10 | 11 | echo "Sleeping for 4 seconds...\n"; 12 | sleep(4); 13 | 14 | echo "Getting item back again\n"; 15 | try { 16 | $bucket->get('docid'); 17 | } catch (\Couchbase\Exception $ex) { 18 | printf("Failed: %s\n", $ex->getMessage()); 19 | } 20 | 21 | echo "Storing item again (without expiry)\n"; 22 | $bucket->upsert('docid', 'value'); 23 | 24 | echo "Using getAndTouch to retrieve key and modify expiry"; 25 | $metadoc = $bucket->getAndTouch('docid', 2); 26 | printf("Current value is %s\n", $metadoc->value); 27 | 28 | echo "Sleeping for 4 seconds again\n"; 29 | sleep(4); 30 | 31 | echo "Getting key again (should fail)\n"; 32 | try { 33 | $bucket->get('docid'); 34 | } catch (\Couchbase\Exception $ex) { 35 | printf("Failed with %s\n", $ex->getMessage()); 36 | } 37 | 38 | echo "Storing key again\n"; 39 | $bucket->upsert('docid', 'someValue'); 40 | 41 | echo "Using touch (without get). Setting expiry for 1 second\n"; 42 | $bucket->touch('docid', 1); 43 | 44 | echo "Sleeping for 4 seconds\n"; 45 | sleep(4); 46 | 47 | echo "Will try to get item again...\n"; 48 | try { 49 | $bucket->get('docid'); 50 | } catch (\Couchbase\Exception $ex) { 51 | printf("Failed with %s\n", $ex->getMessage()); 52 | } -------------------------------------------------------------------------------- /php/query-consistency.php: -------------------------------------------------------------------------------- 1 | openBucket('default'); 5 | 6 | $RANDOM_NUMBER = rand(0, 10000000); 7 | $bucket->upsert('user:'.$RANDOM_NUMBER, array( 8 | "name" => array("Brass", "Doorknob"), 9 | "email" => "brass.doorknob@example.com", 10 | "random" => $RANDOM_NUMBER) 11 | ); 12 | 13 | $query = \Couchbase\N1qlQuery::fromString( 14 | 'SELECT name, email, random, META(default).id FROM default WHERE $1 IN name' 15 | ); 16 | $query->positionalParams(['Brass']); 17 | // If this line is removed, the latest 'random' field might not be present 18 | $query->consistency(\Couchbase\N1qlQuery::REQUEST_PLUS); 19 | 20 | printf("Expecting random: %d\n", $RANDOM_NUMBER); 21 | $result = $bucket->query($query); 22 | foreach ($result->rows as $row) { 23 | printf("Name: %s, Email: %s, Random: %d\n", implode(" ", $row->name), $row->email, $row->random); 24 | if ($row->random == $RANDOM_NUMBER) { 25 | echo "!!! Found or newly inserted document !!!\n"; 26 | } 27 | if (getenv("REMOVE_DOORKNOBS")) { 28 | echo "Removing " . $row->id . " (Requested via env)\n"; 29 | $bucket->remove($row->id); 30 | } 31 | } 32 | 33 | // More light-weight way to do this is to use AT_PLUS consistency 34 | // It will require mutation tokens enabled during connection. 35 | $cluster = new \Couchbase\Cluster('couchbase://192.168.1.194?fetch_mutation_tokens=true'); 36 | $bucket = $cluster->openBucket('default'); 37 | 38 | $RANDOM_NUMBER = rand(0, 10000000); 39 | $result = $bucket->upsert('user:'.$RANDOM_NUMBER, array( 40 | "name" => array("Brass", "Doorknob"), 41 | "email" => "brass.doorknob@example.com", 42 | "random" => $RANDOM_NUMBER) 43 | ); 44 | // construct mutation state from the list of mutation results 45 | $mutationState = \Couchbase\MutationState::from($result); 46 | 47 | $query = \Couchbase\N1qlQuery::fromString( 48 | 'SELECT name, email, random, META(default).id FROM default WHERE $1 IN name' 49 | ); 50 | $query->positionalParams(['Brass']); 51 | // If this line is removed, the latest 'random' field might not be present 52 | $query->consistentWith($mutationState); 53 | 54 | printf("Expecting random: %d\n", $RANDOM_NUMBER); 55 | $result = $bucket->query($query); 56 | foreach ($result->rows as $row) { 57 | printf("Name: %s, Email: %s, Random: %d\n", implode(" ", $row->name), $row->email, $row->random); 58 | if ($row->random == $RANDOM_NUMBER) { 59 | echo "!!! Found or newly inserted document !!!\n"; 60 | } 61 | if (getenv("REMOVE_DOORKNOBS")) { 62 | echo "Removing " . $row->id . " (Requested via env)\n"; 63 | $bucket->remove($row->id); 64 | } 65 | } -------------------------------------------------------------------------------- /php/query-criteria.php: -------------------------------------------------------------------------------- 1 | openBucket('travel-sample'); 4 | 5 | $result = $bucket->query(\Couchbase\N1qlQuery::fromString( 6 | 'SELECT airportname, city, country FROM `travel-sample` ' . 7 | 'WHERE type="airport" AND city="Reno"' 8 | )); 9 | var_dump($result->rows); -------------------------------------------------------------------------------- /php/query-placeholders.php: -------------------------------------------------------------------------------- 1 | options['args'] = array($city); 12 | // The following optimizes the query for repeated invocation. The query string 13 | // (i.e. the one in fromString) is converted to an optimized form at the 14 | // server and returned to the SDK. Internally the SDK will re-use this optimized form 15 | // for future queries if the adhoc flag is set to false 16 | $query->adhoc(false); 17 | return $bkt->query($query); 18 | } 19 | 20 | $cluster = new \Couchbase\Cluster('couchbase://localhost'); 21 | $bucket = $cluster->openBucket('travel-sample'); 22 | 23 | echo "Airports in Reno:\n"; 24 | var_dump(query_city($bucket, "Reno")); 25 | 26 | echo "Airports in Dallas:\n"; 27 | var_dump(query_city($bucket, "Dallas")); 28 | 29 | echo "Aiports in Los Angeles\n"; 30 | var_dump(query_city($bucket, "Los Angeles")); -------------------------------------------------------------------------------- /php/retrieving.php: -------------------------------------------------------------------------------- 1 | openBucket("default"); 4 | 5 | echo "Getting non-existent key. Should fail\n"; 6 | try { 7 | $bucket->get('non-exist-document'); 8 | } catch (\Couchbase\Exception $ex) { 9 | if ($ex->getCode() != COUCHBASE_KEY_ENOENT) { 10 | throw new Exception("GRRR"); 11 | } 12 | printf("Error: %s (0x%x)\n", $ex->getMessage(), $ex->getCode()); 13 | } 14 | 15 | echo "Upserting...\n"; 16 | $bucket->upsert("new_document", array("foo" => "bar")); 17 | echo "Getting\n"; 18 | $result = $bucket->get("new_document"); 19 | var_dump($result); 20 | echo "Foo is: " . $result->value->foo . "\n"; 21 | -------------------------------------------------------------------------------- /php/updating.php: -------------------------------------------------------------------------------- 1 | openBucket("default"); 5 | 6 | // This always works! 7 | echo "Upserting\n"; 8 | $bucket->upsert('docid', array('property' => 'value')); 9 | echo "Getting item back..."; 10 | echo "Value is: \n"; 11 | print_r($bucket->get('docid')->value); 12 | echo "\n....\n"; 13 | 14 | echo "Inserting..\n"; 15 | echo "Will try to insert the document...\n"; 16 | echo "Should fail because the item already exists..\n"; 17 | try { 18 | $bucket->insert('docid', array('property' => 'value')); 19 | throw new Exception("Shouldn't reach here!"); 20 | } catch (\Couchbase\Exception $ex) { 21 | printf("Got error: Code=0x%x, Message=%s\n", $ex->getCode(), $ex->getMessage()); 22 | } 23 | echo "...\n"; 24 | 25 | echo "Replacing the document. This should work because the item already exists"; 26 | $bucket->replace('docid', array("property" => "new_value")); 27 | echo "Getting document again. Should contain the new contents:\n"; 28 | print_r($bucket->get('docid')->value); 29 | echo "\n...\n"; 30 | 31 | echo "Removing document"; 32 | $bucket->remove('docid'); 33 | echo "Replacing document again. Should fail because document no longer exists\n"; 34 | 35 | try { 36 | $bucket->replace("docid", array("property" => "new_value")); 37 | } catch (\Couchbase\Exception $ex) { 38 | printf("Got error %s\n", $ex->getMessage()); 39 | } -------------------------------------------------------------------------------- /python/bulk-operations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | 6 | cb = Bucket('couchbase://10.0.0.31/default') 7 | 8 | # First insert the documents we care about 9 | cb.upsert_multi({ 10 | 'foo': {'foo': 'value'}, 11 | 'bar': {'bar': 'value'}, 12 | 'baz': {'baz': 'value'} 13 | }) 14 | 15 | # Get them back again 16 | rvs = cb.get_multi(['foo', 'bar', 'baz']) 17 | for key, info in rvs.items(): 18 | print('Value for {0}: {1}'.format(key, info.value)) 19 | 20 | # See other error handling examples showing how to handle errors 21 | # in multi operations 22 | -------------------------------------------------------------------------------- /python/cas.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from couchbase.bucket import Bucket 4 | from couchbase.bucket import LOCKMODE_WAIT 5 | from threading import Thread 6 | from couchbase.exceptions import KeyExistsError 7 | 8 | 9 | cb = Bucket('couchbase://10.0.0.31/default', lockmode=LOCKMODE_WAIT) 10 | 11 | cb.upsert('a_list', []) 12 | 13 | 14 | print('Will attempt concurrent document mutations without CAS') 15 | 16 | 17 | def add_item_to_list(client, new_item): 18 | l = client.get('a_list').value 19 | l.append(new_item) 20 | client.replace('a_list', l) 21 | 22 | threads = [Thread(target=add_item_to_list, args=(cb, "item_" + str(x))) 23 | for x in range(0, 10)] 24 | 25 | [t.start() for t in threads] 26 | [t.join() for t in threads] 27 | 28 | cur_list = cb.get('a_list').value 29 | print('Current list has {0} elements'.format(len(cur_list))) 30 | if len(cur_list) != 10: 31 | print('Concurrent modifications removed some of our items!', cur_list) 32 | 33 | 34 | # The same as above, but using CAS 35 | def add_item_to_list_safe(client, new_item): 36 | while True: 37 | rv = client.get('a_list') 38 | l = rv.value 39 | l.append(new_item) 40 | 41 | try: 42 | cb.replace('a_list', l, cas=rv.cas) 43 | return 44 | except KeyExistsError: 45 | print("Cas mismatch for item", new_item) 46 | continue 47 | 48 | # Reset the list again 49 | cb.upsert('a_list', []) 50 | 51 | print('Will attempt concurrent modifications using CAS') 52 | threads = [Thread(target=add_item_to_list_safe, args=(cb, "item_" + str(x))) 53 | for x in range(0, 10)] 54 | 55 | [t.start() for t in threads] 56 | [t.join() for t in threads] 57 | cur_list = cb.get('a_list').value 58 | print('Current list has {0} elements'.format(len(cur_list))) 59 | assert len(cur_list) == 10 60 | -------------------------------------------------------------------------------- /python/cloud.py: -------------------------------------------------------------------------------- 1 | from couchbase.cluster import Cluster 2 | from couchbase.cluster import PasswordAuthenticator 3 | from couchbase.n1ql import N1QLQuery 4 | 5 | ######## Update this to your cluster 6 | endpoint = 'cb.e207a530-a469-492f-89d4-a5392e265c10.dp.cloud.couchbase.com' 7 | username = 'user' 8 | password = 'password' 9 | bucket_name = 'couchbasecloudbucket' 10 | #### User Input ends here. 11 | 12 | # Initialize the Connection 13 | cluster = Cluster('couchbases://' + endpoint + '?ssl=no_verify') # Update the cluster endpoint 14 | authenticator = PasswordAuthenticator(username, password) 15 | cluster.authenticate(authenticator) 16 | cb = cluster.open_bucket(bucket_name) 17 | 18 | # Create a N1QL Primary Index (but ignore if it exists) 19 | cb.bucket_manager().n1ql_index_create_primary(ignore_exists=True) 20 | 21 | # Store a Document 22 | cb.upsert('u:king_arthur', {'name': 'Arthur', 'email': 'kingarthur@couchbase.com', 'interests': ['Holy Grail', 'African Swallows']}) 23 | 24 | # Load the Document and print it 25 | print(cb.get('u:king_arthur').value) 26 | 27 | # Perform a N1QL Query 28 | row_iter = cb.n1ql_query(N1QLQuery('SELECT name FROM %s WHERE $1 IN interests' % (bucket_name), 'African Swallows')) 29 | 30 | # Print each found Row 31 | for row in row_iter: print(row) 32 | -------------------------------------------------------------------------------- /python/connecting-ssl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.bucket import Bucket 4 | from couchbase.cluster import * 5 | import os.path 6 | 7 | hostname ="localhost" 8 | bucket_name = "default" 9 | 10 | # point to certificates, keys and trust stores 11 | # for the purposes of this code, 12 | # the script in etc/x509-cert will generate these 13 | 14 | clientdir = "etc/x509-cert/SSLCA/clientdir" 15 | options = dict(certpath=os.path.join(clientdir, "client.pem"), 16 | truststorepath=os.path.join(clientdir, "trust.pem"), 17 | keypath=os.path.join(clientdir, "client.key")) 18 | 19 | # open a Bucket directly 20 | 21 | # Note the `couchbases` in the scheme. This is required for SSL connections! 22 | cb = Bucket('couchbases://{hostname}/default?certpath={certpath}&truststorepath={truststorepath}&keypath={keypath}'.format(hostname=hostname,**options)) 23 | print(cb.server_nodes) 24 | 25 | # create a Cluster object 26 | 27 | cb_cluster = Cluster("http://{}/".format(hostname)) 28 | 29 | # create an SSL-based Authenticator 30 | authenticator = CertAuthenticator(cluster_username="admin", 31 | cluster_password="password", **options) 32 | # apply this to the cluster 33 | cb_cluster.authenticate(authenticator) 34 | 35 | # user this to open a bucket 36 | cb_2 = cb_cluster.open_bucket(bucket_name) 37 | 38 | # some example operations 39 | 40 | cb_2.upsert("fred", {"hello": "world"}) 41 | cb_2.remove("fred") 42 | -------------------------------------------------------------------------------- /python/connecting.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.bucket import Bucket 4 | 5 | cb = Bucket('couchbase://10.0.0.31/default') 6 | print cb.server_nodes -------------------------------------------------------------------------------- /python/counter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | 6 | cb = Bucket('couchbase://10.0.0.31/default') 7 | 8 | # Remove document so we have predictable behavior in this example 9 | # the 'quiet' argument instructs the client not to raise an exception if the 10 | # document doesn't exist, but fail silently (the status can still be retrieved 11 | # from the returned result object) 12 | cb.remove('docid', quiet=True) 13 | 14 | # Without the 'initial' parameter, this command would fail if the item doesn't exist 15 | rv = cb.counter('docid', delta=20, initial=100) 16 | print('Delta=20, Initial=100. Current value is:', rv.value) 17 | 18 | rv = cb.counter('docid', delta=1) 19 | print('Delta=1. Current value is:', rv.value) 20 | 21 | rv = cb.counter('docid', delta=-50) 22 | print('Delta=-50. Current value is:', rv.value) -------------------------------------------------------------------------------- /python/create-remove-bucket.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.admin import Admin 4 | from couchbase.bucket import Bucket 5 | 6 | adm = Admin('Administrator', '123456', host='localhost', port=8091) 7 | adm.bucket_create('new-bucket', 8 | bucket_type='couchbase', 9 | bucket_password='s3cr3t') 10 | 11 | # Wait for bucket to become ready 12 | adm.wait_ready('new-bucket', timeout=30) 13 | 14 | bucket = Bucket('couchbase://localhost/new-bucket', password='s3cr3t') 15 | bucket.upsert('foo', 'bar') 16 | 17 | adm.bucket_remove('new-bucket') 18 | -------------------------------------------------------------------------------- /python/durability.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.bucket import Bucket 4 | 5 | cb = Bucket('couchbase://10.0.0.31/default') 6 | 7 | # In the Python SDK you can specify "maximum" persistence and 8 | # replication by specifying -1 for either valie 9 | cb.upsert('docid', {'some': 'value'}, persist_to=-1, replicate_to=-1) 10 | 11 | # Store with persisting to master node 12 | cb.upsert('docid', {'some': 'value'}, persist_to=1) 13 | 14 | # Note, this will fail if there are no replicas online 15 | cb.upsert('docid', {'some': 'value'}, persist_to=1, replicate_to=1) -------------------------------------------------------------------------------- /python/encryption/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/couchbaselabs/devguide-examples/c9373a004375a62500cdcde2c56801dbbf794af4/python/encryption/__init__.py -------------------------------------------------------------------------------- /python/encryption/field-encryption.py: -------------------------------------------------------------------------------- 1 | from cbencryption import AES256CryptoProvider 2 | from couchbase.bucket import Bucket 3 | from couchbase.crypto import InMemoryKeyStore 4 | # create insecure key store and register both public and private keys 5 | keystore = InMemoryKeyStore() 6 | keystore.set_key('mypublickey', b'!mysecretkey#9^5usdk39d&dlf)03sL') 7 | keystore.set_key('myprivatekey', b'myauthpassword') 8 | 9 | # create and register provider 10 | provider = AES256CryptoProvider.AES256CryptoProvider(keystore, 'mypublickey', 'myprivatekey') 11 | bucket = Bucket("couchbase://10.143.180.101:8091/default",password='password') 12 | bucket.register_crypto_provider('AES-256-HMAC-SHA256', provider) 13 | 14 | # encrypt document, the alg name must match the provider name and the kid must match a key in the keystore 15 | prefix = '__crypt_' 16 | document = {'message': 'The old grey goose jumped over the wrickety gate.'} 17 | fieldspec = [{'alg': 'AES-256-HMAC-SHA256', 'name': 'message'}] 18 | encrypted_document = bucket.encrypt_fields(document, 19 | fieldspec, 20 | prefix) 21 | expected = { 22 | "__crypt_message": {"alg": "AES-256-HMAC-SHA256", 23 | "kid": "mypublickey", 24 | "ciphertext": "sR6AFEIGWS5Fy9QObNOhbCgfg3vXH4NHVRK1qkhKLQqjkByg2n69lot89qFEJuBsVNTXR77PZR6RjN4h4M9evg==" 25 | } 26 | } 27 | 28 | # retain only signature/iv-independent fields for comparison 29 | 30 | 31 | def filter_encrypted(encrypted_dict): 32 | return {k:v for k,v in encrypted_dict.items() if k in {"alg","kid","ciphertext"}} 33 | 34 | subset_expected = filter_encrypted(expected) 35 | subset_actual = filter_encrypted(encrypted_document) 36 | assert subset_expected == subset_actual 37 | # decrypt document using registered provider 38 | decrypted_document = bucket.decrypt_fields(encrypted_document, fieldspec, prefix) 39 | assert decrypted_document==document -------------------------------------------------------------------------------- /python/expiration.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from time import sleep 3 | 4 | from couchbase.bucket import Bucket 5 | from couchbase.exceptions import NotFoundError 6 | 7 | cb = Bucket('couchbase://10.0.0.31/default') 8 | 9 | print('Storing with an expiration of 2 seconds') 10 | cb.upsert('docid', {'some': 'value'}, ttl=2) 11 | 12 | print('Getting item back immediately') 13 | print(cb.get('docid').value) 14 | 15 | print('Sleeping for 4 seconds...') 16 | sleep(4) 17 | print('Getting key again...') 18 | try: 19 | cb.get('docid') 20 | except NotFoundError: 21 | print('Get failed because item has expired') 22 | 23 | print('Storing item again (without expiry)') 24 | cb.upsert('docid', {'some': 'value'}) 25 | 26 | print('Using get-and-touch to retrieve key and modify expiry') 27 | rv = cb.get('docid', ttl=2) 28 | print('Value is:', rv.value) 29 | 30 | print('Sleeping for 4 seconds again') 31 | sleep(4) 32 | print('Getting key again (should fail)') 33 | try: 34 | cb.get('docid') 35 | except NotFoundError: 36 | print('Failed (not found)') 37 | 38 | print('Storing key again...') 39 | cb.upsert('docid', {'some': 'value'}) 40 | print('Using touch (without get). Setting expiry for 1 second') 41 | cb.touch('docid', ttl=1) 42 | 43 | print('Sleeping for 4 seconds...') 44 | sleep(4) 45 | print('Will try to get item again...') 46 | try: 47 | cb.get('docid') 48 | except NotFoundError: 49 | print('Get failed because key has expired') -------------------------------------------------------------------------------- /python/flush.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.bucket import Bucket 4 | 5 | cb = Bucket('couchbase://localhost/default') 6 | cb.flush() -------------------------------------------------------------------------------- /python/fts-basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | from pprint import pprint 4 | 5 | from couchbase.bucket import Bucket 6 | import couchbase.fulltext as FT 7 | 8 | cb = Bucket() 9 | results = cb.search( 10 | 'travel-search', 11 | FT.MatchQuery('part', fuzziness=0, field='content'), 12 | limit=3, 13 | facets={'countries': FT.TermFacet('country', limit=3)}) 14 | 15 | for row in results: 16 | pprint(row) 17 | 18 | print('Facet results:') -------------------------------------------------------------------------------- /python/n1ql-create-primary-index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from couchbase.bucket import Bucket 4 | 5 | cb = Bucket('couchbase://localhost/default') 6 | manager = cb.bucket_manager() 7 | manager.n1ql_index_create_primary(ignore_exists=True) -------------------------------------------------------------------------------- /python/n1ql-update-delete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from couchbase.bucket import Bucket 3 | from couchbase.n1ql import N1QLQuery 4 | 5 | cb = Bucket('couchbase://localhost/default') 6 | 7 | # Create a set of 'product' documents 8 | docs = { 9 | 'bundt_cake_pan1': { 10 | 'type': 'product', 11 | 'name': 'Bundt Cake Pan', 12 | 'price': 7.35, 13 | 'categories': ['kitchen', 'home'] 14 | }, 15 | 'led_4d_900in_tv1': { 16 | 'type': 'product', 17 | 'name': '4D 900" LED TV', 18 | 'price': 1250000.99, 19 | 'categories': ['technology', 'electronics'] 20 | }, 21 | 'light_bulb_40w_led': { 22 | 'type': 'product', 23 | 'name': '40-Watt LED Bulb', 24 | 'price': 4.40, 25 | 'categories': ['electronics', 'home'] 26 | }, 27 | 'red_puff_parka3': { 28 | 'type': 'product', 29 | 'name': 'Parka (red)', 30 | 'price': 54.99, 31 | 'categories': ['clothing'] 32 | }, 33 | 'utilikilt1_speaker': { 34 | 'type': 'product', 35 | 'name': 'Utilikilt with Bluetooth Speaker in Rear', 36 | 'price': 124.95, 37 | 'categories': ['clothing', 'electronics', 'technology'] 38 | } 39 | } 40 | 41 | # Delete any prior products so we start with a clean dataset 42 | meta = cb.n1ql_query( 43 | N1QLQuery('DELETE from default WHERE type=$1', 'product') 44 | ).execute().meta 45 | print 'Deleted {0} items!'.format(meta['metrics'].get('mutationCount', 0)) 46 | 47 | # Everything's 25% off! 48 | cb.upsert_multi(docs) 49 | query = N1QLQuery( 50 | 'UPDATE default ' 51 | 'SET sale_price=ROUND(price-(price * 0.25), 2) ' 52 | 'WHERE type=$1' 53 | 'RETURNING name, price, sale_price', 54 | 'product' 55 | ) 56 | for row in cb.n1ql_query(query): 57 | print '{0} WAS: {1:2}. NOW ONLY {2:2}'.format( 58 | row['name'], row['price'], row['sale_price']) 59 | 60 | # Show how we can update a single document by its ID 61 | query = N1QLQuery( 62 | 'UPDATE default USE KEYS $keys SET description=$desc', 63 | keys=['utilikilt1_speaker'], 64 | desc='Use this handy utilikilt as a fashion accessory or in the garage, and lets ' 65 | ) 66 | cb.n1ql_query(query).execute() 67 | # Show the new value 68 | print cb.get('utilikilt1_speaker').value['description'] -------------------------------------------------------------------------------- /python/query-atplus.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import time 3 | 4 | from couchbase.bucket import Bucket 5 | from couchbase.n1ql import N1QLQuery, MutationState 6 | 7 | TIMESTAMP = str(time.time()) 8 | 9 | cb = Bucket('couchbase://localhost/default?fetch_mutation_tokens=true') 10 | rv = cb.upsert('ndoc', {'timestamp': TIMESTAMP}) 11 | 12 | ms = MutationState() 13 | ms.add_results(rv) 14 | 15 | query = N1QLQuery('SELECT * from default WHERE timestamp=$1', TIMESTAMP) 16 | query.consistent_with(ms) 17 | print query.encoded 18 | 19 | for row in cb.n1ql_query(query): 20 | print row 21 | -------------------------------------------------------------------------------- /python/query-consistency.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | import random 4 | import os 5 | 6 | from couchbase.bucket import Bucket 7 | from couchbase.n1ql import N1QLQuery, CONSISTENCY_REQUEST 8 | 9 | # Ensure there is a primary index on the default bucket! 10 | RANDOM_NUMBER = random.randint(0, 10000000) 11 | 12 | cb = Bucket('couchbase://10.0.0.31/default') 13 | cb.upsert('user:{}'.format(RANDOM_NUMBER), { 14 | 'name': ['Brass', 'Doorknob'], 15 | 'email': ['brass.doorknob@juno.com'], 16 | 'random': RANDOM_NUMBER 17 | }) 18 | 19 | query = N1QLQuery( 20 | 'SELECT name, email, random, META(default).id FROM default WHERE $1 IN name', 'Brass') 21 | # If this line is removed, the latest 'random' field might not be present 22 | query.consistency = CONSISTENCY_REQUEST 23 | 24 | print('Expecting random:', RANDOM_NUMBER) 25 | 26 | for row in cb.n1ql_query(query): 27 | print('Name: {0}, Email: {1}, Random: {2}'.format(row['name'], row['email'], row['random'])) 28 | if row['random'] == RANDOM_NUMBER: 29 | print('!!! Found our newly inserted document !!!') 30 | if os.environ.get('REMOVE_DOORKNOBS'): 31 | cb.remove(row['id']) 32 | -------------------------------------------------------------------------------- /python/query-criteria.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from pprint import pprint 3 | 4 | from couchbase.bucket import Bucket 5 | from couchbase.n1ql import N1QLQuery 6 | 7 | cb = Bucket('couchbase://10.0.0.31/travel-sample') 8 | 9 | query = N1QLQuery('SELECT airportname, city, country FROM `travel-sample` ' 10 | 'WHERE type="airport" AND city="Reno"') 11 | for row in cb.n1ql_query(query): 12 | pprint(row) -------------------------------------------------------------------------------- /python/query-placeholders.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | from pprint import pprint 4 | 5 | from couchbase.bucket import Bucket 6 | from couchbase.n1ql import N1QLQuery 7 | 8 | cb = Bucket('couchbase://10.0.0.31/travel-sample') 9 | 10 | 11 | def query_city(bkt, city): 12 | query = N1QLQuery('SELECT airportname FROM `travel-sample` ' 13 | 'WHERE city=$1 AND type="airport"', city) 14 | 15 | # Uncomment the following line to make the query optimized for 16 | # repeated invocations. 17 | # The query string is compiled, and the the compiled form is 18 | # stored in the client (as a dictionary value to the query string 19 | # itself). 20 | # 21 | # q.adhoc = False 22 | return bkt.n1ql_query(query) 23 | 24 | 25 | print('Airports in Reno:') 26 | for row in query_city(cb, 'Reno'): 27 | pprint(row) 28 | 29 | print('Airports in Dallas') 30 | for row in query_city(cb, 'Dallas'): 31 | pprint(row) 32 | 33 | print('Airports in Los Angeles') 34 | for row in query_city(cb, 'Los Angeles'): 35 | pprint(row) 36 | -------------------------------------------------------------------------------- /python/retrieving.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | from couchbase.exceptions import NotFoundError 6 | 7 | cb = Bucket('couchbase://10.0.0.31/default') 8 | 9 | print('Getting non-existent key. Should fail..') 10 | try: 11 | cb.get('non-exist-document') 12 | except NotFoundError: 13 | print('Got exception for missing document!') 14 | print('...') 15 | 16 | print('Upserting...') 17 | cb.upsert('new_document', {'foo': 'bar'}) 18 | print('Getting...') 19 | print(cb.get('new_document').value) 20 | -------------------------------------------------------------------------------- /python/subdoc-retrieving.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | import couchbase.exceptions as E 6 | import couchbase.subdocument as SD 7 | 8 | cb = Bucket('couchbase://localhost/default') 9 | 10 | cb.upsert('docid', { 11 | 'name': 'Mark', 12 | 'email': 'm@n.com', 13 | 'array': [1, 2, 3, 4] 14 | }) 15 | 16 | # Do it the simple way: 17 | rv = cb.retrieve_in('docid', 'name', 'array[1]') 18 | print('Name is: {0}, array[1] is: {1}'.format(rv[0], rv[1])) 19 | 20 | # If all results are successful: 21 | name, array_2ndelem = rv 22 | print('Name is: {0}, Array[1] is: {1}'.format(name, array_2ndelem)) 23 | 24 | # Perform mixed-mode operations 25 | rv = cb.lookup_in('docid', 26 | SD.get('name'), SD.get('array[1]'), SD.exists('non-exist')) 27 | print('Name is', rv[0]) 28 | print('Array[1] is', rv[1]) 29 | print('non-exist exists?', rv.exists(2)) 30 | 31 | # See what happens when we try to reference a failed path: 32 | try: 33 | rv[2] 34 | except E.SubdocPathNotFoundError: 35 | print('Using subscript access raises exception for missing item') 36 | 37 | 38 | # If we try to get a non-existent document, it will fail as normal 39 | try: 40 | cb.retrieve_in('non-exist', 'pth1', 'pth2', 'pth3') 41 | except E.NotFoundError: 42 | print('Document itself not found!') -------------------------------------------------------------------------------- /python/subdoc-updating.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | import couchbase.exceptions as E 6 | import couchbase.subdocument as SD 7 | 8 | cb = Bucket('couchbase://localhost/default') 9 | 10 | cb.upsert('docid', { 11 | 'name': 'Mark', 12 | 'email': 'm@n.com', 13 | 'array': [1, 2, 3, 4] 14 | }) 15 | 16 | cb.mutate_in('docid', 17 | # Add 42 as a new element to 'array' 18 | SD.array_append('array', '42'), 19 | # Increment the numeric value of the first element by 99 20 | SD.counter('array[0]', 99), 21 | # Add a new 'description' field 22 | SD.upsert('description', 'just a dev')) 23 | 24 | print('Document is now:', cb.get('docid').value) 25 | 26 | try: 27 | cb.mutate_in('docid', SD.upsert('deep.nested.path', 'some-value')) 28 | except E.SubdocPathNotFoundError as e: 29 | print('Caught exception', e) 30 | 31 | # Use `create` 32 | cb.mutate_in('docid', SD.upsert( 33 | 'deep.nested.path', 'some-value', create_parents=True)) 34 | print('Getting value back:', cb.retrieve_in('docid', 'deep.nested.path')[0]) -------------------------------------------------------------------------------- /python/updating.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | from couchbase.bucket import Bucket 5 | import couchbase.exceptions as E 6 | 7 | cb = Bucket('couchbase://10.0.0.31/default') 8 | 9 | # This always works! 10 | print('Upserting') 11 | cb.upsert('docid', {'property': 'value'}) 12 | print('Getting item back. Value is:', 13 | cb.get('docid').value) 14 | print('...') 15 | 16 | print('Will try to insert the document. Should fail because the item already exists..') 17 | try: 18 | cb.insert('docid', {'property': 'value'}) 19 | except E.KeyExistsError: 20 | print('Insert failed because item already exists!') 21 | print('...') 22 | 23 | print('Replacing the document. This should work because the item already exists') 24 | cb.replace('docid', {'property': 'new_value'}) 25 | print('Getting document again. Should contain the new contents:', 26 | cb.get('docid').value) 27 | print('...') 28 | 29 | print('Removing document.') 30 | # Remove the item, then try to replace it! 31 | cb.remove('docid') 32 | print('Replacing document again. Should fail because document no longer exists') 33 | try: 34 | cb.replace('docid', {'property': 'another value'}) 35 | except E.NotFoundError: 36 | print('Get failed since item does not exist') 37 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/couchbaselabs/devguide-examples/c9373a004375a62500cdcde2c56801dbbf794af4/spring/spring-boot-demo/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring/spring-boot-demo/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.couchbase.demos 12 | spring-boot-demo 13 | 0.0.1-SNAPSHOT 14 | spring-boot-demo 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-webflux 35 | 36 | 37 | 38 | io.reactivex 39 | rxjava-reactive-streams 40 | 1.2.1 41 | 42 | 43 | 44 | com.couchbase.client 45 | java-client 46 | 2.7.9 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/main/java/com/couchbase/demos/springbootdemo/AirlinesController.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springbootdemo; 2 | 3 | import com.couchbase.client.java.Bucket; 4 | import org.reactivestreams.Publisher; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | import rx.RxReactiveStreams; 12 | 13 | import java.util.Map; 14 | 15 | @RestController 16 | @RequestMapping("/airlines") 17 | public class AirlinesController { 18 | 19 | private final Bucket bucket; 20 | 21 | @Autowired 22 | public AirlinesController(Bucket bucket) { 23 | this.bucket = bucket; 24 | } 25 | 26 | @GetMapping(value = "/{id}") 27 | public Publisher>> findById(final @PathVariable("id") String id) { 28 | return RxReactiveStreams.toPublisher( 29 | bucket.async() 30 | .get(id) 31 | .map(doc -> ResponseEntity.ok(doc.content().toMap())) 32 | .singleOrDefault(ResponseEntity.notFound().build()) 33 | ); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/main/java/com/couchbase/demos/springbootdemo/AirportsController.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springbootdemo; 2 | 3 | import com.couchbase.client.java.Bucket; 4 | import com.couchbase.client.java.document.JsonDocument; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.Map; 13 | import java.util.Optional; 14 | 15 | @RestController 16 | @RequestMapping("/airports") 17 | public class AirportsController { 18 | 19 | private final Bucket bucket; 20 | 21 | @Autowired 22 | public AirportsController(Bucket bucket) { 23 | this.bucket = bucket; 24 | } 25 | 26 | @GetMapping(value = "/{id}") 27 | public ResponseEntity> findById(final @PathVariable("id") String id) { 28 | return ResponseEntity.of( 29 | Optional.ofNullable(bucket.get(id)).map(doc -> doc.content().toMap()) 30 | ); 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/main/java/com/couchbase/demos/springbootdemo/DatabaseConfig.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springbootdemo; 2 | 3 | import com.couchbase.client.java.Bucket; 4 | import com.couchbase.client.java.Cluster; 5 | import com.couchbase.client.java.CouchbaseCluster; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class DatabaseConfig { 11 | 12 | @Bean 13 | public Bucket bucket() { 14 | Cluster cluster = CouchbaseCluster.create("127.0.0.1"); 15 | cluster.authenticate("Administrator", "password"); 16 | return cluster.openBucket("travel-sample"); 17 | } 18 | 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/main/java/com/couchbase/demos/springbootdemo/SpringBootDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springbootdemo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringBootDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spring/spring-boot-demo/src/test/java/com/couchbase/demos/springbootdemo/SpringBootDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springbootdemo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootDemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring/spring-data-demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /spring/spring-data-demo/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/couchbaselabs/devguide-examples/c9373a004375a62500cdcde2c56801dbbf794af4/spring/spring-data-demo/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring/spring-data-demo/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /spring/spring-data-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.8.RELEASE 9 | 10 | 11 | com.couchbase.demos 12 | spring-data-demo 13 | 0.0.1-SNAPSHOT 14 | spring-data-demo 15 | Demo project for Spring Data 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-couchbase 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-maven-plugin 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/java/com/couchbase/demos/springdatademo/Airport.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | public class Airport { 4 | 5 | private String airportname; 6 | 7 | public String getAirportname() { 8 | return airportname; 9 | } 10 | 11 | public void setAirportname(String airportname) { 12 | this.airportname = airportname; 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/java/com/couchbase/demos/springdatademo/AirportsController.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping("/airports") 12 | public class AirportsController { 13 | 14 | private final AirportsRepository repository; 15 | 16 | @Autowired 17 | public AirportsController(AirportsRepository repository) { 18 | this.repository = repository; 19 | } 20 | 21 | @GetMapping(value = "/{id}") 22 | public ResponseEntity findById(final @PathVariable("id") String id) { 23 | return ResponseEntity.of(repository.findById(id)); 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/java/com/couchbase/demos/springdatademo/AirportsRepository.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | import org.springframework.data.couchbase.repository.CouchbaseRepository; 4 | 5 | public interface AirportsRepository extends CouchbaseRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/java/com/couchbase/demos/springdatademo/DatabaseConfig.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | @Configuration 10 | public class DatabaseConfig extends AbstractCouchbaseConfiguration { 11 | 12 | @Override 13 | protected List getBootstrapHosts() { 14 | return Collections.singletonList("127.0.0.1"); 15 | } 16 | 17 | @Override 18 | protected String getBucketName() { 19 | return "travel-sample"; 20 | } 21 | 22 | @Override 23 | protected String getUsername() { 24 | return "Administrator"; 25 | } 26 | 27 | @Override 28 | protected String getBucketPassword() { 29 | return "password"; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/java/com/couchbase/demos/springdatademo/SpringDataDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringDataDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringDataDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spring/spring-data-demo/src/test/java/com/couchbase/demos/springdatademo/SpringDataDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.couchbase.demos.springdatademo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringDataDemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------