⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 query.h

📁 一个不错的fastdb使用例子
💻 H
📖 第 1 页 / 共 2 页
字号:
//-< QUERY.H >-------------------------------------------------------*--------*
// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
// (Main Memory Database Management System)                          *   /\|  *
//                                                                   *  /  \  *
//                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
//                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Constructing and hashing database query statements
//-------------------------------------------------------------------*--------*

#ifndef __QUERY_H__
#define __QUERY_H__

/**
 * Element of the query
 */

class FASTDB_DLL_ENTRY dbQueryElement
{

  friend class dbQuery;

  friend class dbCompiler;

  friend class dbQueryExpression;

  friend class dbQueryElementAllocator;

  friend class dbCLI;

public:
  enum ElementType {
    qExpression, // part of SQL expression
    qVarBool,
    qVarInt1,
    qVarInt2,
    qVarInt4,
    qVarInt8,
    qVarReal4,
    qVarReal8,
    qVarString,
    qVarStringPtr,
    qVarReference,
    qVarArrayOfRef,
    qVarArrayOfRefPtr,
    qVarRawData
#ifdef USE_STD_STRING
    ,qVarStdString
#endif
  };

  ElementType getType() const
  {
    return type;
  }

  dbQueryElement* nextElement() const
  {
    return next;
  }

  void* operator new (size_t size EXTRA_DEBUG_NEW_PARAMS);
  void  operator delete(void* p EXTRA_DEBUG_NEW_PARAMS);

  char* dump(char* buf);
  char* dumpValues(char* buf);

  dbQueryElement(ElementType t, void const* p,
                 dbTableDescriptor* table = NULL)
  {
    type = t;
    ptr  = p;
    ref  = table;
    next = NULL;
  }

private:
  dbQueryElement*    next;
  void const*        ptr;
  ElementType        type;
  dbTableDescriptor* ref;
};


/**
 * Allocator of query elements. This class links deallocated elements in the list of free elements,
 * and reused them in future. So number of system memory allocator invocations is dramatically reduced.
 * Cleanup of free elements lst is performed by <code>dbDatabase::cleanup()</code> method
 */

class FASTDB_DLL_ENTRY dbQueryElementAllocator
{

  friend class dbDatabase;

  dbMutex         mutex;
  dbQueryElement* freeChain;

public:
  void deallocate(dbQueryElement* first, dbQueryElement** lastNext)
  {
    dbCriticalSection cs(mutex);

    if (first != NULL)
    {
      *lastNext = freeChain;
      freeChain = first;
    }
  }

  void* allocate(size_t size);

  dbQueryElementAllocator();
  ~dbQueryElementAllocator();

  static dbQueryElementAllocator instance;
};

/**
 * This class represents component of the structure.
 * It is mostly needed for implementation of application specific database types. For example, look at
 * <code>dbDate</code> class. It contains <code>int4 jday</code> component which stores time in seconds sinse 1970.
 * This class defines its own comparison methods:
 * <PRE>
 *     dbQueryExpression operator == (char const* field) { 
 *    dbQueryExpression expr;
 *    expr = dbComponent(field,"jday"),"=",jday;
 *        return expr;
 *     }
 * </PRE>
 * Making it possible to sepcify queries like this (assume that record has column "released" with type dbDate:
 * <PRE>
 *     dbQuery q;
 *     dbDate  date;
 *     q = date == "released";
 * </PRE>
 */

class FASTDB_DLL_ENTRY dbComponent
{

public:
  char const* structure;
  char const* field;

  dbComponent(char const* s, char const* f=NULL) : structure(s), field(f)
  {}

}

;


/**
 * Class representing SubSQL expression.  
 * It is mostly needed for implementation of application specific database types.
 * Look at the example in dbComponent class. 
 * The effect of addeing dbExpression to the query is the same as if this expresion is enclosed in parenthesis.
 */

class FASTDB_DLL_ENTRY dbQueryExpression
{

  friend class dbQuery;
  dbQueryElement*  first;
  dbQueryElement** last;
  bool             operand;

public:

  dbQueryExpression& add
    (dbQueryElement::ElementType type, void const* ptr, dbTableDescriptor* table = NULL)
  {
    last = &(*last = new dbQueryElement(type, ptr, table))->next;
    operand = (type == dbQueryElement::qExpression);
    return *this;
  }

