1 #define LCB_NO_DEPR_CXX_CTORS
2 #undef NDEBUG
3 
4 #include <libcouchbase/couchbase.h>
5 #include <libcouchbase/api3.h>
6 #include <assert.h>
7 #include <string.h>
8 #include <cstdlib>
9 #include <string>
10 #include <vector>
11 
generic_callback(lcb_t,int type,const lcb_RESPBASE * rb)12 static void generic_callback(lcb_t, int type, const lcb_RESPBASE *rb)
13 {
14     printf("Got callback for %s\n", lcb_strcbtype(type));
15 
16     if (rb->rc != LCB_SUCCESS && rb->rc != LCB_SUBDOC_MULTI_FAILURE) {
17         printf("Failure: 0x%x\n", rb->rc);
18         abort();
19     }
20 
21     if (type == LCB_CALLBACK_GET) {
22         const lcb_RESPGET *rg = (const lcb_RESPGET *)rb;
23         printf("Result is: %.*s\n", (int)rg->nvalue, rg->value);
24     } else if (type == LCB_CALLBACK_SDLOOKUP || type == LCB_CALLBACK_SDMUTATE) {
25         lcb_SDENTRY ent;
26         size_t iter = 0;
27         size_t oix = 0;
28         const lcb_RESPSUBDOC *resp = reinterpret_cast<const lcb_RESPSUBDOC*>(rb);
29         while (lcb_sdresult_next(resp, &ent, &iter)) {
30             size_t index = oix++;
31             if (type == LCB_CALLBACK_SDMUTATE) {
32                 index = ent.index;
33             }
34             printf("[%lu]: 0x%x. %.*s\n",
35                 index, ent.status, (int)ent.nvalue, ent.value);
36         }
37     }
38 }
39 
40 // cluster_run mode
41 #define DEFAULT_CONNSTR "couchbase://localhost"
42 
main(int argc,char ** argv)43 int main(int argc, char **argv) {
44     lcb_create_st crst = { 0 };
45     crst.version = 3;
46     if (argc > 1) {
47         crst.v.v3.connstr = argv[1];
48     } else {
49         crst.v.v3.connstr = DEFAULT_CONNSTR;
50     }
51     if (argc > 2) {
52         crst.v.v3.username = argv[2];
53     } else {
54         crst.v.v3.username = "Administrator";
55     }
56     if (argc > 3) {
57         crst.v.v3.passwd = argv[3];
58     } else {
59         crst.v.v3.passwd = "password";
60     }
61 
62     lcb_t instance;
63     lcb_error_t rc = lcb_create(&instance, &crst);
64     assert(rc == LCB_SUCCESS);
65 
66     rc = lcb_connect(instance);
67     assert(rc == LCB_SUCCESS);
68     lcb_wait(instance);
69     rc = lcb_get_bootstrap_status(instance);
70     assert(rc == LCB_SUCCESS);
71 
72     // Install generic callback
73     lcb_install_callback3(instance, LCB_CALLBACK_DEFAULT, generic_callback);
74 
75     // Store an item
76     lcb_CMDSTORE scmd = { 0 };
77     scmd.operation = LCB_SET;
78     LCB_CMD_SET_KEY(&scmd, "key", 3);
79     const char *initval = "{\"hello\":\"world\"}";
80     LCB_CMD_SET_VALUE(&scmd, initval, strlen(initval));
81     rc = lcb_store3(instance, NULL, &scmd);
82     assert(rc == LCB_SUCCESS);
83 
84     lcb_CMDSUBDOC mcmd = { 0 };
85     LCB_CMD_SET_KEY(&mcmd, "key", 3);
86 
87     std::vector<lcb_SDSPEC> specs;
88     std::string bufs[10];
89 
90     // Add some mutations
91     for (int ii = 0; ii < 5; ii++) {
92         std::string& path = bufs[ii * 2];
93         std::string& val = bufs[(ii * 2) + 1];
94         char pbuf[24], vbuf[24];
95 
96         sprintf(pbuf, "pth%d", ii);
97         sprintf(vbuf, "\"Value_%d\"", ii);
98         path = pbuf;
99         val = vbuf;
100 
101         lcb_SDSPEC spec = { 0 };
102         LCB_SDSPEC_SET_PATH(&spec, path.c_str(), path.size());
103         LCB_CMD_SET_VALUE(&spec, val.c_str(), val.size());
104         spec.sdcmd = LCB_SDCMD_DICT_UPSERT;
105         specs.push_back(spec);
106     }
107 
108     mcmd.specs = specs.data();
109     mcmd.nspecs = specs.size();
110     rc = lcb_subdoc3(instance, NULL, &mcmd);
111     assert(rc == LCB_SUCCESS);
112 
113     // Reset the specs
114     specs.clear();
115     for (int ii = 0; ii < 5; ii++) {
116         char pbuf[24];
117         std::string& path = bufs[ii];
118         sprintf(pbuf, "pth%d", ii);
119         path = pbuf;
120 
121         lcb_SDSPEC spec = { 0 };
122         LCB_SDSPEC_SET_PATH(&spec, path.c_str(), path.size());
123         spec.sdcmd = LCB_SDCMD_GET;
124         specs.push_back(spec);
125     }
126 
127     lcb_SDSPEC spec2 = { 0 };
128     LCB_SDSPEC_SET_PATH(&spec2, "dummy", 5);
129     spec2.sdcmd = LCB_SDCMD_GET;
130     specs.push_back(spec2);
131     mcmd.specs = specs.data();
132     mcmd.nspecs = specs.size();
133     rc = lcb_subdoc3(instance, NULL, &mcmd);
134     assert(rc == LCB_SUCCESS);
135 
136     lcb_CMDGET gcmd = { 0 };
137     LCB_CMD_SET_KEY(&gcmd, "key", 3);
138     rc = lcb_get3(instance, NULL, &gcmd);
139     assert(rc == LCB_SUCCESS);
140 
141     lcb_wait(instance);
142     lcb_destroy(instance);
143 }
144