Main Page | Class Hierarchy | Class List | File List | Class Members

query.h

00001 //-< QUERY.H >-------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Constructing and hashing database query statements
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __QUERY_H__
00012 #define __QUERY_H__
00013 
00014 BEGIN_GIGABASE_NAMESPACE
00015 
00019 class GIGABASE_DLL_ENTRY dbQueryElement {
00020     friend class dbQuery;
00021     friend class dbCompiler;
00022     friend class dbQueryExpression;
00023     friend class dbQueryElementAllocator;
00024     friend class dbCLI;
00025   public:
00026     enum ElementType {
00027         qExpression, // part of SQL expression
00028         qVarBool,
00029         qVarInt1,
00030         qVarInt2,
00031         qVarInt4,
00032         qVarInt8,
00033         qVarReal4,
00034         qVarReal8,
00035         qVarString,
00036         qVarStringPtr,
00037         qVarReference,
00038         qVarRectangle, 
00039         qVarArrayOfRef, 
00040         qVarArrayOfInt4,
00041         qVarArrayOfInt8,
00042         qVarArrayOfRefPtr,
00043         qVarArrayOfInt4Ptr,
00044         qVarArrayOfInt8Ptr,
00045         qVarRawData,
00046         qVarStdString,
00047         qVarMfcString,
00048         qVarUnknown
00049     };
00050 
00051     void* operator new (size_t size);
00052     void  operator delete(void* p);
00053 
00054     char_t* dump(char_t* buf);
00055     char_t* dumpValues(char_t* buf);
00056 
00057     dbQueryElement(ElementType t, void const* p,
00058                    dbTableDescriptor* table = NULL)
00059     {
00060         type = t;
00061         ptr  = p;
00062         ref  = table;
00063         next = NULL;
00064     }
00065   private:
00066     dbQueryElement*    next;
00067     void const*        ptr;
00068     ElementType        type;
00069     dbTableDescriptor* ref;
00070 };
00071 
00072 
00078 class GIGABASE_DLL_ENTRY dbQueryElementAllocator { 
00079     friend class dbDatabase;
00080     dbMutex         mutex;
00081     dbQueryElement* freeChain;
00082     
00083   public:
00084     void free(dbQueryElement* first, dbQueryElement** lastNext) { 
00085         dbCriticalSection cs(mutex);
00086         if (first != NULL) { 
00087             *lastNext = freeChain;
00088             freeChain = first;
00089         }
00090     }
00091         
00092     void* allocate(size_t size) { 
00093         dbCriticalSection cs(mutex);
00094         dbQueryElement* elem = freeChain;
00095         if (elem != NULL) {
00096             freeChain = elem->next;
00097             return elem;
00098         } else {
00099             return dbMalloc(size);
00100         }
00101     }
00102     dbQueryElementAllocator();
00103     ~dbQueryElementAllocator();
00104 
00105     static dbQueryElementAllocator instance;
00106 };
00107 
00108 
00128 class GIGABASE_DLL_ENTRY dbComponent {
00129   public:
00130     char_t const* structure;
00131     char_t const* field;
00132 
00133     dbComponent(char_t const* s, char_t const* f=NULL) : structure(s), field(f) {}
00134 };
00135 
00142 class GIGABASE_DLL_ENTRY dbQueryExpression {
00143     friend class dbQuery;
00144     dbQueryElement*  first;
00145     dbQueryElement** last;
00146     bool             operand;
00147 
00148   public:
00149     dbQueryExpression& add(dbQueryElement::ElementType type, void const* ptr, dbTableDescriptor* table = NULL) {
00150         last = &(*last = new dbQueryElement(type, ptr, table))->next;
00151         operand = (type == dbQueryElement::qExpression);
00152         return *this;
00153     }
00154 
00155     dbQueryExpression& operator = (char_t const* ptr) {
00156         first = NULL, last = &first;
00157         return add(dbQueryElement::qExpression, ptr);
00158     }
00159     dbQueryExpression& operator = (dbComponent const& comp);
00160 
00161     dbQueryExpression& operator = (dbQueryExpression const& expr);
00162 
00163     dbQueryExpression& operator,(int1 const& ptr) {
00164         return add(dbQueryElement::qVarInt1, &ptr);
00165     }
00166     dbQueryExpression& operator,(int2 const& ptr) {
00167         return add(dbQueryElement::qVarInt2, &ptr);
00168     }
00169     dbQueryExpression& operator,(int4 const& ptr) {
00170         return add(dbQueryElement::qVarInt4, &ptr);
00171     }
00172     dbQueryExpression& operator,(db_int8 const& ptr) {
00173         return add(dbQueryElement::qVarInt8, &ptr);
00174     }
00175     dbQueryExpression& operator,(nat1 const& ptr) {
00176         return add(dbQueryElement::qVarInt1, &ptr);
00177     }
00178     dbQueryExpression& operator,(nat2 const& ptr) {
00179         return add(dbQueryElement::qVarInt2, &ptr);
00180     }
00181     dbQueryExpression& operator,(nat4 const& ptr) {
00182         return add(dbQueryElement::qVarInt4, &ptr);
00183     }
00184     dbQueryExpression& operator,(db_nat8 const& ptr) {
00185         return add(dbQueryElement::qVarInt8, &ptr);
00186     }
00187 #if SIZEOF_LONG != 8
00188     dbQueryExpression& operator,(long const& ptr) {
00189         return add(dbQueryElement::qVarInt4, &ptr);
00190     }
00191     dbQueryExpression& operator,(unsigned long const& ptr) {
00192         return add(dbQueryElement::qVarInt4, &ptr);
00193     }
00194 #endif
00195     dbQueryExpression& operator,(real4 const& ptr) {
00196         return add(dbQueryElement::qVarReal4, &ptr);
00197     }
00198     dbQueryExpression& operator,(real8 const& ptr) {
00199         return add(dbQueryElement::qVarReal8, &ptr);
00200     }
00201     dbQueryExpression& operator,(void const* ptr) { 
00202         return add(dbQueryElement::qVarRawData, ptr);
00203     }
00204 #ifndef bool
00205     dbQueryExpression& operator,(bool const& ptr) {
00206         return add(dbQueryElement::qVarBool, &ptr);
00207     }
00208 #endif
00209     dbQueryExpression& operator,(char_t const* ptr) {
00210         return add(operand ? dbQueryElement::qVarString
00211                    : dbQueryElement::qExpression, ptr);
00212     }
00213     dbQueryExpression& operator,(char_t const** ptr) {
00214         return add(dbQueryElement::qVarStringPtr, ptr);
00215     }
00216     dbQueryExpression& operator,(char_t** ptr) {
00217         return add(dbQueryElement::qVarStringPtr, ptr);
00218     }
00219     dbQueryExpression& operator,(rectangle const& rect) {
00220         return add(dbQueryElement::qVarRectangle, &rect);
00221     }
00222 #ifdef USE_STD_STRING
00223     dbQueryExpression& operator,(STD_STRING const& str) {
00224         return add(dbQueryElement::qVarStdString, &str);
00225     }
00226 #endif
00227 #ifdef USE_MFC_STRING
00228     dbQueryExpression& operator,(MFC_STRING const& str) {
00229         return add(dbQueryElement::qVarMfcString, &str);
00230     }
00231 #endif
00232 
00233     dbQueryExpression& operator,(dbQueryExpression const& expr) {
00234         *last = new dbQueryElement(dbQueryElement::qExpression, _T("("));
00235         (*last)->next = expr.first;
00236         last = expr.last;
00237         *last = new dbQueryElement(dbQueryElement::qExpression, _T(")"));
00238         last = &(*last)->next;
00239         operand = false;
00240         return *this;
00241     }
00242     dbQueryExpression& operator,(dbComponent const& comp) {
00243         add(dbQueryElement::qExpression, comp.structure);
00244         if (comp.field != NULL) {
00245             add(dbQueryElement::qExpression, _T("."));
00246             add(dbQueryElement::qExpression, comp.field);
00247         }
00248         operand = false;
00249         return *this;
00250     }
00251     dbQueryExpression& operator += (dbComponent const& comp) { 
00252         return *this,comp;
00253     }
00254     dbQueryExpression& operator += (char const* ptr) { 
00255         return add(dbQueryElement::qExpression, ptr);
00256     }
00257 #ifndef NO_MEMBER_TEMPLATES
00258     template<class T>
00259     dbQueryExpression& operator,(dbReference<T> const& value) { 
00260         return add(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00261     }
00262 
00263     template<class T>
00264     inline dbQueryExpression& operator,(dbArray< dbReference<T> > const& value) { 
00265         return add(dbQueryElement::qVarArrayOfRef, &value, 
00266                       &T::dbDescriptor);
00267     }
00268 
00269     template<class T>
00270     inline dbQueryExpression& operator,(dbArray< dbReference<T> >const* const& value) { 
00271         return add(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00272     }
00273 #endif
00274 #if !defined(_MSC_VER) || _MSC_VER+0 >= 1300
00275     inline dbQueryExpression& operator,(dbArray<db_int4> const& value) { 
00276         return add(dbQueryElement::qVarArrayOfInt4, &value);
00277     }
00278 
00279     inline dbQueryExpression& operator,(dbArray<db_int4>const* const& value) { 
00280         return add(dbQueryElement::qVarArrayOfInt4Ptr, &value);
00281     }
00282 
00283     inline dbQueryExpression& operator,(dbArray<db_int8> const& value) { 
00284         return add(dbQueryElement::qVarArrayOfInt8, &value);
00285     }
00286 
00287     inline dbQueryExpression& operator,(dbArray<db_int8>const* const& value) { 
00288         return add(dbQueryElement::qVarArrayOfInt8Ptr, &value);
00289     }
00290 #endif
00291 };
00292 
00293 class dbOrderByNode;
00294 class dbFollowByNode;
00295 
00299 class GIGABASE_DLL_ENTRY dbCompiledQuery {
00300   public:
00301     dbExprNode*        tree;
00302     dbOrderByNode*     order;
00303     dbFollowByNode*    follow;
00304     dbTableDescriptor* table;
00305     int                schemeVersion;
00306 
00307     size_t             stmtLimitStart;
00308     size_t             stmtLimitLen;
00309     int4*              stmtLimitStartPtr;
00310     int4*              stmtLimitLenPtr;
00311     bool               limitSpecified;
00312 
00313     enum IteratorInit {
00314         StartFromAny,
00315         StartFromFirst,
00316         StartFromLast,
00317         StartFromRef,
00318         StartFromArray,
00319         StartFromArrayPtr
00320     };
00321     IteratorInit       startFrom;
00322     enum IteratorType { 
00323         UserDefined      = 0,
00324         TraverseForward  = 1, 
00325         TraverseBackward = 2
00326     };
00327     int  iterType;
00328 
00329     void const*        root;
00330 
00331     void destroy();
00332 
00333     bool compiled() { return tree != NULL; }
00334 
00335     dbCompiledQuery() {
00336         tree = NULL;
00337         order = NULL;
00338         follow = NULL;
00339         table = NULL;
00340         startFrom = StartFromAny;
00341         iterType = UserDefined;
00342         limitSpecified = false;
00343     }
00344 };
00345 
00350 class GIGABASE_DLL_ENTRY dbQuery : public dbCompiledQuery {
00351     friend class dbCompiler;
00352     friend class dbDatabase;
00353     friend class dbSubSql;
00354     friend class dbCLI;
00355   private:
00356     dbMutex            mutex;
00357     dbQueryElement*    elements;
00358     dbQueryElement**   nextElement;
00359     bool               operand;
00360     bool               mutexLocked;
00361     //
00362     // Prohibite query copying
00363     //
00364     dbQuery(dbQuery const&) {}
00365     dbQuery& operator =(dbQuery const&) { return *this; }
00366 
00367   public:
00368     int                pos; // position of condition in statement
00369 
00370     char_t* dump(char_t* buf) { 
00371         char_t* p = buf;
00372         for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) { 
00373             p = elem->dump(p);
00374         }
00375         return buf;
00376     }
00377 
00378     char_t* dumpValues(char_t* buf) { 
00379         char_t* p = buf;
00380         for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) { 
00381             p = elem->dumpValues(p);
00382         }
00383         return buf;
00384     }
00385 
00386     dbQuery& append(dbQueryElement::ElementType type, void const* ptr,
00387                     dbTableDescriptor* table = NULL)
00388     {
00389         nextElement = &(*nextElement=new dbQueryElement(type,ptr,table))->next;
00390         operand = (type == dbQueryElement::qExpression);
00391         return *this;
00392     }
00393 
00394     bool isEmpty() { 
00395         return elements == NULL 
00396             || (elements->next == NULL && elements->type == dbQueryElement::qExpression && *(char_t*)elements->ptr == 0);
00397     }
00398 
00399 
00400     dbQuery& reset();
00401 
00402     //
00403     // Redefined operator = and , make it possible to specify query in the
00404     // following way:
00405     //         int x, y;
00406     //         dbDataTime dt;
00407     //         dbQuery q;
00408     //         dbCursor<record> cursor;
00409     //         q = "x=",x,"and y=",y,"and",dt == "date";
00410     //         for (x = 0; x < max_x; x++) {
00411     //             for (y = 0; y < max_y; y++) {
00412     //                 cursor.select(q);
00413     //                 ...
00414     //             }
00415     //         }
00416 
00417     dbQuery& add(dbQueryExpression const& expr);
00418 
00419     dbQuery& And(char_t const* str) {
00420         if (elements != NULL) {
00421             append(dbQueryElement::qExpression, _T("and"));
00422         }
00423         return append(dbQueryElement::qExpression, str);
00424     }
00425 
00426     dbQuery& Or(char_t const* str) {
00427         if (elements != NULL) {
00428             append(dbQueryElement::qExpression, _T("or"));
00429         }
00430         return append(dbQueryElement::qExpression, str);
00431     }
00432 
00433     dbQuery& add(char_t const* str) {
00434         return append(operand ? dbQueryElement::qVarString
00435                       : dbQueryElement::qExpression, str);
00436     }
00437     dbQuery& add(char_t const** str) {
00438         return append(dbQueryElement::qVarStringPtr, str);
00439     }
00440     dbQuery& add(char_t** str) {
00441         return append(dbQueryElement::qVarStringPtr, str);
00442     }
00443     dbQuery& add(rectangle const& rect) {
00444         return append(dbQueryElement::qVarRectangle, &rect);
00445     }
00446 #ifdef USE_STD_STRING
00447     dbQuery& add(STD_STRING const& str) { 
00448         return append(dbQueryElement::qVarStdString, &str);
00449     }
00450     dbQuery& operator,(STD_STRING const& str) { return add(str); }
00451 #endif
00452 #ifdef USE_MFC_STRING
00453     dbQuery& add(MFC_STRING const& str) { 
00454         return append(dbQueryElement::qVarMfcString, &str);
00455     }
00456     dbQuery& operator,(MFC_STRING const& str) { return add(str); }
00457 #endif
00458     dbQuery& add(int1 const& value) {
00459         return append(dbQueryElement::qVarInt1, &value);
00460     }
00461     dbQuery& add (int2 const& value) {
00462         return append(dbQueryElement::qVarInt2, &value);
00463     }
00464     dbQuery& add (int4 const& value) {
00465         return append(dbQueryElement::qVarInt4, &value);
00466     }
00467     dbQuery& add (db_int8 const& value) {
00468         return append(dbQueryElement::qVarInt8, &value);
00469     }
00470     dbQuery& add(nat1 const& value) {
00471         return append(dbQueryElement::qVarInt1, &value);
00472     }
00473     dbQuery& add (nat2 const& value) {
00474         return append(dbQueryElement::qVarInt2, &value);
00475     }
00476     dbQuery& add (nat4 const& value) {
00477         return append(dbQueryElement::qVarInt4, &value);
00478     }
00479     dbQuery& add (db_nat8 const& value) {
00480         return append(dbQueryElement::qVarInt8, &value);
00481     }
00482 #if SIZEOF_LONG != 8
00483     dbQuery& add (long const& value) {
00484         return append(dbQueryElement::qVarInt4, &value);
00485     }
00486     dbQuery& add (unsigned long const& value) {
00487         return append(dbQueryElement::qVarInt4, &value);
00488     }
00489 #endif
00490     dbQuery& add (real4 const& value) {
00491         return append(dbQueryElement::qVarReal4, &value);
00492     }
00493     dbQuery& add(real8 const& value) {
00494         return append(dbQueryElement::qVarReal8, &value);
00495     }
00496     dbQuery& add(void const* value) { 
00497         return append(dbQueryElement::qVarRawData, value);
00498     }
00499 #ifndef bool
00500     dbQuery& add(bool const& value) {
00501         return append(dbQueryElement::qVarBool, &value);
00502     }
00503     dbQuery& operator,(bool const&  value) { return add(value); }
00504 #endif
00505 
00506     dbQuery& operator,(char_t const*  value) { return add(value); }
00507     dbQuery& operator,(char_t const** value) { return add(value); }
00508     dbQuery& operator,(char_t** value) { return add(value); }
00509     dbQuery& operator,(int1 const&  value) { return add(value); }
00510     dbQuery& operator,(int2 const&  value) { return add(value); }
00511     dbQuery& operator,(int4 const&  value) { return add(value); }
00512     dbQuery& operator,(db_int8 const&  value) { return add(value); }
00513     dbQuery& operator,(nat1 const&  value) { return add(value); }
00514     dbQuery& operator,(nat2 const&  value) { return add(value); }
00515     dbQuery& operator,(nat4 const&  value) { return add(value); }
00516     dbQuery& operator,(db_nat8 const&  value) { return add(value); }
00517 #if SIZEOF_LONG != 8
00518     dbQuery& operator,(long const&  value) { return add(value); }
00519     dbQuery& operator,(unsigned long const&  value) { return add(value); }
00520 #endif
00521     dbQuery& operator,(real4 const& value) { return add(value); }
00522     dbQuery& operator,(real8 const& value) { return add(value); }
00523     dbQuery& operator,(void const*  value) { return add(value); }
00524     dbQuery& operator,(dbQueryExpression const& expr) { return add(expr); }
00525     dbQuery& operator,(rectangle const& rect) { return add(rect); }
00526 
00527     dbQuery& operator = (const char_t* str) {
00528         return reset().append(dbQueryElement::qExpression, str);
00529     }
00530 
00531 #if !defined(_MSC_VER) || _MSC_VER+0 >= 1300
00532     inline dbQuery& operator,(dbArray<db_int4> const& value) { 
00533         return append(dbQueryElement::qVarArrayOfInt4, &value);
00534     }
00535 
00536     inline dbQuery& operator,(dbArray<db_int4>const* const& value) { 
00537         return append(dbQueryElement::qVarArrayOfInt4Ptr, &value);
00538     }
00539 
00540     inline dbQuery& operator,(dbArray<db_int8> const& value) { 
00541         return append(dbQueryElement::qVarArrayOfInt8, &value);
00542     }
00543 
00544     inline dbQuery& operator,(dbArray<db_int8>const* const& value) { 
00545         return append(dbQueryElement::qVarArrayOfInt8Ptr, &value);
00546     }
00547 
00548     inline dbQuery& add(dbArray<db_int4> const& value) { 
00549         return append(dbQueryElement::qVarArrayOfInt4, &value);
00550     }
00551 
00552     inline dbQuery& add(dbArray<db_int4>const* const& value) { 
00553         return append(dbQueryElement::qVarArrayOfInt4Ptr, &value);
00554     }
00555 
00556     inline dbQuery& add(dbArray<db_int8> const& value) { 
00557         return append(dbQueryElement::qVarArrayOfInt8, &value);
00558     }
00559 
00560     inline dbQuery& add(dbArray<db_int8>const* const& value) { 
00561         return append(dbQueryElement::qVarArrayOfInt8Ptr, &value);
00562     }
00563 #endif
00564 
00565 #ifndef NO_MEMBER_TEMPLATES
00566     template<class T>
00567     dbQuery& operator,(dbReference<T> const& value) { 
00568         return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00569     }
00570 
00571     template<class T>
00572     dbQuery& operator,(dbArray< dbReference<T> > const& value) { 
00573         return append(dbQueryElement::qVarArrayOfRef, &value, 
00574                       &T::dbDescriptor);
00575     }
00576     template<class T>
00577     dbQuery& operator,(dbArray< dbReference<T> >const* const& value) { 
00578         return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00579     }
00580 
00581     template<class T>
00582     dbQuery& add(dbReference<T> const& value) { 
00583         return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00584     }
00585 
00586     template<class T>
00587     dbQuery& add(dbArray< dbReference<T> > const& value) { 
00588         return append(dbQueryElement::qVarArrayOfRef, &value, 
00589                       &T::dbDescriptor);
00590     }
00591 
00592     template<class T>
00593     dbQuery& add(dbArray< dbReference<T> >const* const& value) { 
00594         return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00595     }
00596 
00597     template<class T>
00598     dbQuery& operator = (T const& value) { 
00599         return reset().add(value);
00600     }   
00601 #else
00602     dbQuery& operator = (dbQueryExpression const& expr) {
00603         return reset().add(expr);
00604     }    
00605     dbQuery& operator = (rectangle const& expr) {
00606         return reset().add(expr);
00607     }    
00608 #endif
00609 
00610     dbQuery() {
00611         elements = NULL;
00612         nextElement = &elements;
00613         operand = false;
00614         pos = 0;
00615     }
00616     dbQuery(char_t const* str) {
00617         elements = new dbQueryElement(dbQueryElement::qExpression, str);
00618         nextElement = &elements->next;
00619         operand = true;
00620         pos = 0;
00621     }
00622     ~dbQuery() {
00623         reset();
00624     }
00625 };
00626 
00627 #ifdef NO_MEMBER_TEMPLATES
00628 template<class T>
00629 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbReference<T> const& value) { 
00630     return expr.add(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00631 }
00632 template<class T>
00633 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> > const& value) { 
00634     return expr.add(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00635 }
00636 
00637 template<class T>
00638 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> >const* const& value) { 
00639     return expr.add(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00640 }
00641 
00642 template<class T>
00643 inline dbQuery& operator,(dbQuery& query, dbReference<T> const& value) { 
00644     return query.append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00645 }
00646 
00647 template<class T>
00648 inline dbQuery& operator,(dbQuery& query, dbArray< dbReference<T> > const& value) 
00649 { 
00650     return query.append(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00651 }
00652 
00653 template<class T>
00654 inline dbQuery& operator,(dbQuery& query, 
00655                           dbArray< dbReference<T> >const* const& value) 
00656 { 
00657     return query.append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00658 }
00659 
00660 template<class T>
00661 inline dbQuery& add(dbQuery& query, dbReference<T> const& value) { 
00662     return query.append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00663 }
00664 
00665 template<class T>
00666 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> > const& value) { 
00667     return query.append(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00668 }
00669 
00670 template<class T>
00671 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> >const* const& value) { 
00672     return query.append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00673 }
00674 #endif
00675 
00676 #define USER_FUNC(f) static dbUserFunction f##_descriptor(&f, STRLITERAL(#f))
00677 
00678 class  dbInheritedAttribute;
00679 class  dbSynthesizedAttribute;
00680 
00685 class GIGABASE_DLL_ENTRY  dbUserFunctionArgument { 
00686   public:
00687     enum dbArgumentType { 
00688         atInteger, 
00689         atBoolean, 
00690         atString, 
00691         atReal, 
00692         atReference, 
00693         atRawBinary
00694     };  
00695     dbArgumentType type; 
00696     union {
00697         real8         realValue;
00698         db_int8       intValue;
00699         bool          boolValue;
00700         char_t const* strValue;
00701         oid_t         oidValue;
00702         void*         rawValue;
00703     } u;
00704 
00705   private:
00706     friend class dbDatabase;
00707     dbUserFunctionArgument(dbExprNode*             expr, 
00708                            dbInheritedAttribute&   iattr, 
00709                            dbSynthesizedAttribute& sattr, 
00710                            int                     i);
00711 };
00712 
00721 class GIGABASE_DLL_ENTRY dbUserFunction {
00722     friend class dbDatabase;
00723     friend class dbCompiler;
00724 
00725     void*   fptr;
00726     char_t* name;
00727 
00728     dbUserFunction* next;
00729     static dbUserFunction* list;
00730 
00731     enum funcType {
00732         fInt2Bool,
00733         fReal2Bool,
00734         fStr2Bool,
00735         fInt2Int,
00736         fReal2Int,
00737         fStr2Int,
00738         fInt2Real,
00739         fReal2Real,
00740         fStr2Real,
00741         fInt2Str,
00742         fReal2Str,
00743         fStr2Str, 
00744         fArg2Bool, 
00745         fArg2Int, 
00746         fArg2Real, 
00747         fArg2Str, 
00748         fArgArg2Bool, 
00749         fArgArg2Int, 
00750         fArgArg2Real, 
00751         fArgArg2Str, 
00752         fArgArgArg2Bool, 
00753         fArgArgArg2Int, 
00754         fArgArgArg2Real, 
00755         fArgArgArg2Str
00756     };
00757     int type;
00758 
00759     void bind(char_t* name, void* f, funcType ftype);
00760 
00761   public:
00762 
00763     static dbUserFunction* find(char_t const* name) {
00764         for (dbUserFunction* func = list; func != NULL; func = func->next) {
00765             if (name == func->name) {
00766                 return func;
00767             }
00768         }
00769         return NULL;
00770     }
00771 
00772     int getParameterType();
00773 
00774     int getNumberOfParameters();
00775 
00776     dbUserFunction(bool (__cdecl *f)(db_int8), char_t* name) {
00777         bind(name, (void*)f, fInt2Bool);
00778     }
00779     dbUserFunction(bool (__cdecl *f)(real8), char_t* name) {
00780         bind(name, (void*)f, fReal2Bool);
00781     }
00782     dbUserFunction(bool (__cdecl *f)(char_t const*), char_t* name) {
00783         bind(name, (void*)f, fStr2Bool);
00784     }
00785     dbUserFunction(db_int8 (__cdecl *f)(db_int8), char_t* name) {
00786         bind(name, (void*)f, fInt2Int);
00787     }
00788     dbUserFunction(db_int8 (__cdecl *f)(real8), char_t* name) {
00789         bind(name, (void*)f, fReal2Int);
00790     }
00791     dbUserFunction(db_int8 (__cdecl *f)(char_t const*), char_t* name) {
00792         bind(name, (void*)f, fStr2Int);
00793     }
00794     dbUserFunction(real8 (__cdecl *f)(db_int8), char_t* name) {
00795         bind(name, (void*)f, fInt2Real);
00796     }
00797     dbUserFunction(real8 (__cdecl *f)(real8), char_t* name) {
00798         bind(name, (void*)f, fReal2Real);
00799     }
00800     dbUserFunction(real8 (__cdecl *f)(char_t const*), char_t* name) {
00801         bind(name, (void*)f, fStr2Real);
00802     }
00803     dbUserFunction(char_t* (__cdecl *f)(db_int8), char_t* name) {
00804         bind(name, (void*)f, fInt2Str);
00805     }
00806     dbUserFunction(char_t* (__cdecl *f)(real8), char_t* name) {
00807         bind(name, (void*)f, fReal2Str);
00808     }
00809     dbUserFunction(char_t* (__cdecl *f)(char_t const*), char_t* name) {
00810         bind(name, (void*)f, fStr2Str);
00811     }
00812 
00813     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00814         bind(name, (void*)f, fArg2Bool); 
00815     }
00816     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00817         bind(name, (void*)f, fArg2Str); 
00818     }
00819     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00820         bind(name, (void*)f, fArg2Int); 
00821     }
00822     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00823         bind(name, (void*)f, fArg2Real); 
00824     }
00825 
00826     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00827         bind(name, (void*)f, fArgArg2Bool); 
00828     }
00829     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00830         bind(name, (void*)f, fArgArg2Str); 
00831     }
00832     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00833         bind(name, (void*)f, fArgArg2Int); 
00834     }
00835     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00836         bind(name, (void*)f, fArgArg2Real); 
00837     }
00838 
00839 
00840     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00841         bind(name, (void*)f, fArgArgArg2Bool); 
00842     }
00843     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00844         bind(name, (void*)f, fArgArgArg2Str); 
00845     }
00846     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00847         bind(name, (void*)f, fArgArgArg2Int); 
00848     }
00849     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00850         bind(name, (void*)f, fArgArgArg2Real); 
00851     }
00852 };
00853 
00854 END_GIGABASE_NAMESPACE
00855 
00856 
00857 #endif

Generated on Thu Nov 24 23:14:30 2005 for GigaBASE by doxygen 1.3.5