Main Page   Class Hierarchy   Compound List   File List   Compound Members  

query.h

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

Generated on Thu Feb 14 12:42:30 2008 for FastDB by doxygen1.2.18