  dbQueryExpression& operator = (char const* ptr)
  {
    first = NULL, last = &first;

    return add
             (dbQueryElement::qExpression, ptr);
  }

  dbQueryExpression& operator = (dbComponent const& comp);

  dbQueryExpression& operator = (dbQueryExpression const& expr);

  dbQueryExpression& operator,(int1 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt1, &ptr);
  }

  dbQueryExpression& operator,(int2 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt2, &ptr);
  }

  dbQueryExpression& operator,(int4 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt4, &ptr);
  }

  dbQueryExpression& operator,(db_int8 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt8, &ptr);
  }

  dbQueryExpression& operator,(nat1 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt1, &ptr);
  }

  dbQueryExpression& operator,(nat2 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt2, &ptr);
  }

  dbQueryExpression& operator,(nat4 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt4, &ptr);
  }

  dbQueryExpression& operator,(db_nat8 const& ptr)
  {

    return add
             (dbQueryElement::qVarInt8, &ptr);
  }

#if SIZEOF_LONG != 8
  dbQueryExpression& operator,(long const& ptr)
  {

    return add
             (dbQueryElement::qVarInt4, &ptr);
  }

  dbQueryExpression& operator,(unsigned long const& ptr)
  {

    return add
             (dbQueryElement::qVarInt4, &ptr);
  }

#endif
  dbQueryExpression& operator,(real4 const& ptr)
  {

    return add
             (dbQueryElement::qVarReal4, &ptr);
  }

  dbQueryExpression& operator,(real8 const& ptr)
  {

    return add
             (dbQueryElement::qVarReal8, &ptr);
  }

  dbQueryExpression& operator,(bool const& ptr)
  {

    return add
             (dbQueryElement::qVarBool, &ptr);
  }

  dbQueryExpression& operator,(char const* ptr)
  {

    return add
             (operand ? dbQueryElement::qVarString
              : dbQueryElement::qExpression, ptr);
  }

  dbQueryExpression& operator,(char const** ptr)
  {

    return add
             (dbQueryElement::qVarStringPtr, ptr);
  }

  dbQueryExpression& operator,(char** ptr)
  {

    return add
             (dbQueryElement::qVarStringPtr, ptr);
  }

  dbQueryExpression& operator,(void const* ptr)
  {

    return add
             (dbQueryElement::qVarRawData, ptr);
  }

#ifdef USE_STD_STRING
  dbQueryExpression& operator,(std::string const& str)
  {

    return add
             (dbQueryElement::qVarStdString, &str);
  }

#endif
  dbQueryExpression& operator,(dbQueryExpression const& expr)
  {
    *last = new dbQueryElement(dbQueryElement::qExpression, "(");
    (*last)->next = expr.first;
    last = expr.last;
    *last = new dbQueryElement(dbQueryElement::qExpression, ")");
    last = &(*last)->next;
    operand = false;
    return *this;
  }

  dbQueryExpression& operator,(dbComponent const& comp)
  {
    add
      (dbQueryElement::qExpression, comp.structure);

    if (comp.field != NULL)
    {
      add
        (dbQueryElement::qExpression, ".");

      add
        (dbQueryElement::qExpression, comp.field);
    }

    operand = false;
    return *this;
  }

  dbQueryExpression& operator += (dbComponent const& comp)
  {
    return *this,comp;
  }

  dbQueryExpression& operator += (char const* ptr)
  {

    return add
             (dbQueryElement::qExpression, ptr);
  }

#ifndef NO_MEMBER_TEMPLATES

  template<class T>
  dbQueryExpression& operator,(dbReference<T> const& value)
  {

    return add
             (dbQueryElement::qVarReference, &value, &T::dbDescriptor);
  }

  template<class T>
  inline dbQueryExpression& operator,(dbArray< dbReference<T> > const& value)
  {

    return add
             (dbQueryElement::qVarArrayOfRef, &value,
              &T::dbDescriptor);
  }

  template<class T>
  inline dbQueryExpression& operator,(dbArray< dbReference<T> >const* const& value)
  {

    return add
             (dbQueryElement::qVarArrayOfRefPtr, &value, &T::dbDescriptor);
  }

