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