dtl
Category: utilities | Component type: type |
The variant_field class provides a mechanism to access data fields within a variant_row. variant_field is designed to hold values of arbitrary types. In addition variant_field provides the ability for users to cast values between types and assign values back to the variant_row that created a given variant object. This class is used primarily by dynamic queries where the number and the types of the fields returned by a query are unknown.
Defined in the variant_row.h header file.
None.
variant_row, TypeTranslation.
// Manipulating fields in a variant_row
void variant_row_example(void) {
TIMESTAMP_STRUCT test_date = {1999, 9, 29, 0, 0, 0, 0};
vector<TypeTranslation> types;
vector<string> names;
int i;
string s;
TypeTranslation vt0=TypeTranslation(typeid(int).name(), C_INT, SQL_INTEGER, SQL_C_SLONG,
TypeTranslation::TYPE_PRIMITIVE, sizeof(int)),
vt1=TypeTranslation(typeid(string).name(), C_STRING, SQL_VARCHAR, SQL_C_CHAR,
TypeTranslation::TYPE_COMPLEX, sizeof(string));
types.push_back(vt0);
names.push_back("int");
types.push_back(vt1);
names.push_back("string");
variant_row r(types, names);
r["int"] = (int)r["int"] + 5;
i = (int)r["int"];
s = (string) r["int"];
r["int"] = test_date;
s = (string) r["int"];// For gcc will need to call get_string() method here
// Print out the column names
vector<string> colNames = r.GetNames();
for (vector<string>::iterator name_it = colNames.begin(); name_it != colNames.end(); name_it++)
{
cout << (*name_it) << " ";
}
cout << endl;
// Print out all column values
for (i = 0; i < r.size(); i++)
cout << r[i] << " ";
cout << endl;
};
// Using a DynamicDBView to insert records into the database.
// this example also shows how to set NULL fields in a variant_row
// Insert two rows into a table with unknown fields
void SimpleDynamicWrite() {
TIMESTAMP_STRUCT paramDate = {2012, 12, 23, 0, 0, 0, 0};
// Mayan DOOMSDAY! End of the Mayan 5126 year long calendar cycle starting from May 1, 3094 B.C.
// Date is 13.13.13.0.0.0.0 4 Ahaw, 3 K'ank'in
DynamicDBView<> view("DB_EXAMPLE", "*");
DynamicDBView<>::insert_iterator write_it = view;
// NOTE: We need to construct r from the view itself since we
// don't know what fields the table will contain.
// We therefore make a call to the DataObj() function to have the
// table return us a template row with the correct number of fields
// and field types.
variant_row r(view.GetDataObj());
// Prepare the number of the beast!
// Set all fields to the value 6,
// except for the last column which is a date and cannot
// currently accept numeric values
for (size_t i = 0; i < r.size()-1; i++)
{
r[i] = 6;
}
r[i] = paramDate; // set the Doomsdate
// insert the number
*write_it = r;
write_it++;
// Prepare the number of angels who stand before
// the throne of God!
// Set all fields to the value 7,
// except for the last column which is a date and cannot
// currently accept numeric values
for (i = 0; i < r.size()-1; i++)
{
r[i] = 7;
}
r[i] = paramDate;
// insert the number
*write_it = r;
write_it++;
// Insert Purgatory (the void) into the database.
// Set all fields to NULL
for (i = 0; i < r.size()-1; i++)
{
r[i] = NullField();
}
r[i] = NullField();
// insert the number
*write_it = r;
write_it++;
// For more on this example - see the *REAL* DTL homepage!
}
None.
X | A type that is a model of variant_field |
a | Object of type X |
Name | Expression | Precondition | Semantics | Postcondition |
---|---|---|---|---|
Default constructor |
X a() |
Creates an empty variant_field. The type and variant_row parent pointer is not set so an empty variant_field cannot be used until is has been copy or assignment constructed from a variant_row class. | The row is empty. | |
Copy constructor |
X a(const X &b) |
Creates a variant_field to hold an arbitrary type with the given variant_row parent specified in b. The types, and values stored in b are copied into a. | The row is initialized to be able to hold the types and values given in b. The data held in b is copied to a. | |
Assignment operator |
variant_field & operator=(const variant_field &b) |
Assigns a variant_field to hold an arbitrary type with the given variant_row parent specified in b. The types, and values stored in b are copied into a. | The row is initialized to be able to hold the types and values given in b. The data held in b is copied to a. | |
Assign data to a variant_field |
template<typename T> const variant_field & operator=(const T &other) |
Assigns a value to a variant_field. The field's type information is updated to reflect the type of the object passed in and the value of the object is copied to the field's internal data. IN ADDITION, THE NEW VALUE HELD BY THE FIELD IS COPIED BACK TO THE PARENT variant_row. So, if the parent variant_row requires a string for the given field, when a copy operation to the variant_row is attempted, first the data will be cast to a string, then that string data will be copied into the variant_row data. This allows for transparent and type-safe assignment into the variant_row object. This copy process is internal to the variant_row object. For example, if the source variant_field object contains a double but the target variant_row field requires a string any casts done to obtain a string will be internal to variant_row and will not affect the data or type held by the variant_field object. There are some restrictions, see [1]. | ||
Cast operator |
template <class T> operator T() |
Casts the variant data held in the class to a desired target type. Thus, the class might hold a string as its variant data, but we want to cast it to a double. Suppose a is a variant_field that holds a string as its internal data. The expresssion (double) a will try to convert the string held internally into a number to return. There are some restrictions, see [1]. Note also that when casting a variant field to a string we recommend you call the get_string() method since gcc gives an ambiguity error if you just try to cast the field value directly. | ||
Determine if field holds a NULL value |
bool IsNull() |
Returns true if the data held by the field represents a NULL value. | ||
Get an enumerated value listing the type of data held by the field |
char type() |
Returns an enumeration listing the type of the data held
by the variant_field. This enumeration
is listed in bind_basics.h as follows, but is subject to
change so check this file for the latest version:
// short, unsigned short, int, unsigned
int, long, unsigned long |
||
Test if the value held by the field matches a particular type |
template<typename T> bool is_type() |
This method can be used to test if this variant_field holds a value of type T. It takes no arguments, so it can only be used with explicit template instantiation, e.g.: if ( a.is_type<int>() ) |
||
Steam operator |
ostream &operator<<(ostream &o, const variant_field &vf) |
Stream the value held by the variant_field to a standard ostream. | ||
Null check | bool IsNull() | Is this field null? | ||
Set field to null | void SetNull() | Set this field to null | ||
Make field non-null | void ClearNull() | Make this field non-null. | ||
Null field assignment | const variant_field &operator=(const NullField &null) |
Convenience assignment operator to set the destination field to null. Gives clean syntax to make a field have the null value, as in: var_row[fieldName] = NullField(); Essentially equivalent to SetNull(). |
||
Is null comparison |
bool operator==(const NullField &null) friend bool operator==(const NullField &null, const variant_field &vf) |
Returns whether the given field is null. Equivalent to a call to IsNull(). | ||
Is not null comparison |
bool operator!=(const NullField &null) friend bool operator!=(const NullField &null, const variant_field &vf) |
Returns whether the given field is non-null. Equivalent to a call to !IsNull(). |
[1] The allowable types that can be assigned into and cast from variant_field is currently a limited set of types covering the common data types seen in SQL data fields. See variant.h and bind_basics.h for the current list of types supported by this class.
variant_row, DynamicDBView, DynamicIndexedDBView
Copyright © 2002, Michael Gradman and Corwin Joy.
Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Corwin Joy and Michael Gradman make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.