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