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