OOFILE  1.9
oofquery.cpp
Go to the documentation of this file.
1 // COPYRIGHT 1994 A.D. Software, All rights reserved
2 
3 // OOFILE database queries
4 
5 #include "oofpch_c.h" // for precompilation of core files
6 
7 #ifndef H_OOFIOS
8  #include "oofios.h"
9 #endif
10 #ifndef H_OOF3
11  #include "oof3.h"
12 #endif
13 #ifndef H_OOFQUERY
14  #include "oofquery.h"
15 #endif
16 #ifndef H_OOFWORDS
17  #include "oofwords.h"
18 #endif
19 #include <assert.h>
20 
21 #ifdef OOF_MEM_DEBUG_LAST_INCLUDE
22  #include OOF_MEM_DEBUG_LAST_INCLUDE
23 #endif
24 
25 #ifndef OOF_NO_STDLIB
26  #ifndef std
27  using namespace std;
28  #endif
29 #endif
30 
31 
32 // Note: these consts are for future upgrades
35 
36 
37 // -------------------------------------------------------
38 // d b Q u e r y C l a u s e
39 // -------------------------------------------------------
40 void
41 dbQueryClause::getSearchTables(const dbTable* /*inSchTable*/, dbTable*& outDiffFieldTable, dbTable*& outRelatedTable) const
42 {
43  outRelatedTable = outDiffFieldTable = 0;
44 }
45 
46 
48 dbQueryClause::cloneReplacingTable(const dbTable* /*inTable*/, const dbTable* /*repTable*/) const
49 {
50  return 0;
51 }
52 
53 
54 bool
56 {
57  for(int i=0;schStr[i];i++)
58  if((schStr[i]==sWildcardMultiple)||(schStr[i]==sWildcardSingle))
59  return true;
60  return false;
61 }
62 
63 
64 bool
66 {
67  return false;
68 }
69 
70 
71 bool
73 {
74  const bool ret = (inOp >= hasWord && inOp <= hasAllWordsStartsWith);
75  return ret;
76 }
77 
78 
81 {
82  return dbQueryBinaryCombo(this, dbQueryClause::oofAND, &rhs);
83 }
84 
85 
88 {
89  return dbQueryBinaryCombo(this, dbQueryClause::oofAND, &rhs);
90 }
91 
92 
95 {
96  return dbQueryBinaryCombo(this, dbQueryClause::oofOR, &rhs);
97 }
98 
99 
102 {
103  return dbQueryBinaryCombo(this, dbQueryClause::oofOR, &rhs);
104 }
105 
106 
109 {
110  return new dbQueryBinaryComboOwner(this, dbQueryClause::oofOR, adoptRHS);
111 }
112 
113 
116 {
117  return new dbQueryBinaryComboOwner(this, dbQueryClause::oofOR, adoptRHS);
118 }
119 
120 
123 {
124  return new dbQueryBinaryComboOwner(this, dbQueryClause::oofAND,adoptRHS);
125 }
126 
127 
130 {
131  return new dbQueryBinaryComboOwner(this, dbQueryClause::oofAND,adoptRHS);
132 }
133 
134 
135 // -------------------------------------------------------
136 // d b Q u e r y
137 // -------------------------------------------------------
138 dbQuery::dbQuery() : mQuery(0)
139 {
140 }
141 
142 
144 {
145  delete mQuery;
146 }
147 
148 
151 {
152  return new dbQuery(*this);
153 }
154 
155 
156 void
157 dbQuery::describe(ostream& os) const
158 {
159  os << "dbQuery (built query):\t";
160  mQuery->describe(os);
161 }
162 
163 
166 {
167  return builtQuery;
168 }
169 
170 
171 void
173  dbTable*& outDiffFieldTable,
174  dbTable*& outRelatedTable) const
175 {
176  mQuery->getSearchTables(inSchTable, outDiffFieldTable, outRelatedTable);
177 }
178 
179 
184 dbQuery::cloneReplacingTable(const dbTable* inTable, const dbTable* repTable) const
185 {
186  dbQuery* orphanedReturn = 0;
187  dbQueryClause* embeddedNew = mQuery->cloneReplacingTable(inTable, repTable);
188  if (embeddedNew) {
189  orphanedReturn = new dbQuery();
190  *orphanedReturn |= embeddedNew;
191  }
192  return orphanedReturn;
193 }
194 
195 
196 void
198 {
199  if (adoptedBit) {
200  if (mQuery)
201  mQuery = *mQuery || adoptedBit;
202  else
203  mQuery = adoptedBit;
204  }
205 }
206 
207 
208 void
210 {
211  if (adoptedBit) {
212  if (mQuery)
213  mQuery = *mQuery && adoptedBit;
214  else
215  mQuery = adoptedBit;
216  }
217 }
218 
219 
220 // -------------------------------------------------------
221 // d b Q u e r y B i n a r y N o F i e l d
222 // -------------------------------------------------------
224  mRhs(litOrFld),
225  mBinOp(op)
226 {
227 }
228 
229 
231  mBinOp(rhs.mBinOp)
232 {
233  mRhs = rhs.mRhs->clone();
234 }
235 
236 
238 {
239  delete mRhs;
240 }
241 
242 
245 {
246  return new dbQueryBinaryNofield(*this);
247 }
248 
249 
251 dbQueryBinaryNofield::operator=(dbQueryBinaryNofield&)
252 {
253  assert(0); // should never be called
254  return *this;
255 };
256 
257 
258 void
260 {
261  os << "dbQueryBinaryNofield:\t";
262  os << mBinOp << '\t';
263  mRhs->describe(os);
264 }
265 
266 
269 {
270  return entireTable;
271 }
272 
273 
274 
277 {
279  return (dbQueryLiteralStr*) mRhs; // safe downcast
280  else
281  return 0;
282 }
283 
284 
287 {
289  return (dbQueryLiteralStrMultiValue*) mRhs; // safe downcast
290  else
291  return 0;
292 }
293 
294 
297 {
298 // NOTE the following assumes that logic to handle binary logical clauses is a superset of
299 // that handling strings, and if the difference is important we have tried literalStrClause()
300 // BEFORE trying this routine
302  return (dbQueryLiteral*) mRhs; // safe downcast, actually to a parent of the exact type (a dbQueryLiteralLong etc.)
303  else
304  return 0;
305 }
306 
307 
308 // -------------------------------------------------------
309 // d b Q u e r y B i n a r y
310 // -------------------------------------------------------
312  dbQueryBinaryNofield(op,litOrFld),
313  mLhs(fld)
314 {
315  assert(fld->field() && !fld->field()->fieldIsStandalone());
316 }
317 
318 
321 {
322  mLhs = (dbQueryField*) rhs.mLhs->clone(); // safe downcast
323 }
324 
325 
327 {
328  delete mLhs;
329 }
330 
331 
334 {
335  return new dbQueryBinary(*this);
336 }
337 
338 
340 dbQueryBinary::operator=(dbQueryBinary&)
341 {
342  assert(0); // should never be called
343  return *this;
344 };
345 
346 
347 void
348 dbQueryBinary::describe(ostream& os) const
349 {
350  os << "dbQueryBinary:\t";
351  mLhs->describe(os);
352  os << '\t' << mBinOp << '\t';
353  mRhs->describe(os);
354 }
355 
356 
359 {
361  return binaryfieldTofield;
362  else
363  return binaryfieldToLiteral;
364 }
365 
366 
367 void
369  dbTable*& outDiffFieldTable,
370  dbTable*& outRelatedTable) const
371 {
372  mLhs->getSearchTables(inSchTable, outDiffFieldTable, outRelatedTable);
373 }
374 
375 
381 dbQueryBinary::cloneReplacingTable(const dbTable* inTable, const dbTable* repTable) const
382 {
383  dbQueryClause* orphanedReturn = 0;
384  assert(mLhs->queryClauseType()==atomicfield);
385  dbQueryField* lhsNew = (dbQueryField*) (mLhs->cloneReplacingTable(inTable, repTable)); // safe downcast
386  if (lhsNew) {
387  orphanedReturn = new dbQueryBinary(lhsNew, mBinOp, mRhs->clone());
388  }
389  return orphanedReturn;
390 }
391 
392 
393 bool
395 {
397  return false;
398 
399  const dbField* schField = lhsField();
400  if (!schField->fieldIsIndexed())
401  return false;
402 
403  if (schField->fieldType() != charField)
404  return true; // binary indexed field!
405 
406  if (binaryOperator() != equals &&
407  binaryOperator() != startsWith &&
409  )
410  return true; // indexed and can't be wildcard
411 
413  assert(strRHS); // as lhs is char field
414  return strRHS->hasWildcards();
415 }
416 
417 
418 // -------------------------------------------------------
419 // d b Q u e r y B i n a r y C o m b o
420 // -------------------------------------------------------
422  mLhs(lhs),
423  mRhs(rhs),
424  mComboOp(op),
425  mTempKeyStoreToDispose(0),
426  mTempKeyStoreToDispose2(0)
427  {}
428 
429 
431 {
432  delete[] mTempKeyStoreToDispose;
433  delete[] mTempKeyStoreToDispose2;
434 }
435 
436 
439 {
440  return new dbQueryBinaryCombo(*this);
441 }
442 
443 
445  mLhs(rhs.mLhs),
446  mRhs(rhs.mRhs),
447  mComboOp(rhs.mComboOp),
448  mTempKeyStoreToDispose(0),
449  mTempKeyStoreToDispose2(0)
450 {}
451 
452 
457 dbQueryBinaryCombo::cloneReplacingTable(const dbTable* inTable, const dbTable* repTable) const
458 {
459  dbQueryClause* orphanedReturn = 0;
460  dbQueryClause* lhsNew = mLhs->cloneReplacingTable(inTable, repTable);
461  dbQueryClause* rhsNew = mRhs->cloneReplacingTable(inTable, repTable);
462  if (lhsNew || rhsNew) {
463  if (!lhsNew)
464  lhsNew = mLhs->clone();
465  if (!rhsNew)
466  rhsNew = mRhs->clone();
467  orphanedReturn = new dbQueryBinaryCombo(lhsNew, mComboOp, rhsNew);
468  }
469  return orphanedReturn;
470 }
471 
473 dbQueryBinaryCombo::operator=(dbQueryBinaryCombo&)
474 {
475  assert(0); // should never be called
476  return *this;
477 };
478 
479 
480 void
482 {
483  os << "dbQueryBinaryCombo:\t";
484  mLhs->describe(os);
485  os << '\t' << mComboOp << '\t';
486  mRhs->describe(os);
487 }
488 
489 
492 {
493  return binaryCombination;
494 }
495 
496 
497 const dbQueryClause*
498 dbQueryBinaryCombo::item(unsigned int i) const
499 {
500  assert(i<2); // for now, later will have a list of items
501  if (i==0)
502  return mLhs;
503  else
504  return mRhs;
505 }
506 
507 
508 unsigned long
510 {
511  if (mComboOp != oofAND)
512  return 0; // early failure - they're not ANDed
513 
515  return 0;
516 
518  return 0;
519 
520  dbQueryBinary* lhs = (dbQueryBinary*) mLhs; // safe downcast due to above tests
521  if (lhs->binaryOperator() != equals)
522  return 0;
523 
524  dbQueryBinary* rhs = (dbQueryBinary*) mRhs; // safe downcast due to above tests
525  if (rhs->binaryOperator() == notEquals)
526  return 0;
527 
528 // if get here have an expression that CAN be used with a compound index
529 // ie: A==a && B==b -> == ab
530 // A==a && B.startsWith(b) -> startsWith(ab)
531 // A==a && B>=b -> between(ab, a+)
532 
533  const dbField* fld = lhs->lhsField();
534  unsigned long ret = fld->fieldNumber();
535  fld = rhs->lhsField();
536  ret = (ret << 16) + fld->fieldNumber();
537  return ret;
538 }
539 
540 
543 {
544 // this gets a little complicated:
545 // we make this look like a string query, BUT
546 // either of our components can really be binary values
547 // and we also must pad out the LHS to its full key width
548 
549 // WARNING this is only partially implemented, mainly for 2nd being > dbDate
550  assert(fld->fieldStorageLen()<USHRT_MAX);
551  const unsigned short keyLen = fld->fieldStorageLen();
552  const unsigned short firstFieldLen = fld->field(0)->fieldStorageLen();
553  char* target = new char[keyLen]; // uh oh - we need to delete this after the query succeeds!
554  assert(target);
555  delete[] mTempKeyStoreToDispose; // just in case we are reusing a query object somehow
556  delete[] mTempKeyStoreToDispose2;
559 
561  dbQueryLiteral* lit = ((dbQueryBinary*) mLhs)->literalClause(); // safe downcast
562  assert(lit);
563  memset(target, 0, keyLen); // clear the entire compound key width
564 // NOT YET IMPLEMENTED - would be a loop for more than 2 segments
565  memcpy(target, lit->binaryContents(), lit->literalLen());
566  #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
568  #endif
569 
571  dbQueryBinary* rhs = (dbQueryBinary*) mRhs; // safe downcast
572  dbQueryLiteral* finalLit = rhs->literalClause();
573 
574  BinaryQueryOps theOp = rhs->binaryOperator();
575  if (fld->segment(1)->isReversed()) // need to swap the sense of some ops
576  switch(theOp) {
577  case greaterThan:
578  theOp = lessThan;
579  break;
580 
581  case greaterThanOrEqual:
582  theOp = lessThanOrEqual;
583  break;
584 
585  case lessThan:
586  theOp = greaterThan;
587  break;
588 
589  case lessThanOrEqual:
590  theOp = greaterThanOrEqual;
591  break;
592 
593  default:
594  assert(theOp==equals || theOp==startsWith);
595  break;
596  }
597 
598  switch(theOp) {
599  case greaterThan:
600  case greaterThanOrEqual:
601  mTempKeyStoreToDispose2 = target; // and fill 2nd field with 0xFF
602  target += firstFieldLen;
603  memset(target, 0xFF, keyLen-firstFieldLen);
604 
605  target = new char[keyLen];
606  assert(target);
607  mTempKeyStoreToDispose = target;
608  memset(target, 0, keyLen); // clear the entire compound key width
609  // NOT YET IMPLEMENTED - would be a loop for more than 2 segments
610  memcpy(target, lit->binaryContents(), lit->literalLen());
611  #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
613  #endif
614  target += firstFieldLen;
615  memcpy(target, finalLit->binaryContents(), finalLit->literalLen());
616  if (theOp == greaterThan) // HORRIBLE HACK THAT ONLY WORKS ON DATES
617  mTempKeyStoreToDispose2[keyLen-1] = (char) 0xFF; // EFFECTIVE INCREMENT may now work on int, real etc.
621  break;
622 
623 
624  default: // for now
625  mTempKeyStoreToDispose = target;
626  target += firstFieldLen;
627  memcpy(target, finalLit->binaryContents(), finalLit->literalLen());
628  #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
630  #endif
631  return new dbQueryBinary(new dbQueryField(fld),
632  rhs->binaryOperator(),
634  );
635  }
636 }
637 
638 
639 
640 // -------------------------------------------------------
641 // d b Q u e r y B i n a r y C o m b o O w n e r
642 // -------------------------------------------------------
644  dbQueryBinaryCombo(lhs, op, rhs),
645  mOurLhs(lhs),
646  mOurRhs(rhs)
647  {}
648 
649 
651 {
652  delete mOurLhs;
653  delete mOurRhs;
654 }
655 
656 
659 {
660  return new dbQueryBinaryComboOwner(*this);
661 }
662 
663 
664 void
666 {
667  os << "dbQueryBinaryComboOwner:\t";
668  mOurLhs->describe(os);
669  os << '\t' << mComboOp << '\t';
670  mOurRhs->describe(os);
671 }
672 
673 
674 // -------------------------------------------------------
675 // d b Q u e r y T r i n a r y
676 // -------------------------------------------------------
677 // NOTE there is a lot of horrible code in this class
678 // it is offensively coarse, but reasonably efficient and a long way
679 // down the priority list for a rewrite.
681  mTrinOp(rhs.mTrinOp)
682 {
683  mLhs = (dbQueryField*) rhs.mLhs->clone(); // safe downcast
684  mFrom = rhs.mFrom->clone();
685  mTo = rhs.mTo->clone();
686 }
687 
688 
690 {
691  delete mLhs;
692  delete mFrom;
693  delete mTo;
694 }
695 
696 
699 {
700  return new dbQueryTrinary(*this);
701 }
702 
703 
705 dbQueryTrinary::operator=(dbQueryTrinary&)
706 {
707  assert(0); // should never be called
708  return *this;
709 };
710 
711 
712 void
713 dbQueryTrinary::describe(ostream& os) const
714 {
715  os << "dbQueryTrinary:\t";
716  mLhs->describe(os);
717  os << '\t';
718  mFrom->describe(os);
719  os << '\t' << mTrinOp << '\t';
720  mTo->describe(os);
721 }
722 
723 
726 {
727  return trinaryFieldToLiterals;
728 }
729 
730 
731 void
733  dbTable*& outDiffFieldTable,
734  dbTable*& outRelatedTable) const
735 {
736  mLhs->getSearchTables(inSchTable, outDiffFieldTable, outRelatedTable);
737 }
738 
739 
740 
746 dbQueryTrinary::cloneReplacingTable(const dbTable* inTable, const dbTable* repTable) const
747 {
748  dbQueryClause* orphanedReturn = 0;
749  assert(mLhs->queryClauseType()==atomicfield);
750  dbQueryField* lhsNew = (dbQueryField*) (mLhs->cloneReplacingTable(inTable, repTable)); // safe downcast
751  if (lhsNew) {
752  orphanedReturn = new dbQueryTrinary(lhsNew, mTrinOp, mFrom->clone(), mTo->clone());
753  }
754  return orphanedReturn;
755 }
756 
757 
760 {
762  return (dbQueryLiteralStr*) mFrom; // safe downcast
763  else
764  return 0;
765 }
766 
767 
770 {
772  return (dbQueryLiteralStr*) mTo; // safe downcast
773  else
774  return 0;
775 }
776 
777 
780 {
782  return (dbQueryLiteral*) mFrom; // safe downcast
783  return 0;
784 }
785 
786 
789 {
791  return (dbQueryLiteral*) mTo; // safe downcast
792  else
793  return 0;
794 }
795 
796 
797 // -------------------------------------------------------
798 // d b Q u e r y F i e l d
799 // -------------------------------------------------------
801 {
802  mField=0; // for Lint
803 }
804 
807 {
808  return new dbQueryField(*this);
809 }
810 
811 
814 {
815  return atomicfield;
816 }
817 
818 
819 void
820 dbQueryField::describe(ostream& os) const
821 {
822  os << "dbQueryField:\t" << mField->fieldTable()->tableName() << '\t' << mField->fieldName();
823 }
824 
825 
834 void
835 dbQueryField::getSearchTables(const dbTable* inSchTable, dbTable*& outDiffFieldTable, dbTable*& outRelatedTable) const
836 {
837  outRelatedTable = outDiffFieldTable = 0;
838  dbTable* maybeTable = mField->fieldTable();
839  if (maybeTable==inSchTable)
840  return; // NOT on related table, it's on the search table (the usual simple case)
841 
842  // field is not same table as searching
843  outDiffFieldTable = maybeTable;
844  dbTable* relatedTable = maybeTable->lhsTableInRelationshipSpec();
845  if (relatedTable &&
846  (relatedTable->baseTableOfRelationChain()==inSchTable) // for MN and other complex related searches
847  ){
848  outRelatedTable = relatedTable;
849  return;
850  }
851  else {
852  if (maybeTable->tableNumber() == inSchTable->tableNumber())
853  return; // still not right but caller can cope
854  }
855 
856 // NOT YET IMPLEMENTED - work out if table is related to inTable anyway
857 // but they have not qualified it, eg: Patients.search(Visits.Date=="1/1/96");
858  dbConnect::raise(stringstream() << flush
859  << "dbQueryField::relatedTable on field " << mField->fieldName()
860  << " in table " << maybeTable->tableName()
861  << " is not related to target table " << inSchTable->tableName(),
862  false /* not necessarily fatal */
863  );
864 }
865 
866 
871 dbQueryField::cloneReplacingTable(const dbTable* inTable, const dbTable* repTable) const
872 {
873  dbQueryClause* orphanedReturn = 0;
874  dbTable* maybeTable = mField->fieldTable();
875  if (maybeTable->tableNumber() == inTable->tableNumber())
876  {
877  dbField* fieldInRepTable = repTable->field (mField->fieldNumber());
878  orphanedReturn = new dbQueryField(fieldInRepTable);
879  }
880  return orphanedReturn;
881 }
882 
883 
884 
885 
886 
887 // -------------------------------------------------------
888 // d b Q u e r y L i t e r a l
889 // -------------------------------------------------------
892 {
893  return atomicLiteral;
894 }
895 
896 
897 const void*
899 {
900  return 0;
901 }
902 
903 
904 unsigned short
906 {
907  return 0;
908 }
909 
910 
911 // -------------------------------------------------------
912 // d b Q u e r y L i t e r a l L o n g
913 // -------------------------------------------------------
916 {
917  return new dbQueryLiteralLong(*this);
918 }
919 
920 
921 const void*
923 {
924  return &mNum;
925 }
926 
927 
928 void
930 {
931  os << "dbQueryLiteralDouble:\t" << mNum;
932 }
933 
934 
935 unsigned short
937 {
938  return sizeof(long);
939 }
940 
941 
942 
943 // -------------------------------------------------------
944 // d b Q u e r y L i t e r a l U l o n g
945 // -------------------------------------------------------
948 {
949  return new dbQueryLiteralUlong(*this);
950 }
951 
952 
953 const void*
955 {
956  return &mNum;
957 }
958 
959 
960 void
962 {
963  os << "dbQueryLiteralUlong:\t" << mNum;
964 }
965 
966 
967 unsigned short
969 {
970  return sizeof(unsigned long);
971 }
972 
973 
974 
975 // -------------------------------------------------------
976 // d b Q u e r y L i t e r a l S h o r t
977 // -------------------------------------------------------
980 {
981  return new dbQueryLiteralShort(*this);
982 }
983 
984 
985 const void*
987 {
988  return &mNum;
989 }
990 
991 
992 void
994 {
995  os << "dbQueryLiteralShort:\t" << mNum;
996 }
997 
998 
999 unsigned short
1001 {
1002  return sizeof(short);
1003 }
1004 
1005 
1006 
1007 // -------------------------------------------------------
1008 // d b Q u e r y L i t e r a l U s h o r t
1009 // -------------------------------------------------------
1010 dbQueryClause*
1012 {
1013  return new dbQueryLiteralUshort(*this);
1014 }
1015 
1016 
1017 const void*
1019 {
1020  return &mNum;
1021 }
1022 
1023 
1024 void
1026 {
1027  os << "dbQueryLiteralUshort:\t" << mNum;
1028 }
1029 
1030 
1031 unsigned short
1033 {
1034  return sizeof(unsigned short);
1035 }
1036 
1037 
1038 
1039 // -------------------------------------------------------
1040 // d b Q u e r y L i t e r a l D o u b l e
1041 // -------------------------------------------------------
1042 dbQueryClause*
1044 {
1045  return new dbQueryLiteralDouble(*this);
1046 }
1047 
1048 
1049 const void*
1051 {
1052  return &mNum;
1053 }
1054 
1055 
1056 void
1058 {
1059  os << "dbQueryLiteralDouble:\t" << mNum;
1060 }
1061 
1062 
1063 unsigned short
1065 {
1066  return sizeof(double);
1067 }
1068 
1069 
1070 
1071 // -------------------------------------------------------
1072 // d b Q u e r y L i t e r a l B L O B
1073 // -------------------------------------------------------
1075 {
1076  mBLOB=0; // for Lint
1077 }
1078 
1079 dbQueryClause*
1081 {
1082  return new dbQueryLiteralBLOB(*this);
1083 }
1084 
1085 
1086 const void*
1088 {
1089  return mBLOB;
1090 }
1091 
1092 
1093 void
1095 {
1096  os << "dbQueryLiteralBLOB:\n";
1097 }
1098 
1099 
1100 unsigned short
1102 {
1103  return mBLOBlen;
1104 }
1105 
1106 
1107 
1108 // -------------------------------------------------------
1109 // d b Q u e r y L i t e r a l S t r
1110 // -------------------------------------------------------
1111 dbQueryClause*
1113 {
1114  return new dbQueryLiteralStr(*this);
1115 }
1116 
1117 
1120 {
1121  return atomicLiteralStr;
1122 }
1123 
1124 
1125 const void*
1127 {
1128  return mStr;
1129 }
1130 
1131 
1132 void
1134 {
1135  os << "dbQueryLiteralStr:\t" << mStr;
1136 }
1137 
1138 
1139 unsigned short
1141 {
1142  if (!mStr)
1143  return 0;
1144  return strlen(mStr);
1145 }
1146 
1147 
1148 bool
1150 {
1151  if (mCheckedForWildcards == neverChecked) {
1152  assert(mStr);
1154  mCheckedForWildcards = hasWild;
1155  else
1156  mCheckedForWildcards = hasNone;
1157  }
1158  return (mCheckedForWildcards == hasWild);
1159 
1160 }
1161 
1162 
1163 // -------------------------------------------------------
1164 // d b Q u e r y L i t e r a l S t r M u l t i V a l u e
1165 // -------------------------------------------------------
1168 {
1169  return multiLiteralStr;
1170 }
1171 
1172 
1173 // -------------------------------------------------------
1174 // d b Q u e r y L i t e r a l S t r A r r a y
1175 // -------------------------------------------------------
1177 {
1178  mSchStrs=0; // for Lint
1179 }
1180 
1181 dbQueryClause*
1183 {
1184  return new dbQueryLiteralStrArray(*this);
1185 }
1186 
1187 
1188 void
1190 {
1191  mIter = 0;
1192 }
1193 
1194 
1195 bool
1197 {
1198  return mIter < mCount;
1199 }
1200 
1201 
1202 void
1204 {
1205  mIter++;
1206 }
1207 
1208 
1209 const char*
1211 {
1212  return mSchStrs[mIter];
1213 }
1214 
1215 
1216 void
1218 {
1219  os << "dbQueryLiteralStrArray:\t";
1220  for (unsigned long i=0; i<mCount; i++) {
1221  os << mSchStrs[i] << '\t';
1222  }
1223 }
1224 
1225 
1226 // -------------------------------------------------------
1227 // d b Q u e r y L i t e r a l S t r D e l i m i t e d
1228 // -------------------------------------------------------
1230 {
1231  mStr=0; // for Lint
1232  mEndStr=0;
1233  mReadFrom=0;
1234 }
1235 
1236 dbQueryClause*
1238 {
1239  return new dbQueryLiteralStrDelimited(*this);
1240 }
1241 
1242 
1243 void
1245 {
1246  mReadFrom = mStr;
1247  mStrLen = strlen(mStr);
1248  mEndStr = mStr+mStrLen;
1249  CalcWordLen();
1250 }
1251 
1252 
1253 bool
1255 {
1256  return mReadFrom < mEndStr;
1257 }
1258 
1259 
1260 void
1262 {
1263  mReadFrom += mWordLen; // should be pointing at delimiter
1264  assert((mReadFrom>=mEndStr) || (*mReadFrom==mDelim));
1265  mReadFrom++; // skip delimiter
1266  CalcWordLen();
1267 }
1268 
1269 
1270 const char*
1272 {
1273  mCurrent.setChars(mReadFrom, mWordLen);
1274  return mCurrent;
1275 }
1276 
1277 
1278 void
1279 dbQueryLiteralStrDelimited::CalcWordLen()
1280 {
1281  mWordLen=0;
1282  for (const char* ip = mReadFrom; ip < mEndStr && *ip!=mDelim; ip++)
1283  mWordLen++;
1284 }
1285 
1286 
1287 void
1289 {
1290  os << "dbQueryLiteralStrDelimited:\t" << mStr;
1291 }
1292 
1293 
1294 // -------------------------------------------------------
1295 // B i n a r y Q u e r y O p s
1296 // -------------------------------------------------------
1297 ostream&
1299 {
1300  switch (st) {
1301  case (dbQueryClause::equals) :
1302  os << "equals";
1303  break;
1304 
1305  case (dbQueryClause::notEquals) :
1306  os << "notEquals";
1307  break;
1308 
1309  case (dbQueryClause::lessThan) :
1310  os << "lessThan";
1311  break;
1312 
1314  os << "lessThanOrEqual";
1315  break;
1316 
1318  os << "greaterThan";
1319  break;
1320 
1322  os << "greaterThanOrEqual";
1323  break;
1324 
1325  case (dbQueryClause::startsWith) :
1326  os << "startsWith";
1327  break;
1328 
1329  case (dbQueryClause::hasWord) :
1330  os << "hasWord";
1331  break;
1332 
1333  case (dbQueryClause::hasAnyWord) :
1334  os << "hasAnyWord";
1335  break;
1336 
1338  os << "hasAllWords";
1339  break;
1340 
1342  os << "hasWordStartsWith";
1343  break;
1344 
1346  os << "hasAnyWordStartsWith";
1347  break;
1348 
1349  default :
1350  os << "hasAllWordsStartsWith";
1351  }
1352  return os;
1353 }
1354 
1355 
1356 // -------------------------------------------------------
1357 // T r i n a r y Q u e r y O p s
1358 // -------------------------------------------------------
1359 ostream&
1361 {
1362  switch (st) {
1363  case (dbQueryClause::between) :
1364  os << "between";
1365  break;
1366 
1367  default :
1368  os << "outside";
1369  }
1370  return os;
1371 }
1372 
1373 
1374 // -------------------------------------------------------
1375 // Q u e r y C o m b i n a t o r i a l O p s
1376 // -------------------------------------------------------
1377 ostream&
1379 {
1380  switch (st) {
1381  case (dbQueryClause::oofAND) :
1382  os << "and";
1383  break;
1384 
1385  default :
1386  os << "or";
1387  }
1388  return os;
1389 }
1390 
1391 
1392 
1393 
1394 // -------------------------------------------------------
1395 // Q u e r y C l a u s e T y p e s
1396 // -------------------------------------------------------
1397 ostream&
1399 {
1400  switch (st) {
1402  os << "binaryfieldToLiteral";
1403  break;
1404 
1406  os << "binaryfieldToLiteral";
1407  break;
1408 
1410  os << "binaryfieldToLiteral";
1411  break;
1412 
1414  os << "binaryfieldToLiteral";
1415  break;
1416 
1418  os << "binaryfieldToLiteral";
1419  break;
1420 
1422  os << "binaryfieldToLiteral";
1423  break;
1424 
1426  os << "binaryfieldToLiteral";
1427  break;
1428 
1430  os << "binaryfieldToLiteral";
1431  break;
1432 
1434  os << "binaryfieldToLiteral";
1435  break;
1436 
1437  default :
1438  os << "builtQuery";
1439  }
1440  return os;
1441 }
virtual void getSearchTables(const dbTable *inSchTable, dbTable *&outDiffFieldTable, dbTable *&outRelatedTable) const
Find tables on which we are searching, if not simply the field's table.
Definition: oofquery.cpp:835
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:157
dbQueryField(const dbField *fld)
Definition: oofquery.h:575
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:259
const dbField * lhsField() const
Definition: oofquery.h:620
dbQueryLiteralStrMultiValue * literalMultiStrClause() const
Definition: oofquery.cpp:286
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:713
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
conditionally clone if LHS clause requires replacement.
Definition: oofquery.cpp:381
virtual const char * current()
Definition: oofquery.cpp:1271
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:806
virtual void start()
Definition: oofquery.cpp:1189
virtual const void * binaryContents() const
Definition: oofquery.cpp:1050
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1094
static void raise(std::ostream &, bool terminateAfterMsg=true)
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:491
fieldNumT fieldNumber() const
Definition: oof3.h:754
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:244
virtual void describe(std::ostream &) const =0
virtual const oofString & fieldName() const
Definition: oof3.h:769
precompilation header.
tableNumT tableNumber() const
Definition: oof1.h:2376
Binary query combining two sub-queries.
Definition: oofquery.h:203
Tries to hide the different platforms and version issues with standard IO.
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:947
virtual ~dbQueryField()
Definition: oofquery.cpp:800
dbQueryLiteralUlong(unsigned long l)
Definition: oofquery.h:505
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:658
BinaryQueryOps mBinOp
Definition: oofquery.h:156
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
conditionally clone if embedded query requires replacement.
Definition: oofquery.cpp:184
virtual void getSearchTables(const dbTable *inSchTable, dbTable *&outDiffFieldTable, dbTable *&outRelatedTable) const
Definition: oofquery.cpp:368
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
conditionally clone if LHS or RHS clause requires replacement.
Definition: oofquery.cpp:457
Highest level used to assemble queries.
Definition: oofquery.h:46
virtual unsigned short literalLen() const
Definition: oofquery.cpp:1000
dbQueryBinary(dbQueryField *fld, BinaryQueryOps op, dbQueryClause *litOrFld)
Definition: oofquery.cpp:311
char * mTempKeyStoreToDispose2
Definition: oofquery.h:233
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:891
dbQueryBinaryCombo operator|(const dbQueryClause &) const
Definition: oofquery.cpp:94
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:1119
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:438
const dbField * field(unsigned int) const
Definition: oof3.cpp:2413
virtual bool fieldIsIndexed() const
Definition: oof3.cpp:408
bool fieldIsStandalone() const
Definition: oof3.h:733
virtual unsigned short literalLen() const
Definition: oofquery.cpp:936
dbQueryLiteralStr * literalStrToClause() const
Definition: oofquery.cpp:769
virtual unsigned short literalLen() const
Definition: oofquery.cpp:1064
virtual unsigned long fieldStorageLen() const
Definition: oof3.cpp:2390
dbQueryClause * mRhs
Definition: oofquery.h:155
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1112
dbQueryClause::BinaryQueryOps binaryOperator() const
Definition: oofquery.h:610
Abstract base for string fragment queries like OOF_mixKeywordableField::hasAnyWordsOf.
Definition: oofquery.h:355
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1080
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:993
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:665
virtual unsigned long fieldStorageLen() const =0
dbQueryLiteral * literalToClause() const
Definition: oofquery.cpp:788
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:813
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:725
Common trinary query for field, eg: People.Salary.between(50000, 90000); Very similar to dbQueryBinar...
Definition: oofquery.h:263
virtual void getSearchTables(const dbTable *inSchTable, dbTable *&outDiffFieldTable, dbTable *&outRelatedTable) const
Definition: oofquery.cpp:41
virtual unsigned short literalLen() const
Definition: oofquery.cpp:968
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:820
virtual const char * current()
Definition: oofquery.cpp:1210
bool isSimpleIndexedSearch() const
Definition: oofquery.cpp:65
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:915
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
conditionally clone if LHS clause requires replacement.
Definition: oofquery.cpp:746
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
Definition: oofquery.cpp:48
virtual ~dbQueryLiteralBLOB()
Definition: oofquery.cpp:1074
dbQueryBinaryNofield(BinaryQueryOps op, dbQueryClause *litOrFld)
Definition: oofquery.cpp:223
bool isReversed() const
Definition: oof3.h:958
virtual ~dbQueryLiteralStrDelimited()
Definition: oofquery.cpp:1229
virtual ~dbQueryTrinary()
Definition: oofquery.cpp:689
void operator|=(dbQueryClause *adoptedPortion)
Definition: oofquery.cpp:197
dbQueryLiteralStrDelimited(const char *str, char delim)
Definition: oofquery.h:371
static bool wildcardsInString(const char *)
Definition: oofquery.cpp:55
virtual unsigned short literalLen() const
Definition: oofquery.cpp:1032
virtual const void * binaryContents() const
Definition: oofquery.cpp:986
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:961
Common binary query for field, eg: People.Salary > 90000.
Definition: oofquery.h:165
const dbQueryClause * mRhs
Definition: oofquery.h:231
virtual unsigned short literalLen() const
Definition: oofquery.cpp:905
dbQueryBinaryCombo(const dbQueryClause *, QueryCombinatorialOps, const dbQueryClause *)
Definition: oofquery.cpp:421
unsigned long pairFieldsIfCouldUseCompoundIndex() const
Definition: oofquery.cpp:509
virtual ~dbQueryBinary()
Definition: oofquery.cpp:326
bool isSimpleIndexedSearch() const
Definition: oofquery.cpp:394
Builder class used to combine sub-queries when constructing runtime queries.
Definition: oofquery.h:244
virtual dbQueryClause * clone() const =0
LHS argument to queries on fields.
Definition: oofquery.h:572
virtual ~dbQueryLiteralStrArray()
Definition: oofquery.cpp:1176
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:358
dbTable * baseTableOfRelationChain()
Definition: oof1.cpp:1984
dbQueryLiteralStr * literalStrClause() const
Definition: oofquery.cpp:276
virtual const void * binaryContents() const
Definition: oofquery.cpp:1126
virtual ~dbQuery()
Definition: oofquery.cpp:143
dbQueryLiteral * literalFromClause() const
Definition: oofquery.cpp:779
virtual const void * binaryContents() const
Definition: oofquery.cpp:898
static char sWildcardMultiple
Definition: oofquery.h:86
QueryCombinatorialOps
Definition: oofquery.h:51
char * mTempKeyStoreToDispose
Definition: oofquery.h:233
virtual bool more()
Definition: oofquery.cpp:1196
class for building queries of arbitrary complexity with application logic.
Definition: oofquery.h:101
TrinaryQueryOps mTrinOp
Definition: oofquery.h:299
const dbQueryClause * mLhs
Definition: oofquery.h:231
dbQueryLiteralStrArray(const char **schStrs, unsigned long count)
Definition: oofquery.h:405
Argument mainly used to support compound key queries ending in binary number.
Definition: oofquery.h:454
virtual const void * binaryContents() const
Definition: oofquery.cpp:954
const oofString & tableName() const
Definition: oof1.h:2369
dbQueryBinaryCombo operator&&(const dbQueryClause &) const
Definition: oofquery.cpp:87
dbQueryBinaryCombo operator||(const dbQueryClause &) const
Definition: oofquery.cpp:101
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1217
dbQueryLiteralShort(short s)
Definition: oofquery.h:528
dbQueryBinaryCombo operator&(const dbQueryClause &) const
Definition: oofquery.cpp:80
dbQueryClause * mFrom
Definition: oofquery.h:298
OOF_Segment * segment(unsigned int) const
Definition: oof1.h:2592
dbField * field(fieldNumT) const
Definition: oof1.h:2355
Persistent field used to store a set of segments referring to other fields.
Definition: oof3.h:575
Declare query classes.
Base class for persistent tables.
Definition: oof1.h:452
dbQueryLiteral * literalClause() const
Definition: oofquery.cpp:296
dbTable * fieldTable() const
Definition: oof3.cpp:308
Definition: oof3.h:26
virtual unsigned short literalLen() const
Definition: oofquery.cpp:1101
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1043
virtual void getSearchTables(const dbTable *inSchTable, dbTable *&outDiffFieldTable, dbTable *&outRelatedTable) const
Definition: oofquery.cpp:172
void setChars(const char *, unsigned long)
Replace current contents of string with incoming buffer.
Definition: oofstr.cpp:624
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1025
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:268
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:481
dbQueryClause * makeCompoundSearch(const dbCompoundField *)
Definition: oofquery.cpp:542
static bool isWordSearch(dbQueryClause::BinaryQueryOps)
Definition: oofquery.cpp:72
const dbField * mField
Definition: oofquery.h:591
dbQueryLiteralBLOB(void *blob, unsigned short len)
Definition: oofquery.h:456
dbQueryLiteralLong(long l)
Definition: oofquery.h:482
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:698
dbQueryLiteralStr * literalStrFromClause() const
Definition: oofquery.cpp:759
#define OOF_MEM_DEBUG_FORCE_POOL_CHECK
Definition: doxyoof.h:408
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:348
virtual void next()
Definition: oofquery.cpp:1203
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1288
static char sWildcardSingle
Definition: oofquery.h:87
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1182
RHS String argument to queries on fields like dbChar.
Definition: oofquery.h:324
virtual const void * binaryContents() const
Definition: oofquery.cpp:1087
virtual dbQueryClause * cloneReplacingTable(const dbTable *inTable, const dbTable *repTable) const
conditionally clone if embedded query requires replacement.
Definition: oofquery.cpp:871
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1133
std::ostream & operator<<(std::ostream &, const oofE_Base &)
dbQueryLiteralDouble(double d)
Definition: oofquery.h:433
dbQueryTrinary(dbQueryField *fld, TrinaryQueryOps op, dbQueryClause *litOrFldFrom, dbQueryClause *litOrFldTo)
Definition: oofquery.h:265
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:165
virtual OOF_fieldTypes fieldType() const =0
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:1057
dbQueryClause * mTo
Definition: oofquery.h:298
void operator&=(dbQueryClause *adoptedPortion)
Definition: oofquery.cpp:209
dbTable * lhsTableInRelationshipSpec() const
Definition: oof1.cpp:1974
virtual const void * binaryContents() const
Definition: oofquery.cpp:922
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:979
virtual void getSearchTables(const dbTable *inSchTable, dbTable *&outDiffFieldTable, dbTable *&outRelatedTable) const
Definition: oofquery.cpp:732
virtual ~dbQueryBinaryComboOwner()
Definition: oofquery.cpp:650
QueryCombinatorialOps mComboOp
Definition: oofquery.h:232
dbQueryField * mLhs
Definition: oofquery.h:297
virtual ~dbQueryBinaryCombo()
Definition: oofquery.cpp:430
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:333
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:150
dbQueryLiteralUshort(unsigned short s)
Definition: oofquery.h:551
Binary query where LHS is table, eg: dbTable::hasAllWordsDelimited.
Definition: oofquery.h:130
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1237
virtual ~dbQueryBinaryNofield()
Definition: oofquery.cpp:237
dbQueryLiteralStr(const char *inStr)
Definition: oofquery.h:326
const dbQueryClause * item(unsigned int) const
Definition: oofquery.cpp:498
virtual const void * binaryContents() const
Definition: oofquery.cpp:1018
dbQueryBinaryComboOwner(dbQueryClause *, QueryCombinatorialOps, dbQueryClause *)
Definition: oofquery.cpp:643
Base for the RHS arguments to combinatorial queries dbQueryBinary, dbQueryTrinary.
Definition: oofquery.h:307
Base class for persistent fields in dbTable's.
Definition: oof3.h:63
virtual dbQueryClause * clone() const
Definition: oofquery.cpp:1011
virtual void describe(std::ostream &) const
Definition: oofquery.cpp:929
dbQueryField * mLhs
Definition: oofquery.h:194
const dbField * field() const
Definition: oofquery.h:581
virtual dbQueryClause::QueryClauseTypes queryClauseType() const =0
virtual dbQueryClause::QueryClauseTypes queryClauseType() const
Definition: oofquery.cpp:1167
virtual unsigned short literalLen() const
Definition: oofquery.cpp:1140