1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2016 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 #include "config.h"
19 #include "nobucket.h"
20 
21 #include <cstdlib>
22 #include <stdexcept>
23 #include <string>
24 
25 /**
26  * The NoBucket is a bucket that just returns "ENGINE_NO_BUCKET" for "all"
27  * operations. The main purpose for having this bucket is to reduce the
28  * code complexity so we don't have to had checks all over the place to
29  * see if a client is connected to a bucket or not (we may just associate
30  * the connection to this bucket and it'll handle the appropriate
31  * command.
32  */
33 class NoBucket : public ENGINE_HANDLE_V1 {
34 public:
NoBucket()35     NoBucket() {
36         memset(this, 0, sizeof(*this));
37         ENGINE_HANDLE_V1::interface.interface = 1;
38         ENGINE_HANDLE_V1::initialize = initialize;
39         ENGINE_HANDLE_V1::destroy = destroy;
40         ENGINE_HANDLE_V1::allocate = item_allocate;
41         ENGINE_HANDLE_V1::allocate_ex = item_allocate_ex;
42         ENGINE_HANDLE_V1::remove = item_delete;
43         ENGINE_HANDLE_V1::release = item_release;
44         ENGINE_HANDLE_V1::get = get;
45         ENGINE_HANDLE_V1::get_meta = get_meta;
46         ENGINE_HANDLE_V1::get_if = get_if;
47         ENGINE_HANDLE_V1::get_and_touch = get_and_touch;
48         ENGINE_HANDLE_V1::get_locked = get_locked;
49         ENGINE_HANDLE_V1::unlock = unlock;
50         ENGINE_HANDLE_V1::get_stats = get_stats;
51         ENGINE_HANDLE_V1::reset_stats = reset_stats;
52         ENGINE_HANDLE_V1::store = store;
53         ENGINE_HANDLE_V1::store_if = store_if;
54         ENGINE_HANDLE_V1::flush = flush;
55         ENGINE_HANDLE_V1::unknown_command = unknown_command;
56         ENGINE_HANDLE_V1::item_set_cas = item_set_cas;
57         ENGINE_HANDLE_V1::item_set_datatype = item_set_datatype;
58         ENGINE_HANDLE_V1::get_item_info = get_item_info;
59         ENGINE_HANDLE_V1::set_item_info = set_item_info;
60         ENGINE_HANDLE_V1::dcp.step = dcp_step;
61         ENGINE_HANDLE_V1::dcp.open = dcp_open;
62         ENGINE_HANDLE_V1::dcp.add_stream = dcp_add_stream;
63         ENGINE_HANDLE_V1::dcp.close_stream = dcp_close_stream;
64         ENGINE_HANDLE_V1::dcp.get_failover_log = dcp_get_failover_log;
65         ENGINE_HANDLE_V1::dcp.stream_req = dcp_stream_req;
66         ENGINE_HANDLE_V1::dcp.stream_end = dcp_stream_end;
67         ENGINE_HANDLE_V1::dcp.snapshot_marker = dcp_snapshot_marker;
68         ENGINE_HANDLE_V1::dcp.mutation = dcp_mutation;
69         ENGINE_HANDLE_V1::dcp.deletion = dcp_deletion;
70         ENGINE_HANDLE_V1::dcp.deletion_v2 = dcp_deletion_v2;
71         ENGINE_HANDLE_V1::dcp.expiration = dcp_expiration;
72         ENGINE_HANDLE_V1::dcp.flush = dcp_flush;
73         ENGINE_HANDLE_V1::dcp.set_vbucket_state = dcp_set_vbucket_state;
74         ENGINE_HANDLE_V1::dcp.system_event = dcp_system_event;
75         ENGINE_HANDLE_V1::collections.set_manifest = collections_set_manifest;
76         ENGINE_HANDLE_V1::collections.get_manifest = collections_get_manifest;
77         ENGINE_HANDLE_V1::isXattrEnabled = isXattrEnabled;
78         ENGINE_HANDLE_V1::getMaxItemSize = getMaxItemSize;
79     };
80 
81 private:
82     /**
83      * Convert the ENGINE_HANDLE to the underlying class type
84      *
85      * @param handle the handle as provided by the frontend
86      * @return the actual no bucket object
87      */
get_handle(ENGINE_HANDLE * handle)88     static NoBucket* get_handle(ENGINE_HANDLE* handle) {
89         return reinterpret_cast<NoBucket*>(handle);
90     }
91 
initialize(gsl::not_null<ENGINE_HANDLE * >,const char *)92     static ENGINE_ERROR_CODE initialize(gsl::not_null<ENGINE_HANDLE*>,
93                                         const char*) {
94         return ENGINE_SUCCESS;
95     }
96 
destroy(gsl::not_null<ENGINE_HANDLE * > handle,const bool)97     static void destroy(gsl::not_null<ENGINE_HANDLE*> handle, const bool) {
98         delete get_handle(handle);
99     }
100 
item_allocate(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,const DocKey &,const size_t,const int,const rel_time_t,uint8_t,uint16_t)101     static cb::EngineErrorItemPair item_allocate(gsl::not_null<ENGINE_HANDLE*>,
102                                                  gsl::not_null<const void*>,
103                                                  const DocKey&,
104                                                  const size_t,
105                                                  const int,
106                                                  const rel_time_t,
107                                                  uint8_t,
108                                                  uint16_t) {
109         return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
110     }
111 
item_allocate_ex(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * > cookie,const DocKey &,size_t,size_t,int,rel_time_t,uint8_t,uint16_t)112     static std::pair<cb::unique_item_ptr, item_info> item_allocate_ex(
113             gsl::not_null<ENGINE_HANDLE*>,
114             gsl::not_null<const void*> cookie,
115             const DocKey&,
116             size_t,
117             size_t,
118             int,
119             rel_time_t,
120             uint8_t,
121             uint16_t) {
122         throw cb::engine_error(cb::engine_errc::no_bucket, "no bucket");
123     }
124 
item_delete(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,const DocKey &,uint64_t &,uint16_t,mutation_descr_t &)125     static ENGINE_ERROR_CODE item_delete(gsl::not_null<ENGINE_HANDLE*>,
126                                          gsl::not_null<const void*>,
127                                          const DocKey&,
128                                          uint64_t&,
129                                          uint16_t,
130                                          mutation_descr_t&) {
131         return ENGINE_NO_BUCKET;
132     }
133 
item_release(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<item * >)134     static void item_release(gsl::not_null<ENGINE_HANDLE*>,
135                              gsl::not_null<item*>) {
136         throw std::logic_error("NoBucket::item_release: no items should have"
137                                    " been allocated from this engine");
138     }
139 
get(gsl::not_null<ENGINE_HANDLE * > h,gsl::not_null<const void * >,const DocKey &,uint16_t,DocStateFilter)140     static cb::EngineErrorItemPair get(gsl::not_null<ENGINE_HANDLE*> h,
141                                        gsl::not_null<const void*>,
142                                        const DocKey&,
143                                        uint16_t,
144                                        DocStateFilter) {
145         return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
146     }
147 
get_meta(gsl::not_null<ENGINE_HANDLE * > handle,gsl::not_null<const void * > cookie,const DocKey & key,uint16_t vbucket)148     static cb::EngineErrorMetadataPair get_meta(
149             gsl::not_null<ENGINE_HANDLE*> handle,
150             gsl::not_null<const void*> cookie,
151             const DocKey& key,
152             uint16_t vbucket) {
153         return cb::EngineErrorMetadataPair(cb::engine_errc::no_bucket, {});
154     }
155 
get_if(gsl::not_null<ENGINE_HANDLE * > handle,gsl::not_null<const void * >,const DocKey &,uint16_t,std::function<bool (const item_info &)>)156     static cb::EngineErrorItemPair get_if(
157             gsl::not_null<ENGINE_HANDLE*> handle,
158             gsl::not_null<const void*>,
159             const DocKey&,
160             uint16_t,
161             std::function<bool(const item_info&)>) {
162         return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
163     }
164 
get_and_touch(gsl::not_null<ENGINE_HANDLE * > handle,gsl::not_null<const void * > cookie,const DocKey &,uint16_t,uint32_t)165     static cb::EngineErrorItemPair get_and_touch(
166             gsl::not_null<ENGINE_HANDLE*> handle,
167             gsl::not_null<const void*> cookie,
168             const DocKey&,
169             uint16_t,
170             uint32_t) {
171         return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
172     }
173 
get_locked(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,const DocKey &,uint16_t,uint32_t)174     static cb::EngineErrorItemPair get_locked(gsl::not_null<ENGINE_HANDLE*>,
175                                               gsl::not_null<const void*>,
176                                               const DocKey&,
177                                               uint16_t,
178                                               uint32_t) {
179         return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
180     }
181 
unlock(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,const DocKey &,uint16_t,uint64_t)182     static ENGINE_ERROR_CODE unlock(gsl::not_null<ENGINE_HANDLE*>,
183                                     gsl::not_null<const void*>,
184                                     const DocKey&,
185                                     uint16_t,
186                                     uint64_t) {
187         return ENGINE_NO_BUCKET;
188     }
189 
get_stats(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,cb::const_char_buffer key,ADD_STAT)190     static ENGINE_ERROR_CODE get_stats(gsl::not_null<ENGINE_HANDLE*>,
191                                        gsl::not_null<const void*>,
192                                        cb::const_char_buffer key,
193                                        ADD_STAT) {
194         return ENGINE_NO_BUCKET;
195     }
196 
store(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,gsl::not_null<item * >,uint64_t &,ENGINE_STORE_OPERATION,DocumentState)197     static ENGINE_ERROR_CODE store(gsl::not_null<ENGINE_HANDLE*>,
198                                    gsl::not_null<const void*>,
199                                    gsl::not_null<item*>,
200                                    uint64_t&,
201                                    ENGINE_STORE_OPERATION,
202                                    DocumentState) {
203         return ENGINE_NO_BUCKET;
204     }
205 
store_if(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,gsl::not_null<item * >,uint64_t,ENGINE_STORE_OPERATION,cb::StoreIfPredicate,DocumentState)206     static cb::EngineErrorCasPair store_if(gsl::not_null<ENGINE_HANDLE*>,
207                                            gsl::not_null<const void*>,
208                                            gsl::not_null<item*>,
209                                            uint64_t,
210                                            ENGINE_STORE_OPERATION,
211                                            cb::StoreIfPredicate,
212                                            DocumentState) {
213         return {cb::engine_errc::no_bucket, 0};
214     }
215 
flush(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >)216     static ENGINE_ERROR_CODE flush(gsl::not_null<ENGINE_HANDLE*>,
217                                    gsl::not_null<const void*>) {
218         return ENGINE_NO_BUCKET;
219     }
220 
reset_stats(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * > cookie)221     static void reset_stats(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*> cookie) {
222     }
223 
unknown_command(gsl::not_null<ENGINE_HANDLE * >,const void *,gsl::not_null<protocol_binary_request_header * >,ADD_RESPONSE,DocNamespace)224     static ENGINE_ERROR_CODE unknown_command(
225             gsl::not_null<ENGINE_HANDLE*>,
226             const void*,
227             gsl::not_null<protocol_binary_request_header*>,
228             ADD_RESPONSE,
229             DocNamespace) {
230         return ENGINE_NO_BUCKET;
231     }
232 
item_set_cas(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<item * >,uint64_t)233     static void item_set_cas(gsl::not_null<ENGINE_HANDLE*>,
234                              gsl::not_null<item*>,
235                              uint64_t) {
236         throw std::logic_error("NoBucket::item_set_cas: no items should have"
237                                    " been allocated from this engine");
238     }
239 
item_set_datatype(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<item * >,protocol_binary_datatype_t)240     static void item_set_datatype(gsl::not_null<ENGINE_HANDLE*>,
241                                   gsl::not_null<item*>,
242                                   protocol_binary_datatype_t) {
243         throw std::logic_error(
244                 "NoBucket::item_set_datatype: no items should have"
245                 " been allocated from this engine");
246     }
247 
get_item_info(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const item * >,gsl::not_null<item_info * >)248     static bool get_item_info(gsl::not_null<ENGINE_HANDLE*>,
249                               gsl::not_null<const item*>,
250                               gsl::not_null<item_info*>) {
251         throw std::logic_error("NoBucket::get_item_info: no items should have"
252                                    " been allocated from this engine");
253     }
254 
set_item_info(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<item * >,gsl::not_null<const item_info * >)255     static bool set_item_info(gsl::not_null<ENGINE_HANDLE*>,
256                               gsl::not_null<item*>,
257                               gsl::not_null<const item_info*>) {
258         throw std::logic_error("NoBucket::set_item_info: no items should have"
259                                    " been allocated from this engine");
260     }
261 
dcp_step(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,gsl::not_null<struct dcp_message_producers * >)262     static ENGINE_ERROR_CODE dcp_step(
263             gsl::not_null<ENGINE_HANDLE*>,
264             gsl::not_null<const void*>,
265             gsl::not_null<struct dcp_message_producers*>) {
266         return ENGINE_NO_BUCKET;
267     }
268 
dcp_open(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint32_t,uint32_t,cb::const_char_buffer,cb::const_byte_buffer)269     static ENGINE_ERROR_CODE dcp_open(gsl::not_null<ENGINE_HANDLE*>,
270                                       gsl::not_null<const void*>,
271                                       uint32_t,
272                                       uint32_t,
273                                       uint32_t,
274                                       cb::const_char_buffer,
275                                       cb::const_byte_buffer) {
276         return ENGINE_NO_BUCKET;
277     }
278 
dcp_add_stream(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t,uint32_t)279     static ENGINE_ERROR_CODE dcp_add_stream(gsl::not_null<ENGINE_HANDLE*>,
280                                             gsl::not_null<const void*>,
281                                             uint32_t,
282                                             uint16_t,
283                                             uint32_t) {
284         return ENGINE_NO_BUCKET;
285     }
286 
dcp_close_stream(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t)287     static ENGINE_ERROR_CODE dcp_close_stream(gsl::not_null<ENGINE_HANDLE*>,
288                                               gsl::not_null<const void*>,
289                                               uint32_t,
290                                               uint16_t) {
291         return ENGINE_NO_BUCKET;
292     }
293 
dcp_stream_req(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint32_t,uint16_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t *,dcp_add_failover_log)294     static ENGINE_ERROR_CODE dcp_stream_req(gsl::not_null<ENGINE_HANDLE*>,
295                                             gsl::not_null<const void*>,
296                                             uint32_t,
297                                             uint32_t,
298                                             uint16_t,
299                                             uint64_t,
300                                             uint64_t,
301                                             uint64_t,
302                                             uint64_t,
303                                             uint64_t,
304                                             uint64_t*,
305                                             dcp_add_failover_log) {
306         return ENGINE_NO_BUCKET;
307     }
308 
dcp_get_failover_log(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t,ENGINE_ERROR_CODE (*)(vbucket_failover_t *,size_t,gsl::not_null<const void * >))309     static ENGINE_ERROR_CODE dcp_get_failover_log(
310             gsl::not_null<ENGINE_HANDLE*>,
311             gsl::not_null<const void*>,
312             uint32_t,
313             uint16_t,
314             ENGINE_ERROR_CODE (*)(vbucket_failover_t*,
315                                   size_t,
316                                   gsl::not_null<const void*>)) {
317         return ENGINE_NO_BUCKET;
318     }
319 
dcp_stream_end(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t,uint32_t)320     static ENGINE_ERROR_CODE dcp_stream_end(gsl::not_null<ENGINE_HANDLE*>,
321                                             gsl::not_null<const void*>,
322                                             uint32_t,
323                                             uint16_t,
324                                             uint32_t) {
325         return ENGINE_NO_BUCKET;
326     }
327 
dcp_snapshot_marker(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t,uint64_t,uint64_t,uint32_t)328     static ENGINE_ERROR_CODE dcp_snapshot_marker(gsl::not_null<ENGINE_HANDLE*>,
329                                                  gsl::not_null<const void*>,
330                                                  uint32_t,
331                                                  uint16_t,
332                                                  uint64_t,
333                                                  uint64_t,
334                                                  uint32_t) {
335         return ENGINE_NO_BUCKET;
336     }
337 
dcp_mutation(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,const DocKey &,cb::const_byte_buffer,size_t,uint8_t,uint64_t,uint16_t,uint32_t,uint64_t,uint64_t,uint32_t,uint32_t,cb::const_byte_buffer,uint8_t)338     static ENGINE_ERROR_CODE dcp_mutation(gsl::not_null<ENGINE_HANDLE*>,
339                                           gsl::not_null<const void*>,
340                                           uint32_t,
341                                           const DocKey&,
342                                           cb::const_byte_buffer,
343                                           size_t,
344                                           uint8_t,
345                                           uint64_t,
346                                           uint16_t,
347                                           uint32_t,
348                                           uint64_t,
349                                           uint64_t,
350                                           uint32_t,
351                                           uint32_t,
352                                           cb::const_byte_buffer,
353                                           uint8_t) {
354         return ENGINE_NO_BUCKET;
355     }
356 
dcp_deletion(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,const DocKey &,cb::const_byte_buffer,size_t,uint8_t,uint64_t,uint16_t,uint64_t,uint64_t,cb::const_byte_buffer)357     static ENGINE_ERROR_CODE dcp_deletion(gsl::not_null<ENGINE_HANDLE*>,
358                                           gsl::not_null<const void*>,
359                                           uint32_t,
360                                           const DocKey&,
361                                           cb::const_byte_buffer,
362                                           size_t,
363                                           uint8_t,
364                                           uint64_t,
365                                           uint16_t,
366                                           uint64_t,
367                                           uint64_t,
368                                           cb::const_byte_buffer) {
369         return ENGINE_NO_BUCKET;
370     }
371 
dcp_deletion_v2(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,const DocKey &,cb::const_byte_buffer,size_t,uint8_t,uint64_t,uint16_t,uint64_t,uint64_t,uint32_t)372     static ENGINE_ERROR_CODE dcp_deletion_v2(gsl::not_null<ENGINE_HANDLE*>,
373                                              gsl::not_null<const void*>,
374                                              uint32_t,
375                                              const DocKey&,
376                                              cb::const_byte_buffer,
377                                              size_t,
378                                              uint8_t,
379                                              uint64_t,
380                                              uint16_t,
381                                              uint64_t,
382                                              uint64_t,
383                                              uint32_t) {
384         return ENGINE_NO_BUCKET;
385     }
386 
dcp_expiration(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,const DocKey &,cb::const_byte_buffer,size_t,uint8_t,uint64_t,uint16_t,uint64_t,uint64_t,cb::const_byte_buffer)387     static ENGINE_ERROR_CODE dcp_expiration(gsl::not_null<ENGINE_HANDLE*>,
388                                             gsl::not_null<const void*>,
389                                             uint32_t,
390                                             const DocKey&,
391                                             cb::const_byte_buffer,
392                                             size_t,
393                                             uint8_t,
394                                             uint64_t,
395                                             uint16_t,
396                                             uint64_t,
397                                             uint64_t,
398                                             cb::const_byte_buffer) {
399         return ENGINE_NO_BUCKET;
400     }
401 
dcp_flush(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t)402     static ENGINE_ERROR_CODE dcp_flush(gsl::not_null<ENGINE_HANDLE*>,
403                                        gsl::not_null<const void*>,
404                                        uint32_t,
405                                        uint16_t) {
406         return ENGINE_NO_BUCKET;
407     }
408 
dcp_set_vbucket_state(gsl::not_null<ENGINE_HANDLE * >,gsl::not_null<const void * >,uint32_t,uint16_t,vbucket_state_t)409     static ENGINE_ERROR_CODE dcp_set_vbucket_state(
410             gsl::not_null<ENGINE_HANDLE*>,
411             gsl::not_null<const void*>,
412             uint32_t,
413             uint16_t,
414             vbucket_state_t) {
415         return ENGINE_NO_BUCKET;
416     }
417 
dcp_system_event(gsl::not_null<ENGINE_HANDLE * > handle,gsl::not_null<const void * > cookie,uint32_t opaque,uint16_t vbucket,mcbp::systemevent::id event,uint64_t bySeqno,cb::const_byte_buffer key,cb::const_byte_buffer eventData)418     static ENGINE_ERROR_CODE dcp_system_event(
419             gsl::not_null<ENGINE_HANDLE*> handle,
420             gsl::not_null<const void*> cookie,
421             uint32_t opaque,
422             uint16_t vbucket,
423             mcbp::systemevent::id event,
424             uint64_t bySeqno,
425             cb::const_byte_buffer key,
426             cb::const_byte_buffer eventData) {
427         return ENGINE_NO_BUCKET;
428     }
429 
collections_set_manifest(gsl::not_null<ENGINE_HANDLE * > handle,cb::const_char_buffer json)430     static cb::engine_error collections_set_manifest(
431             gsl::not_null<ENGINE_HANDLE*> handle, cb::const_char_buffer json) {
432         return {cb::engine_errc::no_bucket,
433                 "nobucket::collections_set_manifest"};
434     }
435 
collections_get_manifest(gsl::not_null<ENGINE_HANDLE * > handle)436     static cb::EngineErrorStringPair collections_get_manifest(
437             gsl::not_null<ENGINE_HANDLE*> handle) {
438         return {cb::engine_errc::no_bucket,
439                 "nobucket::collections_get_manifest"};
440     }
441 
isXattrEnabled(gsl::not_null<ENGINE_HANDLE * > handle)442     static bool isXattrEnabled(gsl::not_null<ENGINE_HANDLE*> handle) {
443         return false;
444     }
445 
getCompressionMode(gsl::not_null<ENGINE_HANDLE * > handle)446     static BucketCompressionMode getCompressionMode(gsl::not_null<ENGINE_HANDLE*> handle) {
447         return BucketCompressionMode::Off;
448     }
449 
getMaxItemSize(gsl::not_null<ENGINE_HANDLE * > handle)450     static size_t getMaxItemSize(gsl::not_null<ENGINE_HANDLE*> handle) {
451         return default_max_item_size;
452     }
453 
getMinCompressionRatio(gsl::not_null<ENGINE_HANDLE * > handle)454     static float getMinCompressionRatio(gsl::not_null<ENGINE_HANDLE*> handle) {
455         return default_min_compression_ratio;
456     }
457 };
458 
459 MEMCACHED_PUBLIC_API
create_no_bucket_instance(uint64_t interface,GET_SERVER_API get_server_api,ENGINE_HANDLE ** handle)460 ENGINE_ERROR_CODE create_no_bucket_instance(uint64_t interface,
461                                             GET_SERVER_API get_server_api,
462                                             ENGINE_HANDLE **handle)
463 {
464     if (interface != 1) {
465         return ENGINE_ENOTSUP;
466     }
467 
468     try {
469         NoBucket* engine = new NoBucket();
470         *handle = reinterpret_cast<ENGINE_HANDLE*>(engine);
471     } catch (std::bad_alloc& e) {
472         auto logger = get_server_api()->log->get_logger();
473         logger->log(EXTENSION_LOG_WARNING, NULL,
474                     "NoBucket: failed to create engine: %s", e.what());
475         return ENGINE_FAILED;
476     }
477 
478     return ENGINE_SUCCESS;
479 }
480 
481 MEMCACHED_PUBLIC_API
destroy_engine(void)482 void destroy_engine(void) {
483     // Empty
484 }
485