home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Demos / OOFILE / Buildable, limited OOFILE / OOFILE partial source / oofquery.cpp < prev    next >
Encoding:
Text File  |  1995-09-26  |  10.0 KB  |  431 lines  |  [TEXT/CWIE]

  1. // COPYRIGHT 1994 A.D. Software, All rights reserved
  2.  
  3. // OOFILE database queries
  4.  
  5. #include "oofquery.hpp"
  6. #include "oof3.hpp"
  7. #include <assert.h>
  8.  
  9. // -------------------------------------------------------
  10. //                 d b Q u e r y C l a u s e
  11. // -------------------------------------------------------
  12. dbQueryBinaryCombo dbQueryClause::operator&(dbQueryClause& rhs) const
  13. {
  14.     return dbQueryBinaryCombo(this, dbQueryClause::and, &rhs);
  15. }
  16.  
  17.  
  18. dbQueryBinaryCombo dbQueryClause::operator&&(dbQueryClause& rhs) const
  19. {
  20.     return dbQueryBinaryCombo(this, dbQueryClause::and, &rhs);
  21. }
  22.  
  23.  
  24. dbQueryBinaryCombo dbQueryClause::operator|(dbQueryClause& rhs) const
  25. {
  26.     return dbQueryBinaryCombo(this, dbQueryClause::or, &rhs);
  27. }
  28.  
  29.  
  30. dbQueryBinaryCombo dbQueryClause::operator||(dbQueryClause& rhs) const
  31. {
  32.     return dbQueryBinaryCombo(this, dbQueryClause::or, &rhs);
  33. }
  34.  
  35.  
  36.  
  37. // -------------------------------------------------------
  38. //                 d b Q u e r y B i n a r y 
  39. // -------------------------------------------------------
  40. dbQueryBinary::dbQueryBinary(dbQueryBinary& rhs)
  41. {
  42.     mLhs = rhs.mLhs;
  43.     mRhs = rhs.mRhs;
  44.     mBinOp = rhs.mBinOp;
  45.     rhs.mLhs = 0;
  46.     rhs.mRhs = 0;
  47. }
  48.  
  49.  
  50. dbQueryBinary::~dbQueryBinary()
  51. {
  52.     delete mLhs;
  53.     delete mRhs;
  54. }
  55.  
  56.  
  57. dbQueryBinary& dbQueryBinary::operator=(dbQueryBinary& rhs) 
  58.     assert(0);  // should never be called
  59.     return *this; 
  60. };
  61.  
  62.  
  63. dbQueryClause::QueryClauseTypes  dbQueryBinary::queryClauseType()  const
  64. {
  65.     if (mRhs->queryClauseType()==atomicfield)
  66.         return binaryfieldTofield;
  67.     else
  68.         return binaryfieldToLiteral;
  69. }
  70.  
  71.  
  72. dbQueryLiteralStr* dbQueryBinary::literalStrClause() const
  73. {
  74.     if (mRhs->queryClauseType()==atomicLiteralStr) 
  75.         return (dbQueryLiteralStr*) mRhs;  // safe downcast
  76.     else
  77.         return 0;
  78. }
  79.  
  80.  
  81. dbQueryLiteral* dbQueryBinary::literalClause() const
  82. {
  83. // NOTE the following assumes that logic to handle binary logical clauses is a superset of
  84. // that handling strings, and if the difference is important we have tried literalStrClause()
  85. // BEFORE trying this routine
  86.     if ((mRhs->queryClauseType()==atomicLiteral) || (mRhs->queryClauseType()==atomicLiteralStr))
  87.         return (dbQueryLiteral*) mRhs;  // safe downcast, actually to a parent of the exact type (a dbQueryLiteralLong etc.)
  88.     else
  89.         return 0;
  90. }
  91.  
  92.  
  93.  
  94. // -------------------------------------------------------
  95. //           d b Q u e r y B i n a r y C o m b o
  96. // -------------------------------------------------------
  97. dbQueryBinaryCombo::~dbQueryBinaryCombo()
  98. {
  99.     delete[] mTempKeyStoreToDispose;
  100. }
  101.  
  102.  
  103. dbQueryBinaryCombo::dbQueryBinaryCombo(dbQueryBinaryCombo& rhs)
  104. {
  105.     mLhs = rhs.mLhs;
  106.     mRhs = rhs.mRhs;
  107.     mComboOp = rhs.mComboOp;
  108.     mTempKeyStoreToDispose = 0;
  109. // don't need to clear rhs pointers as not deleted
  110. }
  111.  
  112.  
  113. dbQueryBinaryCombo& dbQueryBinaryCombo::operator=(dbQueryBinaryCombo& rhs) 
  114.     assert(0);  // should never be called
  115.     return *this; 
  116. };
  117.  
  118.  
  119. dbQueryClause::QueryClauseTypes  dbQueryBinaryCombo::queryClauseType()  const
  120. {
  121.     return binaryCombination;
  122. }
  123.  
  124.     
  125. const dbQueryClause* dbQueryBinaryCombo::item(unsigned int i) const
  126. {
  127.     assert(i<2);  // for now, later will have a list of items
  128.     if (i==0)
  129.         return mLhs;
  130.     else
  131.         return mRhs;
  132. }
  133.  
  134.  
  135. unsigned long dbQueryBinaryCombo::pairFieldsIfCouldUseCompoundIndex() const
  136. {
  137.     if (mComboOp != and)
  138.         return 0;  // early failure - they're not ANDed
  139.         
  140.     if (mLhs->queryClauseType() != binaryfieldToLiteral)
  141.         return 0;
  142.         
  143.     if (mRhs->queryClauseType() != binaryfieldToLiteral)
  144.         return 0;
  145.         
  146.     dbQueryBinary* lhs = (dbQueryBinary*) mLhs;  // safe downcast due to above tests 
  147.     if (lhs->binaryOperator() != equals)
  148.         return 0;
  149.         
  150.     dbQueryBinary* rhs = (dbQueryBinary*) mRhs;  // safe downcast due to above tests 
  151.     if (rhs->binaryOperator() != equals) 
  152.         return 0;
  153.         
  154. // if get here have an expression that CAN be used with a compound index
  155. // ie:  A==a && B==b 
  156.     const dbField* fld = lhs->lhsField();
  157.     unsigned long ret = fld->fieldNumber();
  158.     fld = rhs->lhsField();
  159.     ret = (ret << 16) + fld->fieldNumber();
  160.     return ret;
  161. }
  162.  
  163.  
  164. dbQueryBinary dbQueryBinaryCombo::makeCompoundSearch(const dbCompoundField* fld)
  165. {
  166. // this gets a little complicated:
  167. // we make this look like a string query, BUT 
  168. // either of our components can really be binary values
  169. // and we also must pad out the LHS to its full key width
  170.     assert(fld->fieldLen()<USHRT_MAX);
  171.     unsigned short keyLen = fld->fieldLen();
  172.     char* target = new char[keyLen];  // uh oh - we need to delete this after the query succeeds!
  173.     assert(target);
  174.     if (mTempKeyStoreToDispose)
  175.         delete[] mTempKeyStoreToDispose;  // just in case we are reusing a query object somehow
  176.     mTempKeyStoreToDispose = target;
  177.  
  178.     {
  179.         assert(mLhs->queryClauseType() == binaryfieldToLiteral);
  180.         dbQueryLiteral* lit = ((dbQueryBinary*) mLhs)->literalClause();  // safe downcast
  181.         assert(lit);
  182.         memset(target, 0, keyLen);  // clear the entire compound key width
  183.     // NOT YET IMPLEMENTED - would be a loop for more than 2 segments
  184.         memcpy(target, lit->binaryContents(), lit->literalLen());    
  185.         #ifdef OOF_SmartHeap
  186.             MemPoolCheck(MemDefaultPool);
  187.         #endif
  188.     }
  189.     
  190.     assert(mRhs->queryClauseType() == binaryfieldToLiteral);
  191.     dbQueryBinary* rhs = (dbQueryBinary*) mRhs;  // safe downcast
  192.     dbQueryLiteral* finalLit = rhs->literalClause();
  193.     target += fld->segment(0)->fieldLen();
  194.     memcpy(target, finalLit->binaryContents(), finalLit->literalLen());    
  195.     #ifdef OOF_SmartHeap
  196.         MemPoolCheck(MemDefaultPool);
  197.     #endif
  198.     
  199.     return dbQueryBinary(    new dbQueryField(fld), 
  200.                                                 rhs->binaryOperator(), 
  201.                                                 new dbQueryLiteralBLOB(mTempKeyStoreToDispose, keyLen)
  202.                                             );
  203. }
  204.  
  205.  
  206. // -------------------------------------------------------
  207. //                 d b Q u e r y T r i n a r y 
  208. // -------------------------------------------------------
  209. // NOTE there is a lot of horrible code in this class
  210. // it is offensively coarse, but reasonably efficient and a long way
  211. // down the priority list for a rewrite.
  212. dbQueryTrinary::dbQueryTrinary(dbQueryTrinary& rhs)
  213. {
  214.     mLhs = rhs.mLhs;
  215.     mFrom = rhs.mFrom;
  216.     mTo = rhs.mTo;
  217.     mTrinOp = rhs.mTrinOp;
  218.     rhs.mLhs = 0;
  219.     rhs.mFrom = 0;
  220.     rhs.mTo = 0;
  221. }
  222.  
  223.  
  224. dbQueryTrinary::~dbQueryTrinary()
  225. {
  226.     delete mLhs;
  227.     delete mFrom;
  228.     delete mTo;
  229. }
  230.  
  231.  
  232. dbQueryTrinary& dbQueryTrinary::operator=(dbQueryTrinary& rhs) 
  233.     assert(0);  // should never be called
  234.     return *this; 
  235. };
  236.  
  237.  
  238. dbQueryClause::QueryClauseTypes  dbQueryTrinary::queryClauseType()  const
  239. {
  240.         return trinaryFieldToLiterals;
  241. }
  242.  
  243.  
  244. dbQueryLiteralStr* dbQueryTrinary::literalStrFromClause() const
  245. {
  246.     if (mFrom->queryClauseType()==atomicLiteralStr) 
  247.         return (dbQueryLiteralStr*) mFrom;  // safe downcast
  248.     else
  249.         return 0;
  250. }
  251.  
  252.  
  253. dbQueryLiteralStr* dbQueryTrinary::literalStrToClause() const
  254. {
  255.     if (mTo->queryClauseType()==atomicLiteralStr) 
  256.         return (dbQueryLiteralStr*) mTo;  // safe downcast
  257.     else
  258.         return 0;
  259. }
  260.  
  261.  
  262. dbQueryLiteral* dbQueryTrinary::literalFromClause() const
  263. {
  264.     if (mFrom->queryClauseType()==atomicLiteral) 
  265.         return (dbQueryLiteral*) mFrom;  // safe downcast
  266.         return 0;
  267. }
  268.  
  269.     
  270. dbQueryLiteral* dbQueryTrinary::literalToClause() const
  271. {
  272.     if (mTo->queryClauseType()==atomicLiteral) 
  273.         return (dbQueryLiteral*) mTo;  // safe downcast
  274.     else
  275.         return 0;
  276. }
  277.  
  278.     
  279. // -------------------------------------------------------
  280. //                 d b Q u e r y F i e l d
  281. // -------------------------------------------------------
  282. dbQueryClause::QueryClauseTypes  dbQueryField::queryClauseType()  const
  283. {
  284.     return atomicfield;
  285. }
  286.  
  287.  
  288. // -------------------------------------------------------
  289. //                 d b Q u e r y L i t e r a l
  290. // -------------------------------------------------------
  291. dbQueryClause::QueryClauseTypes  dbQueryLiteral::queryClauseType()  const
  292. {
  293.     return atomicLiteral;
  294. }
  295.  
  296.  
  297. const void* dbQueryLiteral:: binaryContents() const
  298. {
  299.     return 0;
  300. }
  301.  
  302.  
  303. unsigned short dbQueryLiteral::literalLen() const
  304. {
  305.     return 0;
  306. }
  307.  
  308.     
  309. // -------------------------------------------------------
  310. //          d b Q u e r y L i t e r a l L o n g
  311. // -------------------------------------------------------
  312. const void* dbQueryLiteralLong:: binaryContents() const
  313. {
  314.     return &mNum;
  315. }
  316.  
  317.  
  318. unsigned short dbQueryLiteralLong::literalLen() const
  319. {
  320.     return sizeof(long);
  321. }
  322.  
  323.  
  324.     
  325. // -------------------------------------------------------
  326. //          d b Q u e r y L i t e r a l U l o n g
  327. // -------------------------------------------------------
  328. const void* dbQueryLiteralUlong:: binaryContents() const
  329. {
  330.     return &mNum;
  331. }
  332.  
  333.  
  334. unsigned short dbQueryLiteralUlong::literalLen() const
  335. {
  336.     return sizeof(unsigned long);
  337. }
  338.  
  339.  
  340.     
  341. // -------------------------------------------------------
  342. //          d b Q u e r y L i t e r a l S h o r t
  343. // -------------------------------------------------------
  344. const void* dbQueryLiteralShort:: binaryContents() const
  345. {
  346.     return &mNum;
  347. }
  348.  
  349.  
  350. unsigned short dbQueryLiteralShort::literalLen() const
  351. {
  352.     return sizeof(short);
  353. }
  354.  
  355.  
  356.     
  357. // -------------------------------------------------------
  358. //          d b Q u e r y L i t e r a l U s h o r t
  359. // -------------------------------------------------------
  360. const void* dbQueryLiteralUshort:: binaryContents() const
  361. {
  362.     return &mNum;
  363. }
  364.  
  365.  
  366. unsigned short dbQueryLiteralUshort::literalLen() const
  367. {
  368.     return sizeof(unsigned short);
  369. }
  370.  
  371.  
  372.     
  373. // -------------------------------------------------------
  374. //         d b Q u e r y L i t e r a l D o u b l e
  375. // -------------------------------------------------------
  376. const void* dbQueryLiteralDouble:: binaryContents() const
  377. {
  378.     return &mNum;
  379. }
  380.  
  381.  
  382. unsigned short dbQueryLiteralDouble::literalLen() const
  383. {
  384.     return sizeof(double);
  385. }
  386.  
  387.  
  388.     
  389. // -------------------------------------------------------
  390. //         d b Q u e r y L i t e r a l B L O B
  391. // -------------------------------------------------------
  392. const void* dbQueryLiteralBLOB:: binaryContents() const
  393. {
  394.     return mBLOB;
  395. }
  396.  
  397.  
  398. unsigned short dbQueryLiteralBLOB::literalLen() const
  399. {
  400.     return mBLOBlen;
  401. }
  402.  
  403.  
  404.     
  405. // -------------------------------------------------------
  406. //            d b Q u e r y L i t e r a l S t r
  407. // -------------------------------------------------------
  408. dbQueryClause::QueryClauseTypes  dbQueryLiteralStr::queryClauseType()  const
  409. {
  410.     return atomicLiteralStr;
  411. }
  412.  
  413.  
  414. const void* dbQueryLiteralStr::binaryContents() const
  415. {
  416.     return mStr;
  417. }
  418.  
  419.  
  420. unsigned short dbQueryLiteralStr::literalLen() const
  421. {
  422.     if (!mStr)
  423.         return 0;
  424.     return strlen(mStr);
  425. }
  426.  
  427.  
  428.