Main Page   Class Hierarchy   Compound List   File List   Compound 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&) : dbCompiledQuery() {}
00365     dbQuery& operator =(dbQuery const&) { return *this; }
00366 
00367   public:
00368     int                pos; // position of condition in statement
00369 
00370     bool compileError() { return !isEmpty() && !compiled(); }
00371 
00372     char_t* dump(char_t* buf) { 
00373         char_t* p = buf;
00374         for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) { 
00375             p = elem->dump(p);
00376         }
00377         return buf;
00378     }
00379 
00380     char_t* dumpValues(char_t* buf) { 
00381         char_t* p = buf;
00382         for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) { 
00383             p = elem->dumpValues(p);
00384         }
00385         return buf;
00386     }
00387 
00388     dbQuery& append(dbQueryElement::ElementType type, void const* ptr,
00389                     dbTableDescriptor* table = NULL)
00390     {
00391         nextElement = &(*nextElement=new dbQueryElement(type,ptr,table))->next;
00392         operand = (type == dbQueryElement::qExpression);
00393         return *this;
00394     }
00395 
00396     bool isEmpty() { 
00397         return elements == NULL 
00398             || (elements->next == NULL && elements->type == dbQueryElement::qExpression && *(char_t*)elements->ptr == 0);
00399     }
00400 
00401 
00402     dbQuery& reset();
00403 
00404     //
00405     // Redefined operator = and , make it possible to specify query in the
00406     // following way:
00407     //         int x, y;
00408     //         dbDataTime dt;
00409     //         dbQuery q;
00410     //         dbCursor<record> cursor;
00411     //         q = "x=",x,"and y=",y,"and",dt == "date";
00412     //         for (x = 0; x < max_x; x++) {
00413     //             for (y = 0; y < max_y; y++) {
00414     //                 cursor.select(q);
00415     //                 ...
00416     //             }
00417     //         }
00418 
00419     dbQuery& add(dbQueryExpression const& expr);
00420 
00421     dbQuery& And(dbQueryExpression const& expr) { 
00422         if (elements != NULL) { 
00423             append(dbQueryElement::qExpression, _T("and"));
00424         }
00425         return add(expr);
00426     }
00427 
00428     dbQuery& Or(dbQueryExpression const& expr) { 
00429         if (elements != NULL) { 
00430             append(dbQueryElement::qExpression, _T("or"));
00431         }
00432         return add(expr);
00433     }
00434 
00435     dbQuery& And(char_t const* str) {
00436         if (elements != NULL) {
00437             append(dbQueryElement::qExpression, _T("and"));
00438         }
00439         return append(dbQueryElement::qExpression, str);
00440     }
00441 
00442     dbQuery& Or(char_t const* str) {
00443         if (elements != NULL) {
00444             append(dbQueryElement::qExpression, _T("or"));
00445         }
00446         return append(dbQueryElement::qExpression, str);
00447     }
00448 
00449     dbQuery& add(char_t const* str) {
00450         return append(operand ? dbQueryElement::qVarString
00451                       : dbQueryElement::qExpression, str);
00452     }
00453     dbQuery& add(char_t const** str) {
00454         return append(dbQueryElement::qVarStringPtr, str);
00455     }
00456     dbQuery& add(char_t** str) {
00457         return append(dbQueryElement::qVarStringPtr, str);
00458     }
00459     dbQuery& add(rectangle const& rect) {
00460         return append(dbQueryElement::qVarRectangle, &rect);
00461     }
00462 #ifdef USE_STD_STRING
00463     dbQuery& add(STD_STRING const& str) { 
00464         return append(dbQueryElement::qVarStdString, &str);
00465     }
00466     dbQuery& operator,(STD_STRING const& str) { return add(str); }
00467 #endif
00468 #ifdef USE_MFC_STRING
00469     dbQuery& add(MFC_STRING const& str) { 
00470         return append(dbQueryElement::qVarMfcString, &str);
00471     }
00472     dbQuery& operator,(MFC_STRING const& str) { return add(str); }
00473 #endif
00474     dbQuery& add(int1 const& value) {
00475         return append(dbQueryElement::qVarInt1, &value);
00476     }
00477     dbQuery& add (int2 const& value) {
00478         return append(dbQueryElement::qVarInt2, &value);
00479     }
00480     dbQuery& add (int4 const& value) {
00481         return append(dbQueryElement::qVarInt4, &value);
00482     }
00483     dbQuery& add (db_int8 const& value) {
00484         return append(dbQueryElement::qVarInt8, &value);
00485     }
00486     dbQuery& add(nat1 const& value) {
00487         return append(dbQueryElement::qVarInt1, &value);
00488     }
00489     dbQuery& add (nat2 const& value) {
00490         return append(dbQueryElement::qVarInt2, &value);
00491     }
00492     dbQuery& add (nat4 const& value) {
00493         return append(dbQueryElement::qVarInt4, &value);
00494     }
00495     dbQuery& add (db_nat8 const& value) {
00496         return append(dbQueryElement::qVarInt8, &value);
00497     }
00498 #if SIZEOF_LONG != 8
00499     dbQuery& add (long const& value) {
00500         return append(dbQueryElement::qVarInt4, &value);
00501     }
00502     dbQuery& add (unsigned long const& value) {
00503         return append(dbQueryElement::qVarInt4, &value);
00504     }
00505 #endif
00506     dbQuery& add (real4 const& value) {
00507         return append(dbQueryElement::qVarReal4, &value);
00508     }
00509     dbQuery& add(real8 const& value) {
00510         return append(dbQueryElement::qVarReal8, &value);
00511     }
00512     dbQuery& add(void const* value) { 
00513         return append(dbQueryElement::qVarRawData, value);
00514     }
00515 #ifndef bool
00516     dbQuery& add(bool const& value) {
00517         return append(dbQueryElement::qVarBool, &value);
00518     }
00519     dbQuery& operator,(bool const&  value) { return add(value); }
00520 #endif
00521 
00522     dbQuery& operator,(char_t const*  value) { return add(value); }
00523     dbQuery& operator,(char_t const** value) { return add(value); }
00524     dbQuery& operator,(char_t** value) { return add(value); }
00525     dbQuery& operator,(int1 const&  value) { return add(value); }
00526     dbQuery& operator,(int2 const&  value) { return add(value); }
00527     dbQuery& operator,(int4 const&  value) { return add(value); }
00528     dbQuery& operator,(db_int8 const&  value) { return add(value); }
00529     dbQuery& operator,(nat1 const&  value) { return add(value); }
00530     dbQuery& operator,(nat2 const&  value) { return add(value); }
00531     dbQuery& operator,(nat4 const&  value) { return add(value); }
00532     dbQuery& operator,(db_nat8 const&  value) { return add(value); }
00533 #if SIZEOF_LONG != 8
00534     dbQuery& operator,(long const&  value) { return add(value); }
00535     dbQuery& operator,(unsigned long const&  value) { return add(value); }
00536 #endif
00537     dbQuery& operator,(real4 const& value) { return add(value); }
00538     dbQuery& operator,(real8 const& value) { return add(value); }
00539     dbQuery& operator,(void const*  value) { return add(value); }
00540     dbQuery& operator,(dbQueryExpression const& expr) { return add(expr); }
00541     dbQuery& operator,(rectangle const& rect) { return add(rect); }
00542 
00543     dbQuery& operator = (const char_t* str) {
00544         return reset().append(dbQueryElement::qExpression, str);
00545     }
00546 
00547 #if !defined(_MSC_VER) || _MSC_VER+0 >= 1300
00548     inline dbQuery& operator,(dbArray<db_int4> const& value) { 
00549         return append(dbQueryElement::qVarArrayOfInt4, &value);
00550     }
00551 
00552     inline dbQuery& operator,(dbArray<db_int4>const* const& value) { 
00553         return append(dbQueryElement::qVarArrayOfInt4Ptr, &value);
00554     }
00555 
00556     inline dbQuery& operator,(dbArray<db_int8> const& value) { 
00557         return append(dbQueryElement::qVarArrayOfInt8, &value);
00558     }
00559 
00560     inline dbQuery& operator,(dbArray<db_int8>const* const& value) { 
00561         return append(dbQueryElement::qVarArrayOfInt8Ptr, &value);
00562     }
00563 
00564     inline dbQuery& add(dbArray<db_int4> const& value) { 
00565         return append(dbQueryElement::qVarArrayOfInt4, &value);
00566     }
00567 
00568     inline dbQuery& add(dbArray<db_int4>const* const& value) { 
00569         return append(dbQueryElement::qVarArrayOfInt4Ptr, &value);
00570     }
00571 
00572     inline dbQuery& add(dbArray<db_int8> const& value) { 
00573         return append(dbQueryElement::qVarArrayOfInt8, &value);
00574     }
00575 
00576     inline dbQuery& add(dbArray<db_int8>const* const& value) { 
00577         return append(dbQueryElement::qVarArrayOfInt8Ptr, &value);
00578     }
00579 #endif
00580 
00581 #ifndef NO_MEMBER_TEMPLATES
00582     template<class T>
00583     dbQuery& operator,(dbReference<T> const& value) { 
00584         return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00585     }
00586 
00587     template<class T>
00588     dbQuery& operator,(dbArray< dbReference<T> > const& value) { 
00589         return append(dbQueryElement::qVarArrayOfRef, &value, 
00590                       &T::dbDescriptor);
00591     }
00592     template<class T>
00593     dbQuery& operator,(dbArray< dbReference<T> >const* const& value) { 
00594         return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00595     }
00596 
00597     template<class T>
00598     dbQuery& add(dbReference<T> const& value) { 
00599         return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00600     }
00601 
00602     template<class T>
00603     dbQuery& add(dbArray< dbReference<T> > const& value) { 
00604         return append(dbQueryElement::qVarArrayOfRef, &value, 
00605                       &T::dbDescriptor);
00606     }
00607 
00608     template<class T>
00609     dbQuery& add(dbArray< dbReference<T> >const* const& value) { 
00610         return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00611     }
00612 
00613     template<class T>
00614     dbQuery& operator = (T const& value) { 
00615         return reset().add(value);
00616     }   
00617 #else
00618     dbQuery& operator = (dbQueryExpression const& expr) {
00619         return reset().add(expr);
00620     }    
00621     dbQuery& operator = (rectangle const& expr) {
00622         return reset().add(expr);
00623     }    
00624 #endif
00625 
00626     dbQuery() {
00627         elements = NULL;
00628         nextElement = &elements;
00629         operand = false;
00630         pos = 0;
00631     }
00632     dbQuery(char_t const* str) {
00633         elements = new dbQueryElement(dbQueryElement::qExpression, str);
00634         nextElement = &elements->next;
00635         operand = true;
00636         pos = 0;
00637     }
00638     ~dbQuery() {
00639         reset();
00640     }
00641 };
00642 
00643 #ifdef NO_MEMBER_TEMPLATES
00644 template<class T>
00645 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbReference<T> const& value) { 
00646     return expr.add(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00647 }
00648 template<class T>
00649 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> > const& value) { 
00650     return expr.add(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00651 }
00652 
00653 template<class T>
00654 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> >const* const& value) { 
00655     return expr.add(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00656 }
00657 
00658 template<class T>
00659 inline dbQuery& operator,(dbQuery& query, dbReference<T> const& value) { 
00660     return query.append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00661 }
00662 
00663 template<class T>
00664 inline dbQuery& operator,(dbQuery& query, dbArray< dbReference<T> > const& value) 
00665 { 
00666     return query.append(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00667 }
00668 
00669 template<class T>
00670 inline dbQuery& operator,(dbQuery& query, 
00671                           dbArray< dbReference<T> >const* const& value) 
00672 { 
00673     return query.append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00674 }
00675 
00676 template<class T>
00677 inline dbQuery& add(dbQuery& query, dbReference<T> const& value) { 
00678     return query.append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00679 }
00680 
00681 template<class T>
00682 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> > const& value) { 
00683     return query.append(dbQueryElement::qVarArrayOfRef, &value, &T::dbDescriptor);
00684 }
00685 
00686 template<class T>
00687 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> >const* const& value) { 
00688     return query.append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00689 }
00690 #endif
00691 
00692 #define USER_FUNC(f) static dbUserFunction f##_descriptor(&f, STRLITERAL(#f))
00693 
00694 class  dbInheritedAttribute;
00695 class  dbSynthesizedAttribute;
00696 
00701 class GIGABASE_DLL_ENTRY  dbUserFunctionArgument { 
00702   public:
00703     enum dbArgumentType { 
00704         atInteger, 
00705         atBoolean, 
00706         atString, 
00707         atReal, 
00708         atReference, 
00709         atRawBinary
00710     };  
00711     dbArgumentType type; 
00712     union {
00713         real8         realValue;
00714         db_int8       intValue;
00715         bool          boolValue;
00716         char_t const* strValue;
00717         oid_t         oidValue;
00718         void*         rawValue;
00719     } u;
00720 
00721   private:
00722     friend class dbDatabase;
00723     dbUserFunctionArgument(dbExprNode*             expr, 
00724                            dbInheritedAttribute&   iattr, 
00725                            dbSynthesizedAttribute& sattr, 
00726                            int                     i);
00727 };
00728 
00737 class GIGABASE_DLL_ENTRY dbUserFunction {
00738     friend class dbDatabase;
00739     friend class dbCompiler;
00740 
00741     void*   fptr;
00742     char_t* fname;
00743 
00744     dbUserFunction* next;
00745     static dbUserFunction* list;
00746 
00747     enum funcType {
00748         fInt2Bool,
00749         fReal2Bool,
00750         fStr2Bool,
00751         fInt2Int,
00752         fReal2Int,
00753         fStr2Int,
00754         fInt2Real,
00755         fReal2Real,
00756         fStr2Real,
00757         fInt2Str,
00758         fReal2Str,
00759         fStr2Str, 
00760         fArg2Bool, 
00761         fArg2Int, 
00762         fArg2Real, 
00763         fArg2Str, 
00764         fArgArg2Bool, 
00765         fArgArg2Int, 
00766         fArgArg2Real, 
00767         fArgArg2Str, 
00768         fArgArgArg2Bool, 
00769         fArgArgArg2Int, 
00770         fArgArgArg2Real, 
00771         fArgArgArg2Str
00772     };
00773     int type;
00774 
00775     void bind(char_t* name, void* f, funcType ftype);
00776 
00777   public:
00778 
00779     static dbUserFunction* find(char_t const* name) {
00780         for (dbUserFunction* func = list; func != NULL; func = func->next) {
00781             if (name == func->fname) {
00782                 return func;
00783             }
00784         }
00785         return NULL;
00786     }
00787 
00788     int getParameterType();
00789 
00790     int getNumberOfParameters();
00791 
00792     dbUserFunction(bool (__cdecl *f)(db_int8), char_t* name) {
00793         bind(name, (void*)f, fInt2Bool);
00794     }
00795     dbUserFunction(bool (__cdecl *f)(real8), char_t* name) {
00796         bind(name, (void*)f, fReal2Bool);
00797     }
00798     dbUserFunction(bool (__cdecl *f)(char_t const*), char_t* name) {
00799         bind(name, (void*)f, fStr2Bool);
00800     }
00801     dbUserFunction(db_int8 (__cdecl *f)(db_int8), char_t* name) {
00802         bind(name, (void*)f, fInt2Int);
00803     }
00804     dbUserFunction(db_int8 (__cdecl *f)(real8), char_t* name) {
00805         bind(name, (void*)f, fReal2Int);
00806     }
00807     dbUserFunction(db_int8 (__cdecl *f)(char_t const*), char_t* name) {
00808         bind(name, (void*)f, fStr2Int);
00809     }
00810     dbUserFunction(real8 (__cdecl *f)(db_int8), char_t* name) {
00811         bind(name, (void*)f, fInt2Real);
00812     }
00813     dbUserFunction(real8 (__cdecl *f)(real8), char_t* name) {
00814         bind(name, (void*)f, fReal2Real);
00815     }
00816     dbUserFunction(real8 (__cdecl *f)(char_t const*), char_t* name) {
00817         bind(name, (void*)f, fStr2Real);
00818     }
00819     dbUserFunction(char_t* (__cdecl *f)(db_int8), char_t* name) {
00820         bind(name, (void*)f, fInt2Str);
00821     }
00822     dbUserFunction(char_t* (__cdecl *f)(real8), char_t* name) {
00823         bind(name, (void*)f, fReal2Str);
00824     }
00825     dbUserFunction(char_t* (__cdecl *f)(char_t const*), char_t* name) {
00826         bind(name, (void*)f, fStr2Str);
00827     }
00828 
00829     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00830         bind(name, (void*)f, fArg2Bool); 
00831     }
00832     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00833         bind(name, (void*)f, fArg2Str); 
00834     }
00835     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00836         bind(name, (void*)f, fArg2Int); 
00837     }
00838     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&), char_t* name) { 
00839         bind(name, (void*)f, fArg2Real); 
00840     }
00841 
00842     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00843         bind(name, (void*)f, fArgArg2Bool); 
00844     }
00845     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00846         bind(name, (void*)f, fArgArg2Str); 
00847     }
00848     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00849         bind(name, (void*)f, fArgArg2Int); 
00850     }
00851     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00852         bind(name, (void*)f, fArgArg2Real); 
00853     }
00854 
00855 
00856     dbUserFunction(bool (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00857         bind(name, (void*)f, fArgArgArg2Bool); 
00858     }
00859     dbUserFunction(char_t* (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00860         bind(name, (void*)f, fArgArgArg2Str); 
00861     }
00862     dbUserFunction(db_int8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00863         bind(name, (void*)f, fArgArgArg2Int); 
00864     }
00865     dbUserFunction(real8 (__cdecl *f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char_t* name) { 
00866         bind(name, (void*)f, fArgArgArg2Real); 
00867     }
00868 
00869     ~dbUserFunction();
00870 };
00871 
00872 END_GIGABASE_NAMESPACE
00873 
00874 
00875 #endif

Generated on Thu Feb 14 21:46:03 2008 for GigaBASE by doxygen1.2.18