StreamBase C++ API 10.3.0.4

- Main Page
- Related Pages
- Classes
- Files

- File List

Tuple.hpp
1 // Copyright (c) 2004-2018 Cloud Software Group, Inc. All rights reserved.
2
3 #ifndef STREAMBASE_TUPLE_H
4 #define STREAMBASE_TUPLE_H
5
6 #include "StreamBase.hpp"
7
8 #include "Timestamp.hpp"
9 #include "Schema.hpp"
10 #include "Field.hpp"
11 #include "Exceptions.hpp"
12 #include "Errors.hpp"
13 #include <NMSTL/platform.hpp>
14 #include <streambase/impl/Memory.hpp>
15 #include "TuplePrivate.hpp"
16 #include "TupleExceptions.hpp"
17 #include "FieldValue.hpp"
18
19 #ifdef WIN32
20 #pragma warning( push )
21 #pragma warning(disable:4127)
22 #endif
23
24 SB_INTERNAL_FWD(TupleUtil);
25 SB_INTERNAL_FWD(Errors);
26
27 SB_NAMESPACE_BEGIN;
28
29 class Tuple;
30 class Function;
31
32
33 template <typename T>
34 T Tuple_do_get(const Tuple& tuple, const Field &field);
35 template <typename T>
36 void Tuple_do_set(Tuple& tuple, const Field &field, T value);
37
38 /**
39 * Tuples are value types that can be copied and modified separately thus
40 *
41 * t2 = t1;<br>
42 * t2.setId(0); // does not modify t1
43 *
44 * They will only make copies of the underlying data as needed, so
45 * they are relatively cheap to pass around by value
46 */
47 class Tuple {
48 public:
49 Tuple();
50
51 /// Copy constructor
52 Tuple(const Tuple& t);
53
54 /// Construct a tuple of the specified schema
55 Tuple(const Schema& s);
56
57 /// Destructor
58 ~Tuple();
59
60 const Tuple& operator=(const Tuple& rhs);
61
62 bool operator==(const Tuple& rhs) const;
63
64 /** verify that the tuple is valid
65 * Throws StreamBaseException on invalid tuple */
66 void verify() const;
67
68 /** null all fields in the tuple */
69 void clear() {
70 if(!getSchema()) { return; }
71 for(size_t i = 0; i < getNumFields(); ++i) {
72 setNull(i);
73 }
74 }
75
76 /** @return the schema */
77 const Schema &getSchema() const;
78 /** set the schema */
79 void setSchema(const Schema &);
80
81 /** @return the number of fields in the tuple's schema */
82 size_t getNumFields() const {
83 const Schema& s = getSchema();
84 return s ? s.getNumFields() : 0;
85 }
86
87 /** @return the serialized size of this tuple */
88 size_t getSize() const;
89
90 /** Flags that can be passed to setString(). TRUNCATE: starting in StreamBase 6.3 the
91 * string type does not have a declared length and strings are never truncated.
92 */
93 enum Flags {
94 NONE = 0,
95 TRUNCATE = 1
96 };
97
98
99 //@{
100 /** Return the value of the given field of type T. T must be one of
101 * string, int, double, bool, long, or Timestamp, and correspond to the
102 * field's actual type.
103 *
104 * The Field objects used to set and get Tuple field values must be
105 * obtained via the Tuple's Schema object. A Schema.Field object that has
106 * been created by the user or retrieved from a different Schema may not work.
107 *
108 * @return the value of the field. */
109 template <typename T> T get(const Field &f) const {
110 return Tuple_do_get<T>(*this, f);
111 }
112 template <typename T> T get(size_t i) const {
113 return get<T>(getSchema().getField(i));
114 }
115 template <typename T> T get(const std::string &field_name) const {
116 return get<T>(getSchema().getField(field_name));
117 }
118 //@}
119
120 //@{
121 /** Set a field to a specific value. Supported values are string,
122 * int, double, bool and Timestamp. field must be a of a matching
123 * DataType.
124 *
125 * The Field objects used to set and get Tuple field values must be
126 * obtained via the Tuple's Schema object. A Schema.Field object that has
127 * been created by the user or retrieved from a different Schema may not work.
128 */
129 template <typename T> void set(const Field &field, T value) {
130 return Tuple_do_set<T>(*this, field, value);
131 }
132 template <typename T> void set(int fieldNum, T value) {
133 set(getSchema().getField(fieldNum), value);
134 }
135 template <typename T> void set(const std::string &field_name, T value) {
136 set(getSchema().getField(field_name), value);
137 }
138 //@}
139
140 //@{
141 /** Test the null setting for field f
142 *
143 * The Field objects used to set and get Tuple field values must be
144 * obtained via the Tuple's Schema object. A Schema.Field object that has
145 * been created by the user or retrieved from a different Schema may not work.
146 *
147 * @return true if field is null, false otherwise */
148 bool isNull(const Field &f) const;
149 bool isNull(size_t i) const {
150 return isNull(getSchema().getField(i));
151 }
152 bool isNull(const std::string& n) const {
153 return isNull(getSchema().getField(n));
154 }
155 //@}
156
157 //@{
158 /** Set the null setting for field f
159 *
160 * The Field objects used to set and get Tuple field values must be
161 * obtained via the Tuple's Schema object. A Schema.Field object that has
162 * been created by the user or retrieved from a different Schema may not work.
163 */
164 void setNull(const Field &f);
165 void setNull(size_t i) { setNull(getSchema().getField(i)); }
166 void setNull(const std::string& n) { setNull(getSchema().getField(n)); }
167 //@}
168
169
170 //@{
171 /** Return the value of a Boolean field.
172 *
173 * The Field objects used to set and get Tuple field values must be
174 * obtained via the Tuple's Schema object. A Schema.Field object that has
175 * been created by the user or retrieved from a different Schema may not work.
176 *
177 * @return the Boolean value. */
178 bool getBool(const Field &f) const;
179 bool getBool(size_t i) const {
180 return getBool(getSchema().getField(i));
181 }
182 bool getBool(const std::string& n) const {
183 return getBool(getSchema().getField(n));
184 }
185 //@}
186
187 //@{
188 /** Set the value of a Boolean field.
189 *
190 * The Field objects used to set and get Tuple field values must be
191 * obtained via the Tuple's Schema object. A Schema.Field object that has
192 * been created by the user or retrieved from a different Schema may not work.
193 */
194 void setBool(const Field &f, bool v);
195 void setBool(size_t i, bool v) {
196 setBool(getSchema().getField(i), v);
197 }
198 void setBool(const std::string& n, bool v) {
199 setBool(getSchema().getField(n), v);
200 }
201 //@}
202
203
204 //@{
205 /** Return the value of an int field.
206 *
207 * The Field objects used to set and get Tuple field values must be
208 * obtained via the Tuple's Schema object. A Schema.Field object that has
209 * been created by the user or retrieved from a different Schema may not work.
210 *
211 * @return the int value. */
212 int getInt(const Field &f) const;
213 int getInt(size_t i) const {
214 return getInt(getSchema().getField(i));
215 }
216 int getInt(const std::string& n) const {
217 return getInt(getSchema().getField(n));
218 }
219 //@}
220
221 //@{
222 /** Set the value of an integer field.
223 *
224 * The Field objects used to set and get Tuple field values must be
225 * obtained via the Tuple's Schema object. A Schema.Field object that has
226 * been created by the user or retrieved from a different Schema may not work.
227 */
228 void setInt(const Field &f, int v);
229 void setInt(size_t i, int v) {
230 setInt(getSchema().getField(i), v);
231 }
232 void setInt(const std::string& n, int v) {
233 setInt(getSchema().getField(n), v);
234 }
235 //@}
236
237
238 //@{
239 /** Return the value of a long field.
240 *
241 * The Field objects used to set and get Tuple field values must be
242 * obtained via the Tuple's Schema object. A Schema.Field object that has
243 * been created by the user or retrieved from a different Schema may not work.
244 *
245 * @return the long value. */
246 long long getLong(const Field &f) const;
247 long long getLong(size_t i) const {
248 return getLong(getSchema().getField(i));
249 }
250 long long getLong(const std::string& n) const {
251 return getLong(getSchema().getField(n));
252 }
253 //@}
254
255 //@{
256 /** Set the value of a long field.
257 *
258 * The Field objects used to set and get Tuple field values must be
259 * obtained via the Tuple's Schema object. A Schema.Field object that has
260 * been created by the user or retrieved from a different Schema may not work.
261 */
262 void setLong(const Field &f, long long v);
263 void setLong(size_t i, long long v) {
264 setLong(getSchema().getField(i), v);
265 }
266 void setLong(const std::string& n, long long v) {
267 setLong(getSchema().getField(n), v);
268 }
269 //@}
270
271
272 //@{
273 /** Return the value of a double field.
274 *
275 * The Field objects used to set and get Tuple field values must be
276 * obtained via the Tuple's Schema object. A Schema.Field object that has
277 * been created by the user or retrieved from a different Schema may not work.
278 *
279 * @return the double value. */
280 double getDouble(const Field &f) const;
281 double getDouble(size_t i) const {
282 return getDouble(getSchema().getField(i));
283 }
284 double getDouble(const std::string& n) const {
285 return getDouble(getSchema().getField(n));
286 }
287 //@}
288
289 //@{
290 /** Set the value of a double field.
291 *
292 * The Field objects used to set and get Tuple field values must be
293 * obtained via the Tuple's Schema object. A Schema.Field object that has
294 * been created by the user or retrieved from a different Schema may not work.
295 */
296 void setDouble(const Field &f, double v);
297 void setDouble(size_t i, double v) {
298 setDouble(getSchema().getField(i), v);
299 }
300 void setDouble(const std::string& n, double v) {
301 setDouble(getSchema().getField(n), v);
302 }
303 //@}
304
305
306 //@{
307 /** Return the value of a Timestamp field.
308 *
309 * The Field objects used to set and get Tuple field values must be
310 * obtained via the Tuple's Schema object. A Schema.Field object that has
311 * been created by the user or retrieved from a different Schema may not work.
312 *
313 * @return the Timestamp value. */
314 Timestamp getTimestamp(const Field &f) const;
315 Timestamp getTimestamp(size_t i) const {
316 return getTimestamp(getSchema().getField(i));
317 }
318 Timestamp getTimestamp(const std::string& n) const {
319 return getTimestamp(getSchema().getField(n));
320 }
321 //@}
322
323 //@{
324 /** Set the value of a Timestamp field.
325 *
326 * The Field objects used to set and get Tuple field values must be
327 * obtained via the Tuple's Schema object. A Schema.Field object that has
328 * been created by the user or retrieved from a different Schema may not work.
329 */
330 void setTimestamp(const Field &f, const Timestamp& v);
331 void setTimestamp(size_t i, const Timestamp& v) {
332 setTimestamp(getSchema().getField(i), v);
333 }
334 void setTimestamp(const std::string& n, const Timestamp& v) {
335 setTimestamp(getSchema().getField(n), v);
336 }
337 //@}
338
339
340
341 //@{
342 /** Return the value of a BLOB field.
343 *
344 * The Field objects used to set and get Tuple field values must be
345 * obtained via the Tuple's Schema object. A Schema.Field object that has
346 * been created by the user or retrieved from a different Schema may not work.
347 *
348 * @return the BLOB value. */
349 const std::string& getBlobBuffer(const Field &f) const;
350 const std::string& getBlobBuffer(size_t i) const {
351 return getBlobBuffer(getSchema().getField(i));
352 }
353 const std::string& getBlobBuffer(const std::string& n) const {
354 return getBlobBuffer(getSchema().getField(n));
355 }
356 //@}
357
358 //@{
359 /** Set the value of a BLOB field.
360 *
361 * The Field objects used to set and get Tuple field values must be
362 * obtained via the Tuple's Schema object. A Schema.Field object that has
363 * been created by the user or retrieved from a different Schema may not work.
364 */
365 void setBlobBuffer(const Field &f, const std::string& v);
366 void setBlobBuffer(size_t i, const std::string& v) {
367 setBlobBuffer(getSchema().getField(i), v);
368 }
369 void setBlobBuffer(const std::string& n, const std::string& v) {
370 setBlobBuffer(getSchema().getField(n), v);
371 }
372 //@}
373
374
375 //@{
376 /** Return the value of a LIST field.
377 *
378 * The Schema::Field objects used to set and get Tuple field values must be
379 * obtained via the Tuple's Schema object. A Schema.Field object that has
380 * been created by the user or retrieved from a different Schema may not work.
381 *
382 * @return the LIST value. */
383 const std::vector<FieldValue>& getList(const Schema::Field &f) const;
384 const std::vector<FieldValue>& getList(size_t i) const {
385 return getList(getSchema().getField(i));
386 }
387 const std::vector<FieldValue>& getList(const std::string& n) const {
388 return getList(getSchema().getField(n));
389 }
390 //@}
391
392 //@{
393 /** Set the value of a LIST field.
394 *
395 * The Schema::Field objects used to set and get Tuple field values must be
396 * obtained via the Tuple's Schema object. A Schema.Field object that has
397 * been created by the user or retrieved from a different Schema may not work.
398 */
399 void setList(const Schema::Field &f, const std::vector<FieldValue>& v);
400 void setList(size_t i, const std::vector<FieldValue>& v) {
401 setList(getSchema().getField(i), v);
402 }
403 void setList(const std::string& n, const std::vector<FieldValue>& v) {
404 setList(getSchema().getField(n), v);
405 }
406 //@}
407
408 //@{
409 /** Return the value of a string field.
410 *
411 * The Field objects used to set and get Tuple field values must be
412 * obtained via the Tuple's Schema object. A Schema.Field object that has
413 * been created by the user or retrieved from a different Schema may not work.
414 *
415 * @return the string value. */
416 const std::string& getString(const Field &f) const;
417 const std::string& getString(size_t i) const {
418 return getString(getSchema().getField(i));
419 }
420 const std::string& getString(const std::string& n) const {
421 return getString(getSchema().getField(n));
422 }
423 //@}
424
425
426 //@{
427 /** Set the value of a string field.
428 *
429 * The Field objects used to set and get Tuple field values must be
430 * obtained via the Tuple's Schema object. A Schema.Field object that has
431 * been created by the user or retrieved from a different Schema may not work.
432 */
433 void setString(const Field &field,
434 const std::string &value, Flags flags = NONE);
435 void setString(size_t field,
436 const char* data, size_t len, Flags flags = NONE) {
437 setString(field, std::string(data, len), flags);
438 }
439 void setString(const std::string& field,
440 const char* data, size_t len, Flags flags = NONE) {
441 setString(field, std::string(data, len), flags);
442 }
443 void setString(const Field& field,
444 const char* data, size_t len, Flags flags = NONE) {
445 setString(field, std::string(data, len), flags);
446 }
447 void setString(size_t field_index,
448 const std::string &value, Flags flags = NONE) {
449 setString(getSchema().getField(field_index), value, flags);
450 }
451 void setString(const std::string& field_name,
452 const std::string& value, Flags flags = NONE) {
453 setString(getSchema().getField(field_name), value, flags);
454 }
455 //@}
456
457
458 //@{
459 /** Return the value of a nested tuple field.
460 *
461 * The Field objects used to set and get Tuple field values must be
462 * obtained via the Tuple's Schema object. A Schema.Field object that has
463 * been created by the user or retrieved from a different Schema may not work.
464 *
465 * @return the nested tuple value. */
466 const Tuple& getTuple(const Field &f) const;
467 const Tuple& getTuple(size_t i) const {
468 return getTuple(getSchema().getField(i));
469 }
470 const Tuple& getTuple(const std::string& n) const {
471 return getTuple(getSchema().getField(n));
472 }
473 //@}
474
475 //@{
476 /** Return the value of a function field.
477 *
478 * The Field objects used to set and get Tuple field values must be
479 * obtained via the Tuple's Schema object. A Schema.Field object that has
480 * been created by the user or retrieved from a different Schema may not work.
481 *
482 * @return the function value.
483 */
484 const Function& getFunction(const Field& f) const;
485 const Function& getFunction(size_t i) const {
486 return getFunction(getSchema().getField(i));
487 }
488 const Function& getFunction(const std::string& n) const {
489 return getFunction(getSchema().getField(n));
490 }
491 //@}
492
493 private:
494 Tuple& getTupleMutable(const Field &f);
495
496 public:
497
498 //@{
499 /** Set the value of a nested tuple field.
500 *
501 * The Field objects used to set and get Tuple field values must be
502 * obtained via the Tuple's Schema object. A Schema.Field object that has
503 * been created by the user or retrieved from a different Schema may not work.
504 */
505 void setTuple(const Field &f, const Tuple& v);
506 void setTuple(size_t i, const Tuple& v) {
507 setTuple(getSchema().getField(i), v);
508 }
509 void setTuple(const std::string& n, const Tuple& v) {
510 setTuple(getSchema().getField(n), v);
511 }
512 //@}
513
514 //@{
515 /**
516 * Set the value of a function field
517 *
518 * The Field objects used to set and get Tuple field values must be
519 * obtained via the Tuple's Schema object. A Schema.Field object that has
520 * been created by the user or retrieved from a different Schema may not work.
521 */
522 void setFunction(const Field& f, const Function& v);
523 void setFunction(size_t i, const Function& v) {
524 setFunction(getSchema().getField(i), v);
525 }
526 void setFunction(const std::string& n, const Function& v) {
527 setFunction(getSchema().getField(n), v);
528 }
529 //@}
530
531 /// Takes a field with a path and returns the field at the target of that path
532 FieldValue& getFieldValue(const Field& f);
533 /// Takes a field with a path and returns the field at the target of that path
534 const FieldValue& getFieldValue(const Schema::Field& f) const;
535
536 /// Takes the index of a field in this tuple's schema, returns the corresponding
537 /// field value.
538 FieldValue& getFieldValue(size_t field_num);
539 /// Takes the index of a field in this tuple's schema, returns the corresponding
540 /// field value.
541 const FieldValue& getFieldValue(size_t field_num) const;
542
543 /// Takes the name of a field in this tuple's schema, returns the corresponding
544 /// field value.
545 FieldValue& getFieldValue(const std::string& field_name);
546 /// Takes the name of a field in this tuple's schema, returns the corresponding
547 /// field value.
548 const FieldValue& getFieldValue(const std::string& field_name) const;
549
550 /// Takes a field with a path and sets the value of the field at the target of
551 /// that path to that of the provided FieldValue.
552 void setFieldValue(const Field& f, const FieldValue& fv);
553 /// Takes the index of a field in this tuple's schema and sets the corresponding
554 /// field value.
555 void setFieldValue(size_t field_num, const FieldValue& fv);
556 /// Takes the name of a field in this tuple's schema and sets the corresponding
557 /// field value.
558 void setFieldValue(const std::string& field_name, const FieldValue& fv);
559
560
561 /** @return true if tuple has a header, false otherwise */
562 bool hasHeader() const { return getSchema().hasHeader(); }
563
564
565 /** @return The id for this tuple */
566 unsigned int getId() const;
567 /** set the id */
568 void setId(unsigned int tid);
569
570 /** Return a human-readable string value representing this tuple
571 * in its entirety (including all header values, if applicable).
572 * @return the string value. */
573 std::string as_string() const;
574
575 /** Return a human-readable string value representing this tuple.
576 * It compares to as_string by allowing a user-specified delimiter
577 * between fields, making the header timestamp stand out, and
578 * omitting the TupleId header field.
579 * null_string is written out for any null field.
580 * @return the string value */
581 std::string as_string_external(char delimiter = ',',
582 const std::string& null_string = getNullString()) const;
583
584 /** Return a string value representing this tuple, separated by
585 * the given delimiter.
586 *
587 * @param delimiter the string to put between fields
588 * @param null_string the string used to represent null values
589 * @param include_names whether to preface each field with "<name>="
590 * @param quote_all_strings whether to put quotes around all strings,
591 * regardless of need
592 *
593 * @return the result string
594 */
595 std::string toDelimitedString(const std::string &delimiter,
596 const std::string& null_string = getNullString(),
597 bool include_names = false, bool quote_all_strings = false) const;
598
599 #ifndef DOXYGEN_INTERNAL_ONLY
600 /** Generates a CSV string with a column for each field in the tuple.
601 * null_string is written out for any null field. */
602 void writeCSVString(std::ostream& out, char delim, char quote,
603 const std::string& null_string = getNullString()) const;
604 #endif
605
606 /** Return the default string used to represent null, i.e., null. */
607 static const std::string& getNullString() {
608 static std::string NULL_STRING = "null";
609 return NULL_STRING;
610 }
611
612 #ifndef DOXYGEN_INTERNAL_ONLY
613 /** @brief copy the tuple into the buffer of the given size
614 * - if the tuple does not fit in the buffer, the required size is
615 * returned and the buffer is left in an undefined state
616 * - otherwise the tuple is copied into the buffer in a packed representation
617 * and the amount of the buffer used is returned
618 *
619 * @param buf the buffer into which to copy data (NULL is a safe value to pass)
620 * @param len the size of the buffer in bytes
621 * @param byteswap whether to swap the bytes coming from the buffer
622 * @return the space required/used to serialize the tuple in bytes
623 * <em>Note: this method is not public API, and is for internal StreamBase use only</em>
624 */
625 size_t copyIntoBuffer(void* buf, size_t len, bool byteswap) const;
626
627 /** Set the contents of this tuple from a buffer containing a packed
628 * representation of a tuple
629 *
630 * @param buf the buffer into which to copy data (NULL is a safe value to pass)
631 * @param buf_len the size of the buffer in bytes
632 * @param byteswap whether to swap the bytes coming from the buffer
633 * @param s the Schema to use
634 * @return the size in bytes used from the buffer
635 */
636 size_t setFromPackedBuffer(
637 const void* buf, size_t buf_len, bool byteswap, const Schema& s);
638
639 static Tuple createFromPackedBuffer(size_t* size_used,
640 const void* buf, size_t buf_len, bool byteswap, const Schema& s);
641 #endif
642
643 private:
644 TIBCO_CEP_memory::shared_ptr<TuplePrivateImpl> _;
645 /// These methods are used to implement copy-on-write
646 /// ensureUnique() should be called as the first line of any non-const method
647 /// ensureAllocated() should be called as the first line of any const method
648 void ensureUnique();
649 void ensureAllocated() const;
650
651 Tuple& resolveField(const Field& f);
652 const Tuple& resolveField(const Field& f) const;
653
654 };
655
656 #define DO_ACCESSOR(type, getter) \
657 template <> inline type Tuple_do_get<type>(const Tuple& t, const Field& f) { return t.get ## getter(f); } \
658 template <> inline void Tuple_do_set<type>(Tuple& t, const Field& f, type v) { return t.set ## getter(f, v); }
659
660 DO_ACCESSOR(bool, Bool)
661 DO_ACCESSOR(int, Int)
662 DO_ACCESSOR(long long, Long)
663 DO_ACCESSOR(double, Double)
664 DO_ACCESSOR(std::string, String)
665 DO_ACCESSOR(Timestamp, Timestamp)
666
667 #undef DO_ACCESSOR
668
669
670 #ifdef WIN32
671 #pragma warning( pop )
672 #endif
673
674 SB_NAMESPACE_END;
675
676 inline std::ostream& operator << (std::ostream& os, const sb::Tuple& tuple) {
677 os << tuple.as_string();
678 return os;
679 }
680
681
682 #endif // TUPLE_H