• Main Page
  • Modules
  • Classes
  • Files
  • File List
  • File Members

DataValue.h

Go to the documentation of this file.
00001 #ifndef _DATAVALUE_H_
00002 #define _DATAVALUE_H_
00003 // 
00004 
00005 //
00006 // Copyright (C) 2004-2007  Autodesk, Inc.
00007 // 
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of version 2.1 of the GNU Lesser
00010 // General Public License as published by the Free Software Foundation.
00011 // 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Lesser General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 //
00021 
00022 #ifdef _WIN32
00023 #pragma once
00024 #endif
00025 
00026 #include <FdoStd.h>
00027 #include <Fdo/Expression/LiteralValue.h>
00028 #include <Fdo/Schema/DataType.h>
00029 #include <Fdo/Expression/ExpressionException.h>
00030 
00031 /// \brief
00032 /// The FdoDataValue class derives from FdoLiteralValue and represents a literal
00033 /// value such as a string or a number.
00034 class FdoDataValue : public FdoLiteralValue
00035 {
00036 /// \cond DOXYGEN-IGNORE
00037     friend class FdoInternalDataValue;
00038     friend class FdoByteValue;
00039     friend class FdoDecimalValue;
00040     friend class FdoDoubleValue;
00041     friend class FdoInt16Value;
00042     friend class FdoInt32Value;
00043     friend class FdoInt64Value;
00044     friend class FdoSingleValue;
00045 protected:
00046     /// \brief
00047     ///  Constructs a default instance of an FdoDataValue with data type string and a
00048     /// value of null.
00049     /// 
00050     /// \return
00051     /// Returns nothing
00052     /// 
00053     FdoDataValue();
00054 /// \endcond
00055 
00056 public:
00057     /// \brief
00058     /// Constructs an instance of a null FdoDataValue using the specified arguments.
00059     /// 
00060     /// \param dataType 
00061     /// Input data type
00062     /// 
00063     /// \return
00064     /// Returns nothing
00065     /// 
00066     FDO_API static FdoDataValue* Create(FdoDataType dataType);
00067 
00068     /// \brief
00069     /// Constructs an instance of an FdoBooleanValue using the specified argument.
00070     /// 
00071     /// \param value 
00072     /// Input a Boolean value
00073     /// 
00074     /// \return
00075     /// Returns an FdoBooleanValue
00076     /// 
00077     FDO_API static FdoDataValue* Create(bool value);
00078 
00079     /// \brief
00080     /// Constructs an instance of an FdoByteValue using the specified argument.
00081     /// 
00082     /// \param value 
00083     /// Input a byte
00084     /// 
00085     /// \return
00086     /// Returns an FdoByteValue
00087     /// 
00088     FDO_API static FdoDataValue* Create(FdoByte value);
00089 
00090     /// \brief
00091     /// Constructs an instance of an FdoDateTimeValue using the specified argument.
00092     /// 
00093     /// \param value 
00094     /// Input a FdoDateTime
00095     /// 
00096     /// \return
00097     /// Returns an FdoDateTimeValue
00098     /// 
00099     FDO_API static FdoDataValue* Create(FdoDateTime value);
00100 
00101     /// \brief
00102     /// Constructs an instance of an FdoDecimalValue or FdoDoubleValue using 
00103     /// the specified arguments.
00104     /// 
00105     /// \param value 
00106     /// Input a double
00107     /// \param dataType 
00108     /// Input a data type
00109     /// 
00110     /// \return
00111     /// Returns an FdoDecimalValue or FdoDoubleValue
00112     /// 
00113     FDO_API static FdoDataValue* Create(double value, FdoDataType dataType);
00114 
00115     /// \brief
00116     /// Constructs an instance of an FdoInt16Value using the specified argument.
00117     /// 
00118     /// \param value 
00119     /// Input a 16 bit integer
00120     /// 
00121     /// \return
00122     /// Returns an FdoInt16Value
00123     /// 
00124     FDO_API static FdoDataValue* Create(FdoInt16 value);
00125 
00126     /// \brief
00127     /// Constructs an instance of an FdoInt32Value using the specified argument.
00128     /// 
00129     /// \param value 
00130     /// Input a 32 bit integer
00131     /// 
00132     /// \return
00133     /// Returns an FdoInt32Value
00134     /// 
00135     FDO_API static FdoDataValue* Create(FdoInt32 value);
00136 
00137     /// \brief
00138     /// Constructs an instance of an FdoInt64Value using the specified argument.
00139     /// 
00140     /// \param value 
00141     /// Input a 64 bit integer
00142     /// 
00143     /// \return
00144     /// Returns an FdoInt64Value
00145     /// 
00146     FDO_API static FdoDataValue* Create(FdoInt64 value);
00147 
00148     /// \brief
00149     /// Constructs an instance of an FdoSingleValue using the specified argument.
00150     /// 
00151     /// \param value 
00152     /// Input a single precision floating point value
00153     /// 
00154     /// \return
00155     /// Returns an FdoSingleValue
00156     /// 
00157     FDO_API static FdoDataValue* Create(float value);
00158 
00159     /// \brief
00160     /// Constructs an instance of an FdoStringValue using the specified argument.
00161     /// 
00162     /// \param value 
00163     /// Input a character string
00164     /// 
00165     /// \return
00166     /// Returns an FdoStringValue
00167     /// 
00168     FDO_API static FdoDataValue* Create(FdoString* value);
00169 
00170     /// \brief
00171     /// Constructs an instance of an FdoBLOBValue or FdoCLOBValue using the specified arguments.
00172     /// 
00173     /// \param value 
00174     /// Input a byte array
00175     /// \param length 
00176     /// Input the length of the byte array
00177     /// \param dataType 
00178     /// Input the type of value to create
00179     /// 
00180     /// \return
00181     /// Returns an FdoBLOBValue or an FdoCLOBValue
00182     /// 
00183     FDO_API static FdoDataValue* Create(FdoByte* value, FdoInt32 length, FdoDataType dataType);
00184 
00185     /// \brief
00186     /// Constructs an instance of an FdoBLOBValue or FdoCLOBValue using the specified arguments.
00187     /// 
00188     /// \param value 
00189     /// Input a byte array
00190     /// \param dataType 
00191     /// Input the type of value to create
00192     /// 
00193     /// \return
00194     /// Returns an FdoBLOBValue or an FdoCLOBValue
00195     /// 
00196     FDO_API static FdoDataValue* Create(FdoByteArray* value, FdoDataType dataType);
00197 
00198     /// \brief
00199     /// Gets the data type of the FdoDataValue.
00200     /// 
00201     /// \return
00202     /// Returns an FdoDataType
00203     /// 
00204     FDO_API virtual FdoDataType GetDataType() = 0;
00205 
00206     /// \brief
00207     /// Returns true if the FdoDataValue represents a null value.
00208     /// 
00209     /// \return
00210     /// Returns true if the FdoDataValue represents a null value
00211     /// 
00212     FDO_API virtual bool IsNull();
00213 
00214     /// \brief
00215     /// Sets the FdoDataValue to a null value of the specified type.
00216     /// 
00217     /// \return
00218     /// Returns nothing
00219     /// 
00220     FDO_API virtual void SetNull();
00221 
00222     /// \brief
00223     /// Gets the literal value type of the FdoDataValue.
00224     /// 
00225     /// \return
00226     /// Returns an FdoLiteralValueType
00227     /// 
00228     FDO_API virtual FdoLiteralValueType GetLiteralValueType () const;
00229 
00230     static FdoDataValue* Create(FdoString* value, FdoDataType dataType);
00231 
00232     // Get the value as an XML format string.
00233     FdoString* GetXmlValue();
00234 
00235 /// \cond DOXYGEN-IGNORE
00236 protected:
00237     /// \brief
00238     /// Compares this data value with another data value
00239     /// 
00240     /// \param other 
00241     /// Input the other data value
00242     /// 
00243     /// \return
00244     /// Returns:
00245     ///     FdoCompareType_Equal when this and the other value are equal or both null.
00246     ///     FdoCompareType_Greater when this value is greater than the other value
00247     ///     FdoCompareType_Less when this value is less than the other value
00248     ///     FdoCompareType_Undefined when these two values cannot be compared. Cases where this happens
00249     ///      are:
00250     ///         - one value is null and the other is not null
00251     ///         - the values have incompatible types (e.g. Int32 and DateTime).
00252     ///         
00253     /// 
00254     FdoCompareType Compare( FdoDataValue* other );
00255 
00256     // ReverseCompare is the same as Compare except for two of the return values:
00257     ///     FdoCompareType_Greater when the other value is greater than this value
00258     ///     FdoCompareType_Less when the other value is less than this value
00259     FdoCompareType ReverseCompare( FdoDataValue* other );
00260 
00261     /// \brief
00262     /// Type-specific comparison function. Each sub-class has its own implementation.
00263     /// 
00264     /// \param other 
00265     /// Input the other data value
00266     /// 
00267     /// \return
00268     /// Returns:
00269     ///     FdoCompareType_Equal when this and the other value are equal or both null.
00270     ///     FdoCompareType_Greater when this value is greater than the other value
00271     ///     FdoCompareType_Less when this value is less than the other value
00272     ///     FdoCompareType_Undefined when these two values cannot be compared. Cases where this happens
00273     ///      are:
00274     ///         - one value is null and the other is not null
00275     ///         - the values have incompatible types (e.g. Int32 and DateTime).
00276     ///
00277     ///     Base implementation always returns FdoCompareType_Undefined.
00278     ///         
00279     /// 
00280     virtual FdoCompareType DoCompare( FdoDataValue* other );
00281 
00282     /// \brief
00283     /// Constructs an instance of an FdoDoubleValue from a double
00284     /// 
00285     /// \param value
00286     /// Input the double value
00287     /// \return
00288     /// Returns an FdoDoubleValue
00289     ///
00290     static FdoDataValue* Create( FdoDouble value );
00291 
00292     /// \brief
00293     /// Constructs an instance of an FdoDataValue from another FdoDataValue.
00294     /// 
00295     /// \param dataType
00296     /// Input the destination type. An FdoDataValue of this type is created. 
00297     /// For more information on how the FdoDataValue is created, see the specific 
00298     /// Create(FdoDataValue* FdoBoolean, FdoBoolean, FdoBoolean ) function for
00299     /// each dataType. For example, if dataType=FdoDataType_Int16, see
00300     /// FdoInt16Value::Create(FdoDataValue* FdoBoolean, FdoBoolean, FdoBoolean )
00301     /// \param src 
00302     /// Input the source (other) FdoDataValue
00303     /// \param nullIfIncompatible 
00304     /// Input will determine what to do if source value type is not compatible with the 
00305     /// this type:
00306     ///     true - return NULL.
00307     ///     false - throw an exception
00308     /// 
00309     /// \param shift 
00310     /// Input will determine what to do if the src value is within the range of 
00311     /// valid values for the destination type but still must be shifted to be a 
00312     /// valid destination type value (e.g. 3.5 must be shifted to convert it from
00313     /// FdoDoubleValue to FdoInt32Value):
00314     ///     true - perform the shift.
00315     ///     false - behaviour depends on nullIfIncompatible:
00316     ///         true - return NULL.
00317     ///         false - throw an exception
00318     /// 
00319     /// \param truncate 
00320     /// Input in the future will determine what to do if source value is outside the
00321     ///  range of valid values for the destination type:
00322     ///     true - convert values less than the minimum to the minimum, 
00323     ///            convert values greater than maximum to the maximum
00324     ///     false - behaviour depends on nullIfIncompatible:
00325     ///         true - return NULL.
00326     ///         false - throw an exception
00327     /// \return
00328     /// Returns an FdoDataValue, whose value is converted from the src value. 
00329     static FdoDataValue* Create(
00330         FdoDataType dataType,
00331         FdoDataValue* src, 
00332         FdoBoolean nullIfIncompatible = false,
00333         FdoBoolean shift = true,
00334         FdoBoolean truncate = false
00335     );
00336 
00337 /* Helper Templates for FdoDataValue::Create( FdoDataType, FdoDataValue*, FdoBoolean, FdoBoolean, FdoBoolean ) */
00338 
00339     // Converts values that may need shifting to other values.
00340     template <class CI,             // input FdoDataValue 
00341               class CO,             // output FdoDataValue
00342               class TI,             // input FDO type - must correspond to CI
00343               class TO              // output FDO type - must correspond to CO
00344     > 
00345     static CO* Convert( 
00346         CI* obj,                            // input FdoDataValue
00347         TI val,                             // input scalar value for obj
00348         TO min,                             // minimum value for TO type
00349         TO max,                             // maximum value for TO type
00350         TI round,                           // amount for rounding 
00351         FdoBoolean nullIfIncompatible,      // see FdoDataValue::Create()
00352         FdoBoolean shift,                   // see FdoDataValue::Create()
00353         FdoBoolean truncate,                // see FdoDataValue::Create()
00354         FdoString* sTO                       // TO in string format; for exception messages.
00355     )
00356     {
00357         CO*         ret = NULL;
00358         FdoBoolean  isNull = false;
00359         TO          out;
00360 
00361         // First, truncate the value to be between output type min and max.
00362         Truncate<TI,TO>( val, out, isNull, min, max, nullIfIncompatible, truncate, sTO );
00363                 
00364         if ( isNull ) 
00365         {
00366             // Output determined to be null
00367             ret = CO::Create();
00368         }
00369         else if ( (val < min) || (val > max) ) 
00370         {
00371             // value was truncated. Wrap it in FdoDataValue.
00372             ret = CO::Create(out);
00373         }
00374         else
00375         {
00376             // Round the value and convert it
00377             ret = CO::Create( (TO) ((val < 0) ? (val - round) : (val + round)) );
00378             // Prevent value shifting when shifting not allowed.
00379             VldShift( obj, ret, nullIfIncompatible, shift );
00380         }
00381 
00382         return ret;
00383     };
00384 
00385     // Converts values that don't need shifting, but may need truncation,
00386     // to other values.
00387     template <
00388         class C,                    // output FdoDataValue
00389         class TI,                   // input FDO type 
00390         class TO                    // output FDO type - must correspond to CO
00391     > 
00392     static C* Convert( 
00393         TI val,                             // input scalar value for obj
00394         TO min,                             // minimum value for TO type
00395         TO max,                             // maximum value for TO type
00396         FdoBoolean nullIfIncompatible,      // see FdoDataValue::Create()
00397         FdoBoolean truncate,                // see FdoDataValue::Create()
00398         FdoString* sTO                      // TO in string format; for exception messages.
00399     )
00400     {
00401         C*          ret    = NULL;
00402         FdoBoolean  isNull = false;
00403         TO          out;
00404 
00405         // First, truncate the value to be between output type min and max.
00406         Truncate<TI, TO>( val, out, isNull, min, max, nullIfIncompatible, truncate, sTO );
00407                 
00408         if ( isNull ) 
00409             // Output determined to be null
00410             ret = C::Create();
00411         else
00412             // Wrap output in an FdoDataValue.
00413             ret = C::Create( out );
00414 
00415         return ret;
00416     };
00417 
00418     // Truncates a value to be between a minimum and maximum value.
00419     template <
00420         class TI,                   // input FDO type 
00421         class TO                    // output FDO type
00422     > 
00423     static bool Truncate( 
00424         TI in,                      // original value
00425         TO& out,                    // truncated value
00426         bool& isNull,               // set to true if value truncated and
00427                                     // truncate=false and nullIfIncompatible=true
00428         TO min,                     // minimum value for TO type
00429         TO max,                     // maximum value for TO type
00430         bool nullIfIncompatible,    // see FdoDataValue::Create()
00431         bool truncate,              // see FdoDataValue::Create()
00432         FdoString* sTO              // TO in string format; for exception messages.
00433     )
00434     {
00435         bool success = true;
00436 
00437         // no truncation by default. However, it is up to the caller to 
00438         // determine if casting shifted the value.
00439         out = (TO) in;
00440 
00441         if ( in < min ) 
00442             success = Truncate<TI, TO>( in, out, isNull, min, nullIfIncompatible, truncate );   
00443         else if ( in > max ) 
00444             success = Truncate<TI, TO>( in, out, isNull, max, nullIfIncompatible, truncate );
00445 
00446         if ( !success )
00447             throw FdoExpressionException::Create(
00448                 FdoException::NLSGetMessage(
00449                     FDO_NLSID(EXPRESSION_21_VALUETRUNCATED),
00450                     FdoPtr<FdoDataValue>(FdoDataValue::Create(in))->ToString(),
00451                     sTO,
00452                     FdoPtr<FdoDataValue>(FdoDataValue::Create(min))->ToString(),
00453                     FdoPtr<FdoDataValue>(FdoDataValue::Create(max))->ToString()
00454                 )
00455             );
00456 
00457         return true;
00458     };
00459 
00460     // Truncates a value to a range endpoint
00461     template <
00462         class TI,                   // input FDO type 
00463         class TO                    // output FDO type
00464     > 
00465     static bool Truncate( 
00466         TI in,                      // input value
00467         TO& out,                    // output value
00468         bool& isNull,               // set to true truncate=false and 
00469                                     // nullIfIncompatible=true 
00470         TO bound,                   // the range endpoint
00471         bool nullIfIncompatible,    // see FdoDataValue::Create() 
00472         bool truncate               // see FdoDataValue::Create()
00473     )
00474     {
00475         bool ret = true;
00476         
00477         if ( truncate ) 
00478         {
00479             // Truncation allowed so set output to the range endpoint
00480             out = bound;
00481         }
00482         else
00483         {
00484             if ( nullIfIncompatible ) 
00485                 // Truncation not allowed so set output to null
00486                 isNull = true;
00487             else
00488                 // Truncation not allowed so raise an error
00489                 ret = false;
00490         }
00491 
00492         return ret;
00493     };
00494 
00495     // Helper function for FdoDataValue::Create( FdoDataType, FdoDataValue*, FdoBoolean, FdoBoolean, FdoBoolean )
00496     // Adjusts shifted values depending on whether shift is allowd 
00497     static void VldShift( 
00498         FdoDataValue* origValue,        // original value
00499         FdoDataValue* newValue,         // converted value
00500         bool nullIfIncompatible,        // Determines what happens when shift=false
00501                                         // and origValue != newValue (shift occurred
00502                                         // when origValue was converted to newValue but 
00503                                         // shifting not allowed ):
00504                                         //     true: set newValue to null.
00505                                         //     false: throw an exception
00506          bool shift                     // determines whether value allowed to shift. 
00507      );
00508 
00509     static FdoStringP DataTypeToString( FdoDataType dataType );
00510 
00511     bool        m_isNull;
00512     FdoStringP  m_XmlValue; // Manages GetXmlValue return string when datatype is datetime.
00513 /// \endcond
00514 
00515 };
00516 
00517 /// \ingroup (typedefs)
00518 /// \brief
00519 /// FdoDataValueP is a FdoPtr on FdoDataValue, provided for convenience.
00520 typedef FdoPtr<FdoDataValue> FdoDataValueP;
00521 
00522 #endif
00523 
00524 
Please send us your comment about this page