All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_rec.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 
18 #pragma once
19 
20 #include <aerospike/as_integer.h>
21 #include <aerospike/as_bytes.h>
22 #include <aerospike/as_geojson.h>
23 #include <aerospike/as_list.h>
24 #include <aerospike/as_map.h>
25 #include <aerospike/as_string.h>
26 #include <aerospike/as_util.h>
27 #include <aerospike/as_val.h>
28 
29 #include <stdbool.h>
30 #include <stdint.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /******************************************************************************
37  * TYPES
38  *****************************************************************************/
39 
40 struct as_rec_hooks_s;
41 
42 /**
43  * Callback function for `as_rec_bin_names()`. Used for porting bin names
44  * to Lua.
45  *
46  * @param bin_names A string containing the (null-terminated) bin names.
47  * @param nbins The number of bins in the record.
48  * @param max_name_size The maximum length of a bin name.
49  * @param udata User-provided data.
50  */
51 typedef void (* as_rec_bin_names_callback) (char * bin_names, uint32_t nbins, uint16_t max_name_size, void * udata);
52 
53 /**
54  * Callback function for `as_rec_foreach()`. Called for each bin in the
55  * record.
56  *
57  * @param name The name of the current bin.
58  * @param value The value of the current bin.
59  * @param udata The user-data provided to the `as_rec_foreach()`.
60  *
61  * @return true to continue iterating through the list.
62  * false to stop iterating.
63  */
64 typedef bool (* as_rec_foreach_callback) (const char * name, const as_val * value, void * udata);
65 
66 /**
67  * as_rec is an interface for record types. A record is how data in Aerospike
68  * is represented, and is composed of bins and metadata.
69  *
70  * Implementations:
71  * - as_record
72  *
73  * @extends as_val
74  * @ingroup aerospike_t
75  */
76 typedef struct as_rec_s {
77 
78  /**
79  * @private
80  * as_rec is a subtype of as_val.
81  * You can cast as_rec to as_val.
82  */
84 
85  /**
86  * Data provided by the implementation of `as_rec`.
87  */
88  void * data;
89 
90  /**
91  * Hooks provided by the implementation of `as_rec`.
92  */
93  const struct as_rec_hooks_s * hooks;
94 
95 } as_rec;
96 
97 /**
98  * Record Hooks.
99  *
100  * An implementation of `as_rec` should provide implementations for each
101  * of the hooks.
102  */
103 typedef struct as_rec_hooks_s {
104 
105  /**
106  * Destroy the record.
107  */
108  bool (* destroy)(as_rec * rec);
109 
110  /**
111  * Get the hashcode of the record.
112  */
113  uint32_t (* hashcode)(const as_rec * rec);
114 
115  /**
116  * Get the value of the bin in the record.
117  */
118  as_val * (* get)(const as_rec * rec, const char * name);
119 
120  /**
121  * Set the value of the bin in the record.
122  */
123  int (* set)(const as_rec * rec, const char * name, const as_val * value);
124 
125  /**
126  * Remove the bin from the record.
127  */
128  int (* remove)(const as_rec * rec, const char * bin);
129 
130  /**
131  * Get the ttl value of the record.
132  */
133  uint32_t (* ttl)(const as_rec * rec);
134 
135  /**
136  * Get the generation value of the record.
137  */
138  uint16_t (* gen)(const as_rec * rec);
139 
140  /**
141  * Get the record's key.
142  */
143  as_val * (* key)(const as_rec * rec);
144 
145  /**
146  * Get the record's set name.
147  */
148  const char * (* setname)(const as_rec * rec);
149 
150  /**
151  * Get the number of bins of the record.
152  */
153  uint16_t (* numbins)(const as_rec * rec);
154 
155  /**
156  * Get a list of the record's bin names.
157  */
158  int (* bin_names)(const as_rec * rec, as_rec_bin_names_callback callback, void * udata);
159 
160  /**
161  * Get the digest of the record.
162  */
163  as_bytes * (* digest)(const as_rec * rec);
164 
165  /**
166  * Set flags on a bin.
167  */
168  int (* set_flags)(const as_rec * rec, const char * bin, uint8_t flags);
169 
170  /**
171  * Set the type of record.
172  */
173  int (* set_type)(const as_rec * rec, int8_t type);
174 
175  /**
176  * Set the time to live (ttl) of the record.
177  */
178  int (* set_ttl)(const as_rec * rec, uint32_t ttl);
179 
180  /**
181  * Discard the record's key.
182  */
183  int (* drop_key)(const as_rec * rec);
184 
185  /**
186  * Iterate over each bin in the record.
187  */
188  bool (* foreach)(const as_rec * rec, as_rec_foreach_callback callback, void * udata);
189 
190 } as_rec_hooks;
191 
192 /******************************************************************************
193  * INSTANCE FUNCTIONS
194  *****************************************************************************/
195 
196 /**
197  * @private
198  * Utilized by subtypes of as_rec to initialize the parent.
199  *
200  * @param rec The record to initialize
201  * @param free If TRUE, then as_rec_destory() will free the record.
202  * @param data Data for the map.
203  * @param hooks Implementation for the map interface.
204  *
205  * @return The initialized as_map on success. Otherwise NULL.
206  *
207  * @relatesalso as_rec
208  */
209 as_rec * as_rec_cons(as_rec * rec, bool free, void * data, const as_rec_hooks * hooks);
210 
211 /**
212  * Initialize a stack allocated record.
213  *
214  * @param rec Stack allocated record to initialize.
215  * @param data Data for the record.
216  * @param hooks Implementation for the record interface.
217  *
218  * @return On success, the initialized record. Otherwise NULL.
219  *
220  * @relatesalso as_rec
221  */
222 as_rec * as_rec_init(as_rec * rec, void * data, const as_rec_hooks * hooks);
223 
224 /**
225  * Create and initialize a new heap allocated record.
226  *
227  * @param data Data for the record.
228  * @param hooks Implementation for the record interface.
229  *
230  * @return On success, a new record. Otherwise NULL.
231  *
232  * @relatesalso as_rec
233  */
234 as_rec * as_rec_new(void * data, const as_rec_hooks * hooks);
235 
236 /**
237  * Destroy the record.
238  *
239  * @relatesalso as_rec
240  */
241 static inline void as_rec_destroy(as_rec * rec)
242 {
243  as_val_destroy((as_val *) rec);
244 }
245 
246 /******************************************************************************
247  * INLINE FUNCTIONS
248  ******************************************************************************/
249 
250 /**
251  * Get the data source for the record.
252  *
253  * @relatesalso as_rec
254  */
255 static inline void * as_rec_source(const as_rec * rec)
256 {
257  return rec ? rec->data : NULL;
258 }
259 
260 /**
261  * Remove a bin from a record.
262  *
263  * @param rec The record to remove the bin from.
264  * @param name The name of the bin to remove.
265  *
266  * @return 0 on success, otherwise an error occurred.
267  *
268  * @relatesalso as_rec
269  */
270 static inline int as_rec_remove(const as_rec * rec, const char * name)
271 {
272  return as_util_hook(remove, 1, rec, name);
273 }
274 
275 /**
276  * Get the ttl for the record.
277  *
278  * @relatesalso as_rec
279  */
280 static inline uint32_t as_rec_ttl(const as_rec * rec)
281 {
282  return as_util_hook(ttl, 0, rec);
283 }
284 
285 /**
286  * Get the generation of the record
287  *
288  * @relatesalso as_rec
289  */
290 static inline uint16_t as_rec_gen(const as_rec * rec)
291 {
292  return as_util_hook(gen, 0, rec);
293 }
294 
295 /**
296  * Get the record's key.
297  *
298  * @relatesalso as_rec
299  */
300 static inline as_val * as_rec_key(const as_rec * rec)
301 {
302  return as_util_hook(key, 0, rec);
303 }
304 
305 /**
306  * Get the record's set name.
307  *
308  * @relatesalso as_rec
309  */
310 static inline const char * as_rec_setname(const as_rec * rec)
311 {
312  return as_util_hook(setname, 0, rec);
313 }
314 
315 /**
316  * Get the number of bins in the record.
317  *
318  * @relatesalso as_rec
319  */
320 static inline uint16_t as_rec_numbins(const as_rec * rec)
321 {
322  return as_util_hook(numbins, 0, rec);
323 }
324 
325 /**
326  * Get a list of the bin names in the record.
327  *
328  * @relatesalso as_rec
329  */
330 static inline int as_rec_bin_names(const as_rec * rec, as_rec_bin_names_callback callback, void * udata)
331 {
332  return as_util_hook(bin_names, 0, rec, callback, udata);
333 }
334 
335 /**
336  * Get the digest of the record.
337  *
338  * @relatesalso as_rec
339  */
340 static inline as_bytes * as_rec_digest(const as_rec * rec)
341 {
342  return as_util_hook(digest, 0, rec);
343 }
344 
345 /**
346  * Set flags on a bin.
347  *
348  * @relatesalso as_rec
349  */
350 static inline int as_rec_set_flags(const as_rec * rec, const char * name, uint8_t flags)
351 {
352  return as_util_hook(set_flags, 0, rec, name, flags);
353 }
354 
355 /**
356  * Set the record type.
357  *
358  * @relatesalso as_rec
359  */
360 static inline int as_rec_set_type(const as_rec * rec, int8_t rec_type)
361 {
362  return as_util_hook(set_type, 0, rec, rec_type);
363 }
364 
365 /**
366  * Set the time to live (ttl).
367  *
368  * @relatesalso as_rec
369  */
370 static inline int as_rec_set_ttl(const as_rec * rec, uint32_t ttl)
371 {
372  return as_util_hook(set_ttl, 0, rec, ttl);
373 }
374 
375 /**
376  * Drop the record's key.
377  *
378  * @relatesalso as_rec
379  */
380 static inline int as_rec_drop_key(const as_rec * rec)
381 {
382  return as_util_hook(drop_key, 0, rec);
383 }
384 
385 /******************************************************************************
386  * BIN GETTER FUNCTIONS
387  ******************************************************************************/
388 
389 /**
390  * Get a bin's value.
391  *
392  * @param rec The as_rec to read the bin value from.
393  * @param name The name of the bin.
394  *
395  * @return On success, the value of the bin. Otherwise NULL.
396  *
397  * @relatesalso as_rec
398  */
399 static inline as_val * as_rec_get(const as_rec * rec, const char * name)
400 {
401  return as_util_hook(get, NULL, rec, name);
402 }
403 
404 /**
405  * Get a bin's value as an int64_t.
406  *
407  * @param rec The as_rec to read the bin value from.
408  * @param name The name of the bin.
409  *
410  * @return On success, the value of the bin. Otherwise 0.
411  *
412  * @relatesalso as_rec
413  */
414 static inline int64_t as_rec_get_int64(const as_rec * rec, const char * name)
415 {
416  as_val * v = as_util_hook(get, NULL, rec, name);
418  return i ? as_integer_toint(i) : 0;
419 }
420 
421 /**
422  * Get a bin's value as a double.
423  *
424  * @param rec The as_rec to read the bin value from.
425  * @param name The name of the bin.
426  *
427  * @return On success, the value of the bin. Otherwise 0.
428  *
429  * @relatesalso as_rec
430  */
431 static inline double as_rec_get_double(const as_rec * rec, const char * name)
432 {
433  as_val * v = as_util_hook(get, NULL, rec, name);
434  as_double * ptr = as_double_fromval(v);
435  return ptr ? ptr->value : 0.0;
436 }
437 
438 /**
439  * Get a bin's value as a NULL terminated string.
440  *
441  * @param rec The as_rec to read the bin value from.
442  * @param name The name of the bin.
443  *
444  * @return On success, the value of the bin. Otherwise NULL.
445  *
446  * @relatesalso as_rec
447  */
448 static inline char * as_rec_get_str(const as_rec * rec, const char * name)
449 {
450  as_val * v = as_util_hook(get, NULL, rec, name);
451  as_string * s = as_string_fromval(v);
452  return s ? as_string_tostring(s) : 0;
453 }
454 
455 /**
456  * Get a bin's value as a NULL terminated GeoJSON string.
457  *
458  * @param rec The as_rec to read the bin value from.
459  * @param name The name of the bin.
460  *
461  * @return On success, the value of the bin. Otherwise NULL.
462  *
463  * @relatesalso as_rec
464  */
465 static inline char * as_rec_get_geojson_str(const as_rec * rec, const char * name)
466 {
467  as_val * v = as_util_hook(get, NULL, rec, name);
469  return as_geojson_get(s);
470 }
471 
472 /**
473  * Get a bin's value as an as_integer.
474  *
475  * @param rec The as_rec to read the bin value from.
476  * @param name The name of the bin.
477  *
478  * @return On success, the value of the bin. Otherwise NULL.
479  *
480  * @relatesalso as_rec
481  */
482 static inline as_integer * as_rec_get_integer(const as_rec * rec, const char * name)
483 {
484  as_val * v = as_util_hook(get, NULL, rec, name);
485  return as_integer_fromval(v);
486 }
487 
488 /**
489  * Get a bin's value as an as_double.
490  *
491  * @param rec The as_rec to read the bin value from.
492  * @param name The name of the bin.
493  *
494  * @return On success, the value of the bin. Otherwise NULL.
495  *
496  * @relatesalso as_rec
497  */
498 static inline as_double * as_rec_get_as_double(const as_rec * rec, const char * name)
499 {
500  as_val * v = as_util_hook(get, NULL, rec, name);
501  return as_double_fromval(v);
502 }
503 
504 /**
505  * Get a bin's value as an as_string.
506  *
507  * @param rec The as_rec to read the bin value from.
508  * @param name The name of the bin.
509  *
510  * @return On success, the value of the bin. Otherwise NULL.
511  *
512  * @relatesalso as_rec
513  */
514 static inline as_string * as_rec_get_string(const as_rec * rec, const char * name)
515 {
516  as_val * v = as_util_hook(get, NULL, rec, name);
517  return as_string_fromval(v);
518 }
519 
520 /**
521  * Get a bin's value as an as_geojson.
522  *
523  * @param rec The as_rec to read the bin value from.
524  * @param name The name of the bin.
525  *
526  * @return On success, the value of the bin. Otherwise NULL.
527  *
528  * @relatesalso as_rec
529  */
530 static inline as_geojson * as_rec_get_geojson(const as_rec * rec, const char * name)
531 {
532  as_val * v = as_util_hook(get, NULL, rec, name);
533  return as_geojson_fromval(v);
534 }
535 
536 /**
537  * Get a bin's value as an as_bytes.
538  *
539  * @param rec The as_rec to read the bin value from.
540  * @param name The name of the bin.
541  *
542  * @return On success, the value of the bin. Otherwise NULL.
543  *
544  * @relatesalso as_rec
545  */
546 static inline as_bytes * as_rec_get_bytes(const as_rec * rec, const char * name)
547 {
548  as_val * v = as_util_hook(get, NULL, rec, name);
549  return as_bytes_fromval(v);
550 }
551 
552 /**
553  * Get a bin's value as an as_list.
554  *
555  * @param rec The as_rec to read the bin value from.
556  * @param name The name of the bin.
557  *
558  * @return On success, the value of the bin. Otherwise NULL.
559  *
560  * @relatesalso as_rec
561  */
562 static inline as_list * as_rec_get_list(const as_rec * rec, const char * name)
563 {
564  as_val * v = as_util_hook(get, NULL, rec, name);
565  return as_list_fromval(v);
566 }
567 
568 /**
569  * Get a bin's value as an as_map.
570  *
571  * @param rec The as_rec to read the bin value from.
572  * @param name The name of the bin.
573  *
574  * @return On success, the value of the bin. Otherwise NULL.
575  *
576  * @relatesalso as_rec
577  */
578 static inline as_map * as_rec_get_map(const as_rec * rec, const char * name)
579 {
580  as_val * v = as_util_hook(get, NULL, rec, name);
581  return as_map_fromval(v);
582 }
583 
584 /******************************************************************************
585  * BIN SETTER FUNCTIONS
586  ******************************************************************************/
587 
588 /**
589  * Set the bin's value to an as_val.
590  *
591  * @param rec The as_rec to write the bin value to - CONSUMES REFERENCE
592  * @param name The name of the bin.
593  * @param value The value of the bin.
594  *
595  * @return On success, 0. Otherwise an error occurred.
596  *
597  * @relatesalso as_rec
598  */
599 static inline int as_rec_set(const as_rec * rec, const char * name, const as_val * value)
600 {
601  return as_util_hook(set, 1, rec, name, value);
602 }
603 
604 /**
605  * Set the bin's value to an int64_t.
606  *
607  * @param rec The as_rec storing the bin.
608  * @param name The name of the bin.
609  * @param value The value of the bin.
610  *
611  * @return On success, 0. Otherwise an error occurred.
612  *
613  * @relatesalso as_rec
614  */
615 static inline int as_rec_set_int64(const as_rec * rec, const char * name, int64_t value)
616 {
617  return as_util_hook(set, 1, rec, name, (as_val *) as_integer_new(value));
618 }
619 
620 /**
621  * Set the bin's value to a double.
622  *
623  * @param rec The as_rec storing the bin.
624  * @param name The name of the bin.
625  * @param value The value of the bin.
626  *
627  * @return On success, 0. Otherwise an error occurred.
628  *
629  * @relatesalso as_rec
630  */
631 static inline int as_rec_set_double(const as_rec * rec, const char * name, double value)
632 {
633  return as_util_hook(set, 1, rec, name, (as_val *) as_double_new(value));
634 }
635 
636 /**
637  * Set the bin's value to a NULL terminated string.
638  *
639  * @param rec The as_rec storing the bin.
640  * @param name The name of the bin.
641  * @param value The value of the bin.
642  *
643  * @return On success, 0. Otherwise an error occurred.
644  *
645  * @relatesalso as_rec
646  */
647 static inline int as_rec_set_str(const as_rec * rec, const char * name, const char * value)
648 {
649  return as_util_hook(set, 1, rec, name, (as_val *) as_string_new_strdup(value));
650 }
651 
652 /**
653  * Set the bin's value to an as_integer.
654  *
655  * @param rec The as_rec storing the bin.
656  * @param name The name of the bin.
657  * @param value The value of the bin.
658  *
659  * @return On success, 0. Otherwise an error occurred.
660  *
661  * @relatesalso as_rec
662  */
663 static inline int as_rec_set_integer(const as_rec * rec, const char * name, const as_integer * value)
664 {
665  return as_util_hook(set, 1, rec, name, (as_val *) value);
666 }
667 
668 /**
669  * Set the bin's value to an as_double.
670  *
671  * @param rec The as_rec storing the bin.
672  * @param name The name of the bin.
673  * @param value The value of the bin.
674  *
675  * @return On success, 0. Otherwise an error occurred.
676  *
677  * @relatesalso as_rec
678  */
679 static inline int as_rec_set_as_double(const as_rec * rec, const char * name, const as_double * value)
680 {
681  return as_util_hook(set, 1, rec, name, (as_val *) value);
682 }
683 
684 /**
685  * Set the bin's value to an as_string.
686  *
687  * @param rec The as_rec storing the bin.
688  * @param name The name of the bin.
689  * @param value The value of the bin.
690  *
691  * @return On success, 0. Otherwise an error occurred.
692  *
693  * @relatesalso as_rec
694  */
695 static inline int as_rec_set_string(const as_rec * rec, const char * name, const as_string * value)
696 {
697  return as_util_hook(set, 1, rec, name, (as_val *) value);
698 }
699 
700 /**
701  * Set the bin's value to an as_geojson.
702  *
703  * @param rec The as_rec storing the bin.
704  * @param name The name of the bin.
705  * @param value The value of the bin.
706  *
707  * @return On success, 0. Otherwise an error occurred.
708  *
709  * @relatesalso as_rec
710  */
711 static inline int as_rec_set_geojson(const as_rec * rec, const char * name, const as_geojson * value)
712 {
713  return as_util_hook(set, 1, rec, name, (as_val *) value);
714 }
715 
716 /**
717  * Set the bin's value to an as_bytes.
718  *
719  * @param rec The as_rec storing the bin.
720  * @param name The name of the bin.
721  * @param value The value of the bin.
722  *
723  * @return On success, 0. Otherwise an error occurred.
724  *
725  * @relatesalso as_rec
726  */
727 static inline int as_rec_set_bytes(const as_rec * rec, const char * name, const as_bytes * value)
728 {
729  return as_util_hook(set, 1, rec, name, (as_val *) value);
730 }
731 
732 /**
733  * Set the bin's value to an as_list.
734  *
735  * @param rec The as_rec storing the bin.
736  * @param name The name of the bin.
737  * @param value The value of the bin.
738  *
739  * @return On success, 0. Otherwise an error occurred.
740  *
741  * @relatesalso as_rec
742  */
743 static inline int as_rec_set_list(const as_rec * rec, const char * name, const as_list * value)
744 {
745  return as_util_hook(set, 1, rec, name, (as_val *) value);
746 }
747 
748 /**
749  * Set the bin's value to an as_map.
750  *
751  * @param rec The as_rec storing the bin.
752  * @param name The name of the bin.
753  * @param value The value of the bin.
754  *
755  * @return On success, 0. Otherwise an error occurred.
756  *
757  * @relatesalso as_rec
758  */
759 static inline int as_rec_set_map(const as_rec * rec, const char * name, const as_map * value)
760 {
761  return as_util_hook(set, 1, rec, name, (as_val *) value);
762 }
763 
764 /******************************************************************************
765  * ITERATION FUNCTIONS
766  ******************************************************************************/
767 
768 /**
769  * Call the callback function for each bin in the record.
770  *
771  * @param rec The as_rec containing the bins to iterate over.
772  * @param callback The function to call for each entry.
773  * @param udata User-data to be passed to the callback.
774  *
775  * @return true if iteration completes fully. false if iteration was aborted.
776  *
777  * @relatesalso as_rec
778  */
779 static inline bool as_rec_foreach(const as_rec * rec, as_rec_foreach_callback callback, void * udata)
780 {
781  return as_util_hook(foreach, false, rec, callback, udata);
782 }
783 
784 /******************************************************************************
785  * CONVERSION FUNCTIONS
786  ******************************************************************************/
787 
788 /**
789  * Convert to an as_val.
790  *
791  * @relatesalso as_rec
792  */
793 static inline as_val * as_rec_toval(const as_rec * rec)
794 {
795  return (as_val *) rec;
796 }
797 
798 /**
799  * Convert from an as_val.
800  *
801  * @relatesalso as_rec
802  */
803 static inline as_rec * as_rec_fromval(const as_val * v)
804 {
805  return as_util_fromval(v, AS_REC, as_rec);
806 }
807 
808 /******************************************************************************
809  * as_val FUNCTIONS
810  ******************************************************************************/
811 
812 /**
813  * @private
814  * Internal helper function for destroying an as_val.
815  */
816 void as_rec_val_destroy(as_val *);
817 
818 /**
819  * @private
820  * Internal helper function for getting the hashcode of an as_val.
821  */
822 uint32_t as_rec_val_hashcode(const as_val *v);
823 
824 /**
825  * @private
826  * Internal helper function for getting the string representation of an as_val.
827  */
828 char * as_rec_val_tostring(const as_val *v);
829 
830 #ifdef __cplusplus
831 } // end extern "C"
832 #endif