All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_operations.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2015 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at 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, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <stdbool.h>
20 #include <stdint.h>
21 #include <aerospike/as_bin.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /******************************************************************************
28  * TYPES
29  *****************************************************************************/
30 
31 /**
32  * Operation Identifiers
33  */
34 typedef enum as_operator_e {
35 
36  /**
37  * Return the bin from the cluster.
38  */
40 
41  /**
42  * Update the bin.
43  */
45 
46  /**
47  * Increment a bin containing an
48  * integer value.
49  */
51 
52  /**
53  * Append bytes to the bin containing
54  * either a string or blob.
55  */
57 
58  /**
59  * Prepend bytes to the bin containing
60  * either a string or blob.
61  */
63 
64  /**
65  * Touch the record's ttl.
66  */
68 
69 } as_operator;
70 
71 /**
72  * Operation on a bin.
73  * The value for the bin will be applied according to the operation.
74  */
75 typedef struct as_binop_s {
76 
77  /**
78  * The operation to be performed on the bin.
79  */
81 
82  /**
83  * The bin the operation will be performed on.
84  */
86 
87 } as_binop;
88 
89 /**
90  * Sequence of operations.
91  *
92  * ~~~~~~~~~~{.c}
93  * as_operations ops;
94  * as_operations_inita(&ops, 2);
95  * as_operations_add_incr(&ops, "bin1", 123);
96  * as_operations_add_append_str(&ops, "bin2", "abc");
97  * ...
98  * as_operations_destroy(&ops);
99  * ~~~~~~~~~~
100  *
101  */
102 typedef struct as_binops_s {
103 
104  /**
105  * @private
106  * If true, then as_binops_destroy() will free the entries.
107  */
108  bool _free;
109 
110  /**
111  * Number of entries allocated
112  */
113  uint16_t capacity;
114 
115  /**
116  * Number of entries used
117  */
118  uint16_t size;
119 
120  /**
121  * Sequence of entries
122  */
124 
125 } as_binops;
126 
127 /**
128  * The `aerospike_key_operate()` function provides the ability to execute
129  * multiple operations on a record in the database as a single atomic
130  * transaction.
131  *
132  * The `as_operations` object is used to define the operations to be performed
133  * on the record.
134  *
135  * ## Initialization
136  *
137  * Before using as_operations, you must first initialize it via either:
138  * - as_operations_inita()
139  * - as_operations_init()
140  * - as_operations_new()
141  *
142  * as_operations_inita() is a macro that initializes a stack allocated
143  * as_operations and allocates an internal array of operations. The macro
144  * accepts a pointer to the stack allocated as_operations and the number of
145  * operations to be added.
146  *
147  * ~~~~~~~~~~{.c}
148  * as_operations ops;
149  * as_operations_inita(&ops, 2);
150  * ~~~~~~~~~~
151  *
152  * as_operations_init() is a function that initializes a stack allocated
153  * as_operations. It differes from as_operations_inita() in that it allocates
154  * the internal array of operations on the heap. It accepts a pointer to the
155  * stack allocated as_operations and the number of operations to be added.
156  *
157  * ~~~~~~~~~~{.c}
158  * as_operations ops;
159  * as_operations_init(&ops, 2);
160  * ~~~~~~~~~~
161  *
162  * as_operations_new() is a function that will allocate a new as_operations
163  * on the heap. It will also allocate the internal array of operation on the
164  * heap.
165  *
166  * ~~~~~~~~~~{.c}
167  * as_operations * ops = as_operations_new(2);
168  * ~~~~~~~~~~
169  *
170  * When you no longer needthe as_operations, you can release the resources
171  * allocated to it via as_operations_destroy().
172  *
173  * ## Destruction
174  *
175  * When you no longer require an as_operations, you should call
176  * `as_operations_destroy()` to release it and associated resources.
177  *
178  * ~~~~~~~~~~{.c}
179  * as_operations_destroy(ops);
180  * ~~~~~~~~~~
181  *
182  * ## Usage
183  *
184  * as_operations is a sequence of operations to be applied to a record.
185  *
186  * Each of the following operations is added to the end of the sequence
187  * of operations.
188  *
189  * When you have compiled the sequence of operations you want to execute,
190  * then you will send it to aerospike_key_operate().
191  *
192  *
193  * ### Modifying a String
194  *
195  * Aerospike allows you to append a string to a bin containing
196  * a string.
197  *
198  * The following appends a "abc" to bin "bin1".
199  *
200  * ~~~~~~~~~~{.c}
201  * as_operations_add_append_str(ops, "bin1", "abc");
202  * ~~~~~~~~~~
203  *
204  * There is also a prepend operation, which will add the string
205  * to the beginning of the bin's current value.
206  *
207  * ~~~~~~~~~~{.c}
208  * as_operations_add_prepend_str(ops, "bin1", "abc");
209  * ~~~~~~~~~~
210  *
211  * ### Modifying a Byte Array
212  *
213  * Aerospike allows you to append a byte array to a bin containing
214  * a byte array.
215  *
216  * The following appends a 4 byte sequence to bin "bin1".
217  *
218  * ~~~~~~~~~~{.c}
219  * uint8_t raw[4] = { 1, 2, 3, 4 };
220  * as_operations_add_append_raw(ops, "bin1", raw, 4);
221  * ~~~~~~~~~~
222  *
223  * There is also a prepend operation, which will add the bytes
224  * to the beginning of the bin's current value.
225  *
226  * ~~~~~~~~~~{.c}
227  * uint8_t raw[4] = { 1, 2, 3, 4 };
228  * as_operations_add_prepend_raw(ops, "bin1", raw, 4);
229  * ~~~~~~~~~~
230  *
231  * ### Increment an Integer
232  *
233  * Aerospike allows you to increment the value of a bin
234  *
235  * The following increments the value in bin "bin1" by 4.
236  *
237  * ~~~~~~~~~~{.c}
238  * as_operations_add_incr(ops, "bin1", 4);
239  * ~~~~~~~~~~
240  *
241  * ### Write a Value
242  *
243  * Write a value into a bin. Overwriting previous value.
244  *
245  * The following writes a string "xyz" to "bin1".
246  *
247  * ~~~~~~~~~~{.c}
248  * as_operations_add_write_str(ops, "bin1", "xyz");
249  * ~~~~~~~~~~
250  *
251  * ### Read a Value
252  *
253  * Read a value from a bin. This is ideal, if you performed an
254  * operation on a bin, and want to read the new value.
255  *
256  * The following reads the value of "bin1"
257  *
258  * ~~~~~~~~~~{.c}
259  * as_operations_add_read(ops, "bin1", "xyz");
260  * ~~~~~~~~~~
261  *
262  * ### Touch a Record
263  *
264  * Touching a record will refresh its ttl and increment the generation
265  * of the record.
266  *
267  * The following touches a record.
268  *
269  * ~~~~~~~~~~{.c}
270  * as_operations_add_touch(ops);
271  * ~~~~~~~~~~
272  *
273  * @ingroup client_objects
274  */
275 typedef struct as_operations_s {
276 
277  /**
278  * @private
279  * If true, then as_operations_destroy() will free this instance.
280  */
281  bool _free;
282 
283  /**
284  * The generation of the record.
285  */
286  uint16_t gen;
287 
288  /**
289  * The time-to-live (expiration) of the record in seconds.
290  */
291  uint32_t ttl;
292 
293  /**
294  * Operations to be performed on the bins of a record.
295  */
297 
298 } as_operations;
299 
300 /******************************************************************************
301  * MACROS
302  *****************************************************************************/
303 
304 /**
305  * Initializes a stack allocated `as_operations` (as_operations) and allocates
306  * `__nops` number of entries on the stack.
307  *
308  * ~~~~~~~~~~{.c}
309  * as_operations ops;
310  * as_operations_inita(&ops, 2);
311  * as_operations_add_incr(&ops, "bin1", 123);
312  * as_operations_add_append_str(&ops, "bin2", "abc");
313  * ~~~~~~~~~~
314  *
315  * @param __ops The `as_operations *` to initialize.
316  * @param __nops The number of `as_binops.entries` to allocate on the
317  * stack.
318  *
319  * @relates as_operations
320  * @ingroup as_operations_object
321  */
322 #define as_operations_inita(__ops, __nops) \
323  (__ops)->_free = false;\
324  (__ops)->gen = 0;\
325  (__ops)->ttl = 0;\
326  (__ops)->binops._free = false;\
327  (__ops)->binops.capacity = __nops;\
328  (__ops)->binops.size = 0;\
329  (__ops)->binops.entries = (as_binop *) alloca(sizeof(as_binop) * __nops);
330 
331 /******************************************************************************
332  * FUNCTIONS
333  *****************************************************************************/
334 
335 /**
336  * Intializes a stack allocated `as_operations`.
337  *
338  * ~~~~~~~~~~{.c}
339  * as_operations ops;
340  * as_operations_init(&ops, 2);
341  * as_operations_add_incr(&ops, "bin1", 123);
342  * as_operations_add_append_str(&ops, "bin2", "abc");
343  * ~~~~~~~~~~
344  *
345  * Use `as_operations_destroy()` to free the resources allocated to the
346  * `as_operations`.
347  *
348  * @param ops The `as_operations` to initialize.
349  * @param nops The number of `as_operations.binops.entries` to allocate on the heap.
350  *
351  * @return The initialized `as_operations` on success. Otherwise NULL.
352  *
353  * @relates as_operations
354  * @ingroup as_operations_object
355  */
356 as_operations * as_operations_init(as_operations * ops, uint16_t nops);
357 
358 /**
359  * Create and initialize a heap allocated `as_operations`.
360  *
361  * ~~~~~~~~~~{.c}
362  * as_operations ops = as_operations_new(2);
363  * as_operations_add_incr(ops, "bin1", 123);
364  * as_operations_add_append_str(ops, "bin2", "abc");
365  * ~~~~~~~~~~
366  *
367  * Use `as_operations_destroy()` to free the resources allocated to the
368  * `as_operations`.
369  *
370  * @param nops The number of `as_operations.binops.entries` to allocate on the heap.
371  *
372  * @return The new `as_operations` on success. Otherwise NULL.
373  *
374  * @relates as_operations
375  * @ingroup as_operations_object
376  */
377 as_operations * as_operations_new(uint16_t nops);
378 
379 /**
380  * Destroy an `as_operations` and release associated resources.
381  *
382  * ~~~~~~~~~~{.c}
383  * as_operations_destroy(binops);
384  * ~~~~~~~~~~
385  *
386  * @param ops The `as_operations` to destroy.
387  *
388  * @relates as_operations
389  * @ingroup as_operations_object
390  */
392 
393 /**
394  * Add a `AS_OPERATOR_WRITE` bin operation.
395  *
396  * @param ops The `as_operations` to append the operation to.
397  * @param name The name of the bin to perform the operation on.
398  * @param value The value to be used in the operation.
399  *
400  * @return true on success. Otherwise an error occurred.
401  *
402  * @relates as_operations
403  * @ingroup as_operations_object
404  */
405 bool as_operations_add_write(as_operations * ops, const as_bin_name name, as_bin_value * value);
406 
407 /**
408  * Add a `AS_OPERATOR_WRITE` bin operation with an int64_t value.
409  *
410  * @param ops The `as_operations` to append the operation to.
411  * @param name The name of the bin to perform the operation on.
412  * @param value The value to be used in the operation.
413  *
414  * @return true on success. Otherwise an error occurred.
415  *
416  * @relates as_operations
417  * @ingroup as_operations_object
418  */
419 bool as_operations_add_write_int64(as_operations * ops, const as_bin_name name, int64_t value);
420 
421 /**
422  * Add a `AS_OPERATOR_WRITE` bin operation with a double value.
423  *
424  * @param ops The `as_operations` to append the operation to.
425  * @param name The name of the bin to perform the operation on.
426  * @param value The value to be used in the operation.
427  *
428  * @return true on success. Otherwise an error occurred.
429  *
430  * @relates as_operations
431  * @ingroup as_operations_object
432  */
433 bool as_operations_add_write_double(as_operations * ops, const as_bin_name name, double value);
434 
435 /**
436  * Add a `AS_OPERATOR_WRITE` bin operation with a NULL-terminated string value.
437  *
438  * @param ops The `as_operations` to append the operation to.
439  * @param name The name of the bin to perform the operation on.
440  * @param value The value to be used in the operation.
441  * @param free If true, then the value will be freed when the operations is destroyed.
442  *
443  * @return true on success. Otherwise an error occurred.
444  *
445  * @relates as_operations
446  * @ingroup as_operations_object
447  */
448 bool as_operations_add_write_strp(as_operations * ops, const as_bin_name name, const char * value, bool free);
449 
450 /**
451  * Add a `AS_OPERATOR_WRITE` bin operation with a NULL-terminated string value.
452  *
453  * @param ops The `as_operations` to append the operation to.
454  * @param name The name of the bin to perform the operation on.
455  * @param value The value to be used in the operation. Must last for the lifetime of the operations.
456  *
457  * @return true on success. Otherwise an error occurred.
458  *
459  * @relates as_operations
460  * @ingroup as_operations_object
461  */
462 static inline bool as_operations_add_write_str(as_operations * ops, const as_bin_name name, const char * value)
463 {
464  return as_operations_add_write_strp(ops, name, value, false);
465 }
466 
467 /**
468  * Add a `AS_OPERATOR_WRITE` bin operation with a raw bytes value.
469  *
470  * @param ops The `as_operations` to append the operation to.
471  * @param name The name of the bin to perform the operation on.
472  * @param value The value to be used in the operation.
473  * @param size The size of the value.
474  * @param free If true, then the value will be freed when the operations is destroyed.
475  *
476  * @return true on success. Otherwise an error occurred.
477  *
478  * @relates as_operations
479  * @ingroup as_operations_object
480  */
481 bool as_operations_add_write_rawp(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size, bool free);
482 
483 /**
484  * Add a `AS_OPERATOR_WRITE` bin operation with a raw bytes value.
485  *
486  * @param ops The `as_operations` to append the operation to.
487  * @param name The name of the bin to perform the operation on.
488  * @param value The value to be used in the operation.
489  * @param size The size of the value. Must last for the lifetime of the operations.
490  *
491  * @return true on success. Otherwise an error occurred.
492  *
493  * @relates as_operations
494  * @ingroup as_operations_object
495  */
496 static inline bool as_operations_add_write_raw(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size)
497 {
498  return as_operations_add_write_rawp(ops, name, value, size, false);
499 }
500 
501 /**
502  * Add a `AS_OPERATOR_READ` bin operation.
503  *
504  * @param ops The `as_operations` to append the operation to.
505  * @param name The name of the bin to perform the operation on.
506  *
507  * @return true on success. Otherwise an error occurred.
508  *
509  * @relates as_operations
510  * @ingroup as_operations_object
511  */
512 bool as_operations_add_read(as_operations * ops, const as_bin_name name);
513 
514 /**
515  * Add a `AS_OPERATOR_INCR` bin operation with (required) int64_t value.
516  *
517  * @param ops The `as_operations` to append the operation to.
518  * @param name The name of the bin to perform the operation on.
519  * @param value The value to be used in the operation.
520  *
521  * @return true on success. Otherwise an error occurred.
522  *
523  * @relates as_operations
524  * @ingroup as_operations_object
525  */
526 bool as_operations_add_incr(as_operations * ops, const as_bin_name name, int64_t value);
527 
528 /**
529  * Add a `AS_OPERATOR_INCR` bin operation with double value.
530  *
531  * @param ops The `as_operations` to append the operation to.
532  * @param name The name of the bin to perform the operation on.
533  * @param value The value to be used in the operation.
534  *
535  * @return true on success. Otherwise an error occurred.
536  *
537  * @relates as_operations
538  * @ingroup as_operations_object
539  */
540 bool as_operations_add_incr_double(as_operations * ops, const as_bin_name name, double value);
541 
542 /**
543  * Add a `AS_OPERATOR_PREPEND` bin operation with a NULL-terminated string value.
544  *
545  * @param ops The `as_operations` to append the operation to.
546  * @param name The name of the bin to perform the operation on.
547  * @param value The value to be used in the operation.
548  * @param free If true, then the value will be freed when the operations is destroyed.
549  *
550  * @return true on success. Otherwise an error occurred.
551  *
552  * @relates as_operations
553  * @ingroup as_operations_object
554  */
555 bool as_operations_add_prepend_strp(as_operations * ops, const as_bin_name name, const char * value, bool free);
556 
557 /**
558  * Add a `AS_OPERATOR_PREPEND` bin operation with a NULL-terminated string value.
559  *
560  * @param ops The `as_operations` to append the operation to.
561  * @param name The name of the bin to perform the operation on.
562  * @param value The value to be used in the operation. Must last for the lifetime of the operations.
563  *
564  * @return true on success. Otherwise an error occurred.
565  *
566  * @relates as_operations
567  * @ingroup as_operations_object
568  */
569 static inline bool as_operations_add_prepend_str(as_operations * ops, const as_bin_name name, const char * value)
570 {
571  return as_operations_add_prepend_strp(ops, name, value, false);
572 }
573 
574 /**
575  * Add a `AS_OPERATOR_PREPEND` bin operation with a raw bytes value.
576  *
577  * @param ops The `as_operations` to append the operation to.
578  * @param name The name of the bin to perform the operation on.
579  * @param value The value to be used in the operation.
580  * @param size The size of the value.
581  * @param free If true, then the value will be freed when the operations is destroyed.
582  *
583  * @return true on success. Otherwise an error occurred.
584  *
585  * @relates as_operations
586  * @ingroup as_operations_object
587  */
588 bool as_operations_add_prepend_rawp(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size, bool free);
589 
590 /**
591  * Add a `AS_OPERATOR_PREPEND` bin operation with a raw bytes value.
592  *
593  * @param ops The `as_operations` to append the operation to.
594  * @param name The name of the bin to perform the operation on.
595  * @param value The value to be used in the operation. Must last for the lifetime of the operations.
596  * @param size The size of the value.
597  *
598  * @return true on success. Otherwise an error occurred.
599  *
600  * @relates as_operations
601  * @ingroup as_operations_object
602  */
603 static inline bool as_operations_add_prepend_raw(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size)
604 {
605  return as_operations_add_prepend_rawp(ops, name, value, size, false);
606 }
607 
608 /**
609  * Add a `AS_OPERATOR_APPEND` bin operation with a NULL-terminated string value.
610  *
611  * @param ops The `as_operations` to append the operation to.
612  * @param name The name of the bin to perform the operation on.
613  * @param value The value to be used in the operation.
614  * @param free If true, then the value will be freed when the operations is destroyed.
615  *
616  * @return true on success. Otherwise an error occurred.
617  *
618  * @relates as_operations
619  * @ingroup as_operations_object
620  */
621 bool as_operations_add_append_strp(as_operations * ops, const as_bin_name name, const char * value, bool free);
622 
623 /**
624  * Add a `AS_OPERATOR_APPEND` bin operation with a NULL-terminated string value.
625  *
626  * @param ops The `as_operations` to append the operation to.
627  * @param name The name of the bin to perform the operation on.
628  * @param value The value to be used in the operation. Must last for the lifetime of the operations.
629  *
630  * @return true on success. Otherwise an error occurred.
631  *
632  * @relates as_operations
633  * @ingroup as_operations_object
634  */
635 static inline bool as_operations_add_append_str(as_operations * ops, const as_bin_name name, const char * value)
636 {
637  return as_operations_add_append_strp(ops, name, value, false);
638 }
639 
640 /**
641  * Add a `AS_OPERATOR_APPEND` bin operation with a raw bytes value.
642  *
643  * @param ops The `as_operations` to append the operation to.
644  * @param name The name of the bin to perform the operation on.
645  * @param value The value to be used in the operation.
646  * @param size The size of the value.
647  * @param free If true, then the value will be freed when the operations is destroyed.
648  *
649  * @return true on success. Otherwise an error occurred.
650  *
651  * @relates as_operations
652  * @ingroup as_operations_object
653  */
654 bool as_operations_add_append_rawp(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size, bool free);
655 
656 /**
657  * Add a `AS_OPERATOR_APPEND` bin operation with a raw bytes value.
658  *
659  * @param ops The `as_operations` to append the operation to.
660  * @param name The name of the bin to perform the operation on.
661  * @param value The value to be used in the operation. Must last for the lifetime of the operations.
662  * @param size The size of the value.
663  *
664  * @return true on success. Otherwise an error occurred.
665  *
666  * @relates as_operations
667  * @ingroup as_operations_object
668  */
669 static inline bool as_operations_add_append_raw(as_operations * ops, const as_bin_name name, const uint8_t * value, uint32_t size)
670 {
671  return as_operations_add_append_rawp(ops, name, value, size, false);
672 }
673 
674 /**
675  * Add a `AS_OPERATOR_TOUCH` record operation.
676  *
677  * @param ops The `as_operations` to append the operation to.
678  *
679  * @return true on success. Otherwise an error occurred.
680  *
681  * @relates as_operations
682  * @ingroup as_operations_object
683  */
685 
686 #ifdef __cplusplus
687 } // end extern "C"
688 #endif