casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableExprData.h
Go to the documentation of this file.
00001 //# TableExprData.h: Abstract base class for data object in a TaQL expression
00002 //# Copyright (C) 2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: TableExprData.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $
00028 
00029 
00030 #ifndef TABLES_TABLEEXPRDATA_H
00031 #define TABLES_TABLEEXPRDATA_H
00032 
00033 //# Includes
00034 #include <casa/aips.h>
00035 #include <casa/Utilities/DataType.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class String;
00041 class IPosition;
00042 template<class T> class Array;
00043 template<class T> class Block;
00044 
00045 
00046 // <summary>
00047 // Abstract base class for data object in a TaQL expression.
00048 // </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //   <li> <linkto class="TableExprNode">TableExprNode</linkto>.
00057 // </prerequisite>
00058 
00059 // <synopsis>
00060 // The Table Query Language (TaQL) is implemented by means of the
00061 // <src>TableExprNode</src> classes. It is primarily meant to do
00062 // selection on tables. However, it is also possible to use it for
00063 // selection on any other set of data resembling tabular data.
00064 // <br>An example of such a data set is a set of
00065 // <linkto class=Record>Record</linkto> objects. TaQL can be used
00066 // to select some of those records based on the contents of one or more
00067 // fields in the records. Note that this example is already directly
00068 // supported by TaQL.
00069 // <br>Another example is when a user has several equally long vectors
00070 // with data. The vectors can be seen as fields and TaQL can be used
00071 // to select entries from the vectors. This example requires that
00072 // this class TableExprData is used.
00073 // <p>
00074 // The <linkto class=TableExprNodeRecordField>TableExprNodeRecordField</linkto>
00075 // and <linkto class=TableExprId>TableExprId</linkto> classes form
00076 // the means by which TaQL can deal with any set of data.
00077 // <br>First the TaQL expression has to be setup. This is done by
00078 // constructing a <src>TableExprNodeRecordField</src> object for each
00079 // 'field' to be used in the expression. <src>TableExprNodeRecordField</src>
00080 // uses a <linkto class=RecordInterface>RecordInterface</linkto> object
00081 // to make the data type of a field in the data set known and to
00082 // map a field name to a field index (the index is the sequence number
00083 // of the field in the record description).
00084 // <br>When evaluating the expression for each member in the data set,
00085 // a <src>TableExprData></src> needs to be passed (which is automatically
00086 // converted to <linkto class=TableExprId>TableExprId</linkto>).
00087 // So a class needs to be written to access the data in the data set.
00088 // It needs to be derived from the abstract base class <src>TableExprData</src>
00089 // defined in this file. An example is given below.
00090 // <p>
00091 // It is also possible that the data set contains records and that
00092 // the selection is based on fields in those records. In such a case
00093 // the record passed to <src>TableExprNodeRecordField</src> should contain
00094 // subrecords representing those records. The field index in the various
00095 // functions as passed as a <src>Block<Int></src> to denote the fields
00096 // in the subrecords (and possibly subsubrecords, etc..
00097 // However, normally records won't be used and <src>fieldNrs[0]</src>
00098 // gives the field index.
00099 // </synopsis>
00100 
00101 // <example>
00102 // This example shows how a data set consisting of two vectors
00103 // of scalars can be used.
00104 // <srcblock>
00105 // // Write a class derived from TableExprData to handle the vectors.
00106 // class MyTestClass : public TableExprData
00107 // {
00108 // public:
00109 //   // Constructor checks if both vectors have equal length.
00110 //   MyTestClass (const Vector<Int>& fld1, const Vector<String>& fld2)
00111 //     : itsFld1(fld1), itsFld2(fld2), itsEntry(0)
00112 //     { AlwaysAssert (fld1.nelements() == fld2.nelements(), AipsError); }
00113 //   virtual ~MyTestClass()
00114 //     {}
00115 //   void next()
00116 //     { itsEntry++; }
00117 //   // Note that only the get functions for the possible types are needed.
00118 //   // Also note that all numeric types are handled by TaQL as Double.
00119 //   // The exception should never be thrown unless things are screwed up.
00120 //   virtual Double getDouble (const Block<Int>& fieldNrs) const
00121 //     { switch (fieldNrs[0]) {
00122 //       case 0:
00123 //         return itsFld1(itsEntry);
00124 //       default:
00125 //         throw AipsError();
00126 //       }
00127 //     }
00128 //   virtual String getString (const Block<Int>& fieldNrs) const
00129 //     { switch (fieldNrs[0]) {
00130 //       case 1:
00131 //         return itsFld2(itsEntry);
00132 //       default:
00133 //         throw AipsError();
00134 //       }
00135 //     }
00136 //   virtual DataType dataType (const Block<Int>& fieldNrs) const
00137 //     { switch (fieldNrs[0]) {
00138 //       case 0:
00139 //         return TpInt;
00140 //       case 1:
00141 //         return TpString;
00142 //       default:
00143 //         throw AipsError();
00144 //       }
00145 //     }
00146 //   // Make a Record to give to vectors a name.
00147 //   // The order in which the fields are defined determines the fieldnrs
00148 //   // passed to the get functions.
00149 //   static Record makeRecord()
00150 //     { RecordDesc desc;
00151 //       desc.addField ("fld1", TpInt);
00152 //       desc.addField ("fld2", TpString);
00153 //       return Record(desc);
00154 //     }
00155 // private:
00156 //   Vector<Int>    itsFld1;
00157 //   Vector<String> itsFld2;
00158 //   uInt           itsEntry;
00159 // };
00160 //   
00161 // Vector<uInt> findMatches (const Vector<Int>& fld1,
00162 //                           const Vector<String>& fld2)
00163 // {
00164 //   // Make some expression.
00165 //   // First create a Record to make the names and types known.
00166 //   Record rec(MyTestClass::makeRecord());
00167 //   TableExprNode expr (makeRecordExpr(rec,"fld1") > 10 &&
00168 //                       makeRecordExpr(rec,"fld2") != pattern("*xxx*"));
00169 //   // Now evaluate the expression for each entry in the vector.
00170 //   // Make a MyTestClass object to handle the vectors and put it in
00171 //   // a TableExprId object for the TaQL evaluator.
00172 //   // Note that TableExprId holds a pointer to the original MyTestClass
00173 //   // object, so the TaQL evaluator 'sees' the changes we make by
00174 //   // using the its next() function.
00175 //   MyTestClass subj(fld1, fld2);
00176 //   TableExprId eid(subj);
00177 //   // The matching entry numbers are stored in a vector.
00178 //   Vector<uInt> result(fld1.nelements());
00179 //   uInt nr=0;
00180 //   Bool valb;
00181 //   for (uInt i=0; i<fld1.nelements(); i++) {
00182 //     expr.get (eid, valb);
00183 //     if (valb) {
00184 //       result(nr++) = i;
00185 //     }
00186 //     subj.next();         // Next time the next entry must be used
00187 //   }
00188 //   result.resize (nr, True);
00189 //   return result;
00190 // }
00191 // </srcBlock>
00192 // </example>
00193 
00194 // <motivation>
00195 // This class makes it possible that TaQL can be used in a very versatile way.
00196 // </motivation>
00197 
00198 //# <todo asof="1996/03/12">
00199 //# </todo>
00200 
00201 
00202 class TableExprData
00203 {
00204 public:
00205   // Construct it from a row number.
00206   TableExprData()
00207     {;}
00208   
00209   virtual ~TableExprData();
00210 
00211   // Get the shape of the given field.
00212   // Need only be implemented if there are arrays in the data.
00213   // The default implementation returns an empty IPosition.
00214   virtual IPosition shape (const Block<Int>& fieldNrs) const;
00215 
00216   // Get the data type of the given field.
00217   // Note that TpArray types have to be returned for arrays.
00218   // If the field is unknown, TpOther should be returned.
00219   // It is used for the isdefined function to check if the field
00220   // is really defined.
00221   virtual DataType dataType (const Block<Int>& fieldNrs) const = 0;
00222 
00223   // Get a scalar in the given type.
00224   // This might involve converting for Double and DComplex.
00225   // Most default implementations throws an "not possible" exception.
00226   // The default <src>getDouble</src> invokes <src>getInt</src>.
00227   // The default <src>getDComplex</src> invokes <src>getDouble</src>.
00228   // <group>
00229   virtual Bool     getBool     (const Block<Int>& fieldNrs) const;
00230   virtual Int64    getInt      (const Block<Int>& fieldNrs) const;
00231   virtual Double   getDouble   (const Block<Int>& fieldNrs) const;
00232   virtual DComplex getDComplex (const Block<Int>& fieldNrs) const;
00233   virtual String   getString   (const Block<Int>& fieldNrs) const;
00234   // </group>
00235 
00236   // Get an array in the given type.
00237   // This might involve converting for Double and DComplex.
00238   // Most default implementations throws an "not possible" exception.
00239   // The default <src>getArrayDComplex</src> invokes
00240   // <src>getArrayDouble</src>.
00241   // <group>
00242   virtual Array<Bool>     getArrayBool     (const Block<Int>& fieldNrs) const;
00243   virtual Array<Int64>    getArrayInt      (const Block<Int>& fieldNrs) const;
00244   virtual Array<Double>   getArrayDouble   (const Block<Int>& fieldNrs) const;
00245   virtual Array<DComplex> getArrayDComplex (const Block<Int>& fieldNrs) const;
00246   virtual Array<String>   getArrayString   (const Block<Int>& fieldNrs) const;
00247   // </group>
00248 };
00249 
00250 
00251 } //# NAMESPACE CASA - END
00252 
00253 #endif