#endif
};

class dbOrderByNode;

class dbFollowByNode;


/**
 * Class used for precompiled queries
 */

class FASTDB_DLL_ENTRY dbCompiledQuery
{

public:
  dbExprNode*        tree;
  dbOrderByNode*     order;
  dbFollowByNode*    follow;
  dbTableDescriptor* table;
  int                schemeVersion;

  enum IteratorInit {
    StartFromAny,
    StartFromFirst,
    StartFromLast,
    StartFromRef,
    StartFromArray,
    StartFromArrayPtr
  };
  IteratorInit       startFrom;
  void const*        root;

  void destroy();

  bool compiled()
  {
    return tree != NULL;
  }

  dbCompiledQuery()
  {
    tree = NULL;
    order = NULL;
    follow = NULL;
    table = NULL;
    startFrom = StartFromAny;
  }
};

/**
 * Query class. It is derived from <code>dbCompiledQuery</code> class because each query is compiled only once - when
 * it is executed first time. All subsequent executions of query used precompiled tree.
 */

class FASTDB_DLL_ENTRY dbQuery : public dbCompiledQuery
{

  friend class dbCompiler;

  friend class dbDatabase;

  friend class dbSubSql;

  friend class dbCLI;

private:
  dbMutex            mutex;
  dbQueryElement*    elements;
  dbQueryElement**   nextElement;
  bool               operand;
  bool               mutexLocked;

  //
  // Prohibite query copying
  //
  dbQuery(dbQuery const&)
  {}

  dbQuery& operator =(dbQuery const&)
  {
    return *this;
  }

public:
  int                pos; // position of condition in statement


  char* dump(char* buf)
  {
    char* p = buf;

    for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next)
    {
      p = elem->dump(p);
    }

    return buf;
  }

  char* dumpValues(char* buf)
  {
    char* p = buf;

    for (dbQueryElement* elem = elements; elem != NULL; elem = elem->next)
    {
      p = elem->dumpValues(p);
    }

    return buf;
  }

  dbQuery& append(dbQueryElement::ElementType type, void const* ptr,
                  dbTableDescriptor* table = NULL)
  {
    nextElement = &(*nextElement=new dbQueryElement(type,ptr,table))->next;
    operand = (type == dbQueryElement::qExpression);
    return *this;
  }

  dbQuery& reset();

  //
  // Redefined operator = and , make it possible to specify query in the
  // following way:
  //         int x, y;
  //         dbDataTime dt;
  //         dbQuery q;
  //         dbCursor<record> cursor;
  //         q = "x=",x,"and y=",y,"and",dt == "date";
  //         for (x = 0; x < max_x; x++) {
  //             for (y = 0; y < max_y; y++) {
  //                 cursor.select(q);
  //                 ...
  //             }
  //         }

  dbQuery& add
    (dbQueryExpression const& expr);

  dbQuery& And(char const* str)
  {
    if (elements != NULL)
    {
      append(dbQueryElement::qExpression, "and");
    }

    return append(dbQueryElement::qExpression, str);
  }

  dbQuery& Or(char const* str)
  {
    if (elements != NULL)
    {
      append(dbQueryElement::qExpression, "or");
    }

    return append(dbQueryElement::qExpression, str);
  }

  dbQuery& add
    (char const* str)
  {
    return append(operand ? dbQueryElement::qVarString
                  : dbQueryElement::qExpression, str);
  }

  dbQuery& add
    (char const** str)
  {
    return append(dbQueryElement::qVarStringPtr, str);
  }

#ifdef USE_STD_STRING
  dbQuery& add
    (std::string const& str)
  {
    return append(dbQueryElement::qVarStdString, &str);
  }

  dbQuery& operator,(std::string const& str)
  {

    return add
             (str);
  }

#endif

  dbQuery& add
    (char** str)
  {
    return append(dbQueryElement::qVarStringPtr, str);
  }

  dbQuery& add
    (int1 const& value)
  {
    return append(dbQueryElement::qVarInt1, &value);
  }

  dbQuery& add
    (int2 const& value)
  {
    return append(dbQueryElement::qVarInt2, &value);
  }

  dbQuery& add
    (int4 const& value)
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -