00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __QUERY_H__
00012 #define __QUERY_H__
00013
00017 class FASTDB_DLL_ENTRY dbQueryElement {
00018 friend class dbQuery;
00019 friend class dbCompiler;
00020 friend class dbQueryExpression;
00021 friend class dbQueryElementAllocator;
00022 public:
00023 enum ElementType {
00024 qExpression,
00025 qVarBool,
00026 qVarInt1,
00027 qVarInt2,
00028 qVarInt4,
00029 qVarInt8,
00030 qVarReal4,
00031 qVarReal8,
00032 qVarString,
00033 qVarStringPtr,
00034 qVarReference,
00035 qVarArrayOfRef,
00036 qVarArrayOfRefPtr,
00037 qVarRawData
00038 #ifdef USE_STD_STRING
00039 ,qVarStdString
00040 #endif
00041 };
00042
00043 void* operator new (size_t size);
00044 void operator delete(void* p) {
00045 delete[] (char*)p;
00046 }
00047
00048 char* dump(char* buf);
00049 char* dumpValues(char* buf);
00050
00051 dbQueryElement(ElementType t, void const* p,
00052 dbTableDescriptor* table = NULL)
00053 {
00054 type = t;
00055 ptr = p;
00056 ref = table;
00057 next = NULL;
00058 }
00059 private:
00060 dbQueryElement* next;
00061 void const* ptr;
00062 ElementType type;
00063 dbTableDescriptor* ref;
00064 };
00065
00066
00072 class FASTDB_DLL_ENTRY dbQueryElementAllocator {
00073 friend class dbDatabase;
00074
00075 dbMutex& mutex;
00076 dbQueryElement* freeChain;
00077
00078 public:
00079 void deallocate(dbQueryElement* first, dbQueryElement** lastNext) {
00080 dbCriticalSection cs(mutex);
00081 if (first != NULL) {
00082 *lastNext = freeChain;
00083 freeChain = first;
00084 }
00085 }
00086
00087 void* allocate(size_t size) {
00088 dbCriticalSection cs(mutex);
00089 dbQueryElement* elem = freeChain;
00090 if (elem != NULL) {
00091 freeChain = elem->next;
00092 return elem;
00093 } else {
00094 return new byte[size];
00095 }
00096 }
00097 dbQueryElementAllocator();
00098 ~dbQueryElementAllocator();
00099
00100 static dbQueryElementAllocator instance;
00101 };
00102
00103 inline void* dbQueryElement::operator new(size_t size) {
00104 return dbQueryElementAllocator::instance.allocate(size);
00105 }
00106
00126 class FASTDB_DLL_ENTRY dbComponent {
00127 public:
00128 char const* structure;
00129 char const* field;
00130
00131 dbComponent(char const* s, char const* f=NULL) : structure(s), field(f) {}
00132 };
00133
00134
00141 class FASTDB_DLL_ENTRY dbQueryExpression {
00142 friend class dbQuery;
00143 dbQueryElement* first;
00144 dbQueryElement** last;
00145 bool operand;
00146
00147 public:
00148 dbQueryExpression& add(dbQueryElement::ElementType type, void const* ptr, dbTableDescriptor* table = NULL) {
00149 last = &(*last = new dbQueryElement(type, ptr, table))->next;
00150 operand = (type == dbQueryElement::qExpression);
00151 return *this;
00152 }
00153
00154 dbQueryExpression& operator = (char const* ptr) {
00155 first = NULL, last = &first;
00156 return add(dbQueryElement::qExpression, ptr);
00157 }
00158 dbQueryExpression& operator = (dbComponent const& comp);
00159
00160 dbQueryExpression& operator = (dbQueryExpression const& expr);
00161
00162 dbQueryExpression& operator,(int1 const& ptr) {
00163 return add(dbQueryElement::qVarInt1, &ptr);
00164 }
00165 dbQueryExpression& operator,(int2 const& ptr) {
00166 return add(dbQueryElement::qVarInt2, &ptr);
00167 }
00168 dbQueryExpression& operator,(int4 const& ptr) {
00169 return add(dbQueryElement::qVarInt4, &ptr);
00170 }
00171 dbQueryExpression& operator,(db_int8 const& ptr) {
00172 return add(dbQueryElement::qVarInt8, &ptr);
00173 }
00174 dbQueryExpression& operator,(real4 const& ptr) {
00175 return add(dbQueryElement::qVarReal4, &ptr);
00176 }
00177 dbQueryExpression& operator,(real8 const& ptr) {
00178 return add(dbQueryElement::qVarReal8, &ptr);
00179 }
00180 dbQueryExpression& operator,(bool const& ptr) {
00181 return add(dbQueryElement::qVarBool, &ptr);
00182 }
00183 dbQueryExpression& operator,(char const* ptr) {
00184 return add(operand ? dbQueryElement::qVarString
00185 : dbQueryElement::qExpression, ptr);
00186 }
00187 dbQueryExpression& operator,(char const** ptr) {
00188 return add(dbQueryElement::qVarStringPtr, ptr);
00189 }
00190 dbQueryExpression& operator,(char** ptr) {
00191 return add(dbQueryElement::qVarStringPtr, ptr);
00192 }
00193 dbQueryExpression& operator,(void const* ptr) {
00194 return add(dbQueryElement::qVarRawData, ptr);
00195 }
00196 #ifdef USE_STD_STRING
00197 dbQueryExpression& operator,(std::string const& str) {
00198 return add(dbQueryElement::qVarStdString, &str);
00199 }
00200 #endif
00201 dbQueryExpression& operator,(dbQueryExpression const& expr) {
00202 *last = new dbQueryElement(dbQueryElement::qExpression, "(");
00203 (*last)->next = expr.first;
00204 last = expr.last;
00205 *last = new dbQueryElement(dbQueryElement::qExpression, ")");
00206 last = &(*last)->next;
00207 operand = false;
00208 return *this;
00209 }
00210 dbQueryExpression& operator,(dbComponent const& comp) {
00211 add(dbQueryElement::qExpression, comp.structure);
00212 if (comp.field != NULL) {
00213 add(dbQueryElement::qExpression, ".");
00214 add(dbQueryElement::qExpression, comp.field);
00215 }
00216 operand = false;
00217 return *this;
00218 }
00219 dbQueryExpression& operator += (dbComponent const& comp) {
00220 return *this,comp;
00221 }
00222 dbQueryExpression& operator += (char const* ptr) {
00223 return add(dbQueryElement::qExpression, ptr);
00224 }
00225 #ifndef NO_MEMBER_TEMPLATES
00226 template<class T>
00227 dbQueryExpression& operator,(dbReference<T> const& value) {
00228 return add(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00229 }
00230
00231 template<class T>
00232 inline dbQueryExpression& operator,(dbArray< dbReference<T> > const& value) {
00233 return add(dbQueryElement::qVarArrayOfRef, &value,
00234 &T::dbDescriptor);
00235 }
00236
00237 template<class T>
00238 inline dbQueryExpression& operator,(dbArray< dbReference<T> >const* const& value) {
00239 return add(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00240 }
00241 #endif
00242 };
00243
00244 class dbOrderByNode;
00245 class dbFollowByNode;
00246
00247
00251 class FASTDB_DLL_ENTRY dbCompiledQuery {
00252 public:
00253 dbExprNode* tree;
00254 dbOrderByNode* order;
00255 dbFollowByNode* follow;
00256 dbTableDescriptor* table;
00257
00258 enum IteratorInit {
00259 StartFromAny,
00260 StartFromFirst,
00261 StartFromLast,
00262 StartFromRef,
00263 StartFromArray,
00264 StartFromArrayPtr
00265 };
00266 IteratorInit startFrom;
00267 void const* root;
00268
00269 void destroy();
00270
00271 bool compiled() { return tree != NULL; }
00272
00273 dbCompiledQuery() {
00274 tree = NULL;
00275 order = NULL;
00276 follow = NULL;
00277 table = NULL;
00278 startFrom = StartFromAny;
00279 }
00280 };
00281
00286 class FASTDB_DLL_ENTRY dbQuery : public dbCompiledQuery {
00287 friend class dbCompiler;
00288 friend class dbDatabase;
00289 friend class dbSubSql;
00290 private:
00291 dbMutex mutex;
00292 dbQueryElement* elements;
00293 dbQueryElement** nextElement;
00294 bool operand;
00295 bool mutexLocked;
00296
00297
00298
00299
00300 dbQuery(dbQuery const&) {}
00301 dbQuery& operator =(dbQuery const&) { return *this; }
00302
00303 public:
00304 int pos;
00305
00306
00307 char* dump(char* buf) {
00308 char* p = buf;
00309 for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) {
00310 p = elem->dump(p);
00311 }
00312 return buf;
00313 }
00314
00315 char* dumpValues(char* buf) {
00316 char* p = buf;
00317 for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next) {
00318 p = elem->dumpValues(p);
00319 }
00320 return buf;
00321 }
00322
00323 dbQuery& append(dbQueryElement::ElementType type, void const* ptr,
00324 dbTableDescriptor* table = NULL)
00325 {
00326 nextElement = &(*nextElement=new dbQueryElement(type,ptr,table))->next;
00327 operand = (type == dbQueryElement::qExpression);
00328 return *this;
00329 }
00330
00331 dbQuery& reset();
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 dbQuery& add(dbQueryExpression const& expr);
00349
00350 dbQuery& And(char const* str) {
00351 if (elements != NULL) {
00352 append(dbQueryElement::qExpression, "and");
00353 }
00354 return append(dbQueryElement::qExpression, str);
00355 }
00356
00357 dbQuery& Or(char const* str) {
00358 if (elements != NULL) {
00359 append(dbQueryElement::qExpression, "or");
00360 }
00361 return append(dbQueryElement::qExpression, str);
00362 }
00363
00364 dbQuery& add(char const* str) {
00365 return append(operand ? dbQueryElement::qVarString
00366 : dbQueryElement::qExpression, str);
00367 }
00368 dbQuery& add(char const** str) {
00369 return append(dbQueryElement::qVarStringPtr, str);
00370 }
00371 #ifdef USE_STD_STRING
00372 dbQuery& add(std::string const& str) {
00373 return append(dbQueryElement::qVarStdString, &str);
00374 }
00375 dbQuery& operator,(std::string const& str) { return add(str); }
00376 #endif
00377 dbQuery& add(char** str) {
00378 return append(dbQueryElement::qVarStringPtr, str);
00379 }
00380 dbQuery& add(int1 const& value) {
00381 return append(dbQueryElement::qVarInt1, &value);
00382 }
00383 dbQuery& add (int2 const& value) {
00384 return append(dbQueryElement::qVarInt2, &value);
00385 }
00386 dbQuery& add (int4 const& value) {
00387 return append(dbQueryElement::qVarInt4, &value);
00388 }
00389 dbQuery& add (db_int8 const& value) {
00390 return append(dbQueryElement::qVarInt8, &value);
00391 }
00392 dbQuery& add (real4 const& value) {
00393 return append(dbQueryElement::qVarReal4, &value);
00394 }
00395 dbQuery& add(real8 const& value) {
00396 return append(dbQueryElement::qVarReal8, &value);
00397 }
00398 dbQuery& add(bool const& value) {
00399 return append(dbQueryElement::qVarBool, &value);
00400 }
00401 dbQuery& add(void const* value) {
00402 return append(dbQueryElement::qVarRawData, value);
00403 }
00404
00405 dbQuery& operator,(char const* value) { return add(value); }
00406 dbQuery& operator,(char const** value) { return add(value); }
00407 dbQuery& operator,(char** value) { return add(value); }
00408 dbQuery& operator,(int1 const& value) { return add(value); }
00409 dbQuery& operator,(int2 const& value) { return add(value); }
00410 dbQuery& operator,(int4 const& value) { return add(value); }
00411 dbQuery& operator,(db_int8 const& value) { return add(value); }
00412 dbQuery& operator,(real4 const& value) { return add(value); }
00413 dbQuery& operator,(real8 const& value) { return add(value); }
00414 dbQuery& operator,(bool const& value) { return add(value); }
00415 dbQuery& operator,(void const* value) { return add(value); }
00416 dbQuery& operator,(dbQueryExpression const& expr) { return add(expr); }
00417
00418 dbQuery& operator = (const char* str) {
00419 return reset().append(dbQueryElement::qExpression, str);
00420 }
00421
00422 #ifndef NO_MEMBER_TEMPLATES
00423 template<class T>
00424 dbQuery& operator,(dbReference<T> const& value) {
00425 return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00426 }
00427
00428 template<class T>
00429 inline dbQuery& operator,(dbArray< dbReference<T> > const& value) {
00430 return append(dbQueryElement::qVarArrayOfRef, &value,
00431 &T::dbDescriptor);
00432 }
00433
00434 template<class T>
00435 inline dbQuery& operator,(dbArray< dbReference<T> >const* const& value) {
00436 return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00437 }
00438
00439 template<class T>
00440 dbQuery& add(dbReference<T> const& value) {
00441 return append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00442 }
00443
00444 template<class T>
00445 dbQuery& add(dbArray< dbReference<T> > const& value) {
00446 return append(dbQueryElement::qVarArrayOfRef, &value,
00447 &T::dbDescriptor);
00448 }
00449 template<class T>
00450 dbQuery& add(dbArray< dbReference<T> >const* const& value) {
00451 return append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00452 }
00453
00454 template<class T>
00455 dbQuery& operator = (T const& value) {
00456 return reset().add(value);
00457 }
00458 #else
00459 dbQuery& operator = (dbQueryExpression const& expr) {
00460 return reset().add(expr);
00461 }
00462 #endif
00463
00464
00465 dbQuery() {
00466 elements = NULL;
00467 nextElement = &elements;
00468 operand = false;
00469 pos = 0;
00470 }
00471 dbQuery(char const* str) {
00472 elements = new dbQueryElement(dbQueryElement::qExpression, str);
00473 nextElement = &elements->next;
00474 operand = true;
00475 pos = 0;
00476 }
00477 ~dbQuery() {
00478 reset();
00479 }
00480 };
00481
00482 #ifdef NO_MEMBER_TEMPLATES
00483 template<class T>
00484 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbReference<T> const& value) {
00485 return expr.add(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00486 }
00487 template<class T>
00488 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> > const& value) {
00489 return expr.add(dbQueryElement::qVarArrayOfRef, &value,
00490 &T::dbDescriptor);
00491 }
00492
00493 template<class T>
00494 inline dbQueryExpression& operator,(dbQueryExpression& expr, dbArray< dbReference<T> >const* const& value) {
00495 return expr.add(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00496 }
00497
00498 template<class T>
00499 inline dbQuery& operator,(dbQuery& query, dbReference<T> const& value) {
00500 return query.append(dbQueryElement::qVarReference, &value,
00501 &T::dbDescriptor);
00502 }
00503
00504 template<class T>
00505 inline dbQuery& operator,(dbQuery& query,
00506 dbArray< dbReference<T> > const& value)
00507 {
00508 return query.append(dbQueryElement::qVarArrayOfRef, &value,
00509 &T::dbDescriptor);
00510 }
00511
00512 template<class T>
00513 inline dbQuery& operator,(dbQuery& query,
00514 dbArray< dbReference<T> >const* const& value)
00515 {
00516 return query.append(dbQueryElement::qVarArrayOfRefPtr, &value,
00517 &T::dbDescriptor);
00518 }
00519
00520 template<class T>
00521 inline dbQuery& add(dbQuery& query, dbReference<T> const& value) {
00522 return query.append(dbQueryElement::qVarReference, &value, &T::dbDescriptor);
00523 }
00524
00525 template<class T>
00526 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> > const& value) {
00527 return query.append(dbQueryElement::qVarArrayOfRef, &value,
00528 &T::dbDescriptor);
00529 }
00530
00531 template<class T>
00532 inline dbQuery& add(dbQuery& query, dbArray< dbReference<T> >const* const& value) {
00533 return query.append(dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
00534 }
00535 #endif
00536
00537 #define USER_FUNC(f) static dbUserFunction f##_descriptor(&f, #f)
00538
00539 struct dbInheritedAttribute;
00540 union dbSynthesizedAttribute;
00541
00546 class FASTDB_DLL_ENTRY dbUserFunctionArgument {
00547 public:
00548 enum dbArgumentType {
00549 atInteger,
00550 atBoolean,
00551 atString,
00552 atReal,
00553 atReference,
00554 atRawBinary
00555 };
00556 dbArgumentType type;
00557 union {
00558 real8 realValue;
00559 db_int8 intValue;
00560 bool boolValue;
00561 char const* strValue;
00562 oid_t oidValue;
00563 void* rawValue;
00564 } u;
00565
00566 private:
00567 friend class dbDatabase;
00568 dbUserFunctionArgument(dbExprNode* expr,
00569 dbInheritedAttribute& iattr,
00570 dbSynthesizedAttribute& sattr,
00571 int i);
00572 };
00573
00582 class FASTDB_DLL_ENTRY dbUserFunction {
00583 friend class dbDatabase;
00584 friend class dbCompiler;
00585
00586 void* fptr;
00587 char* name;
00588
00589 dbUserFunction* next;
00590 static dbUserFunction* list;
00591
00592 enum funcType {
00593 fInt2Bool,
00594 fReal2Bool,
00595 fStr2Bool,
00596 fInt2Int,
00597 fReal2Int,
00598 fStr2Int,
00599 fInt2Real,
00600 fReal2Real,
00601 fStr2Real,
00602 fInt2Str,
00603 fReal2Str,
00604 fStr2Str,
00605 fArg2Bool,
00606 fArg2Int,
00607 fArg2Real,
00608 fArg2Str,
00609 fArgArg2Bool,
00610 fArgArg2Int,
00611 fArgArg2Real,
00612 fArgArg2Str,
00613 fArgArgArg2Bool,
00614 fArgArgArg2Int,
00615 fArgArgArg2Real,
00616 fArgArgArg2Str
00617 };
00618 int type;
00619
00620 void bind(char* name, void* f, funcType ftype);
00621
00622 public:
00623
00624 static dbUserFunction* find(char const* name) {
00625 for (dbUserFunction* func = list; func != NULL; func = func->next) {
00626 if (name == func->name) {
00627 return func;
00628 }
00629 }
00630 return NULL;
00631 }
00632
00633 int getParameterType();
00634
00635 int getNumberOfParameters();
00636
00637 dbUserFunction(bool (*f)(db_int8), char* name) {
00638 bind(name, (void*)f, fInt2Bool);
00639 }
00640 dbUserFunction(bool (*f)(real8), char* name) {
00641 bind(name, (void*)f, fReal2Bool);
00642 }
00643 dbUserFunction(bool (*f)(char const*), char* name) {
00644 bind(name, (void*)f, fStr2Bool);
00645 }
00646 dbUserFunction(db_int8 (*f)(db_int8), char* name) {
00647 bind(name, (void*)f, fInt2Int);
00648 }
00649 dbUserFunction(db_int8 (*f)(real8), char* name) {
00650 bind(name, (void*)f, fReal2Int);
00651 }
00652 dbUserFunction(db_int8 (*f)(char const*), char* name) {
00653 bind(name, (void*)f, fStr2Int);
00654 }
00655 dbUserFunction(real8 (*f)(db_int8), char* name) {
00656 bind(name, (void*)f, fInt2Real);
00657 }
00658 dbUserFunction(real8 (*f)(real8), char* name) {
00659 bind(name, (void*)f, fReal2Real);
00660 }
00661 dbUserFunction(real8 (*f)(char const*), char* name) {
00662 bind(name, (void*)f, fStr2Real);
00663 }
00664 dbUserFunction(char* (*f)(db_int8), char* name) {
00665 bind(name, (void*)f, fInt2Str);
00666 }
00667 dbUserFunction(char* (*f)(real8), char* name) {
00668 bind(name, (void*)f, fReal2Str);
00669 }
00670 dbUserFunction(char* (*f)(char const*), char* name) {
00671 bind(name, (void*)f, fStr2Str);
00672 }
00673
00674
00675 dbUserFunction(bool (*f)(dbUserFunctionArgument&), char* name) {
00676 bind(name, (void*)f, fArg2Bool);
00677 }
00678 dbUserFunction(char* (*f)(dbUserFunctionArgument&), char* name) {
00679 bind(name, (void*)f, fArg2Str);
00680 }
00681 dbUserFunction(db_int8 (*f)(dbUserFunctionArgument&), char* name) {
00682 bind(name, (void*)f, fArg2Int);
00683 }
00684 dbUserFunction(real8 (*f)(dbUserFunctionArgument&), char* name) {
00685 bind(name, (void*)f, fArg2Real);
00686 }
00687
00688 dbUserFunction(bool (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00689 bind(name, (void*)f, fArgArg2Bool);
00690 }
00691 dbUserFunction(char* (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00692 bind(name, (void*)f, fArgArg2Str);
00693 }
00694 dbUserFunction(db_int8 (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00695 bind(name, (void*)f, fArgArg2Int);
00696 }
00697 dbUserFunction(real8 (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00698 bind(name, (void*)f, fArgArg2Real);
00699 }
00700
00701
00702 dbUserFunction(bool (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00703 bind(name, (void*)f, fArgArgArg2Bool);
00704 }
00705 dbUserFunction(char* (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00706 bind(name, (void*)f, fArgArgArg2Str);
00707 }
00708 dbUserFunction(db_int8 (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00709 bind(name, (void*)f, fArgArgArg2Int);
00710 }
00711 dbUserFunction(real8 (*f)(dbUserFunctionArgument&, dbUserFunctionArgument&, dbUserFunctionArgument&), char* name) {
00712 bind(name, (void*)f, fArgArgArg2Real);
00713 }
00714 };
00715
00716 #endif
00717
00718
00719