query.cpp

来自「FastDb是高效的内存数据库系统」· C++ 代码 · 共 477 行

CPP
477
字号
//-< QUERY.CPP >-----------------------------------------------------*--------*
// 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
//-------------------------------------------------------------------*--------*

#define INSIDE_FASTDB

#include "fastdb.h"
#include "symtab.h"
#include "compiler.h"

dbQueryElementAllocator dbQueryElementAllocator::instance;


char* dbQueryElement::dump(char* buf)
{
  switch (type)
  {

  case qExpression:
    buf += sprintf(buf, " %s ", (const char*)ptr);
    break;

  case qVarBool:
    buf += sprintf(buf, "{boolean}");
    break;

  case qVarInt1:
    buf += sprintf(buf, "{int1}");
    break;

  case qVarInt2:
    buf += sprintf(buf, "{int2}");
    break;

  case qVarInt4:
    buf += sprintf(buf, "{int4}");
    break;

  case qVarInt8:
    buf += sprintf(buf, "{int8}");
    break;

  case qVarReal4:
    buf += sprintf(buf, "{real4}");
    break;

  case qVarReal8:
    buf += sprintf(buf, "{real8}");
    break;

  case qVarString:
    buf += sprintf(buf, "{char*}");
    break;

  case qVarStringPtr:
    buf += sprintf(buf, "{char**}");
    break;

  case qVarReference:

    if (ref != NULL)
    {
      buf += sprintf(buf, "{dbReference<%s>}", ref->getName());
    }
    else
    {
      buf += sprintf(buf, "{dbAnyReference}");
    }

    break;

  case qVarArrayOfRef:

    if (ref != NULL)
    {
      buf += sprintf(buf, "{dbArray< dbReference<%s> >}", ref->getName());
    }
    else
    {
      buf += sprintf(buf, "{dbArray<dbAnyReference>}");
    }

    break;

  case qVarArrayOfRefPtr:

    if (ref != NULL)
    {
      buf += sprintf(buf, "{dbArray< dbReference<%s> >*}", ref->getName());
    }
    else
    {
      buf += sprintf(buf, "{dbArray<dbAnyReference>*}");
    }

    break;

  case qVarRawData:
    buf += sprintf(buf, "{raw binary}");
    break;
#ifdef USE_STD_STRING

  case qVarStdString:
    buf += sprintf(buf, "{string}");
    break;
#endif

  }

  return buf;
}


char* dbQueryElement::dumpValues(char* buf)
{
  switch (type)
  {

  case qExpression:
    buf += sprintf(buf, " %s ", (char*)ptr);
    break;

  case qVarBool:
    buf += sprintf(buf, "%s", *(bool*)ptr ? "true" : "false");
    break;

  case qVarInt1:
    buf += sprintf(buf, "%d", *(int1*)ptr);
    break;

  case qVarInt2:
    buf += sprintf(buf, "%d", *(int2*)ptr);
    break;

  case qVarInt4:
    buf += sprintf(buf, "%d", *(int4*)ptr);
    break;

  case qVarInt8:
    buf += sprintf(buf, INT8_FORMAT, *(db_int8*)ptr);
    break;

  case qVarReal4:
    buf += sprintf(buf, "%f", *(real4*)ptr);
    break;

  case qVarReal8:
    buf += sprintf(buf, "%f", *(real8*)ptr);
    break;

  case qVarString:
    buf += sprintf(buf, "'%s'", (char*)ptr);
    break;

  case qVarStringPtr:
    buf += sprintf(buf, "'%s'", *(char**)ptr);
    break;

  case qVarReference:

    if (ref != NULL)
    {
      buf += sprintf(buf, "@%s:%x", ref->getName(), *(oid_t*)ptr);
    }
    else
    {
      buf += sprintf(buf, "@%x", *(oid_t*)ptr);
    }

    break;

  case qVarArrayOfRef:

    if (ref != NULL)
    {
      buf += sprintf(buf, "{dbArray< dbReference<%s> >}", ref->getName());
    }
    else
    {
      buf += sprintf(buf, "{dbArray<dbAnyReference>}");
    }

    break;

  case qVarArrayOfRefPtr:

    if (ref != NULL)
    {
      buf += sprintf(buf, "{dbArray< dbReference<%s> >*}", ref->getName());
    }
    else
    {
      buf += sprintf(buf, "{dbArray<dbAnyReference>*}");
    }

    break;

  case qVarRawData:
    buf += sprintf(buf, "{raw binary}");
    break;
#ifdef USE_STD_STRING

  case qVarStdString:
    buf += sprintf(buf, "'%s'", ((std::string*)ptr)->c_str());
    break;
#endif

  }

  return buf;
}

dbQueryElementAllocator::dbQueryElementAllocator()
    : freeChain(NULL)
{}

void* dbQueryElementAllocator::allocate(size_t size)
{
  dbCriticalSection cs(mutex);
  dbQueryElement* elem = freeChain;

  if (elem != NULL)
  {
    freeChain = elem->next;
    return elem;
  }
  else
  {
    return dbMalloc(size);
  }
}

void* dbQueryElement::operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
  return dbQueryElementAllocator::instance.allocate(size);
}


void  dbQueryElement::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
  dbFree(p);
}


dbQueryElementAllocator::~dbQueryElementAllocator()
{
  dbQueryElement *elem, *next;

  for (elem = freeChain; elem != NULL; elem = next)
  {
    next = elem->next;
    delete elem;
  }
}

dbQueryExpression& dbQueryExpression::operator = (dbComponent const& comp)
{
  first = NULL;
  last = &first;

  add
    (dbQueryElement::qExpression, comp.structure);

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

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

  operand = false;
  return *this;
}

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

dbQuery& dbQuery::add
  (dbQueryExpression const& expr)
{
  append(dbQueryElement::qExpression, "(");
  *nextElement = expr.first;
  nextElement = expr.last;
  append(dbQueryElement::qExpression, ")");
  operand = false;
  return *this;
}



dbQuery& dbQuery::reset()
{
  dbQueryElementAllocator::instance.deallocate(elements, nextElement);
  elements = NULL;
  nextElement = &elements;
  operand = false;
  mutexLocked = false;
  dbCompiledQuery::destroy();
  return *this;
}

void dbCompiledQuery::destroy()
{
  if (tree != NULL)
  {
    dbMutex& mutex = dbExprNodeAllocator::instance.getMutex();
    dbCriticalSection cs(mutex);

    if (mutex.isInitialized())
    {
      delete tree;

      for (dbOrderByNode *op = order, *nop; op != NULL; op = nop)
      {
        nop = op->next;
        delete op;
      }

      for (dbFollowByNode *fp = follow, *nfp; fp != NULL; fp = nfp)
      {
        nfp = fp->next;
        delete fp;
      }
    }

    tree = NULL;
  }

  startFrom = StartFromAny;
  follow = NULL;
  order = NULL;
  table = NULL;
}

int dbUserFunction::getParameterType()
{
  static byte argType[] = {
                            tpInteger,
                            tpReal,
                            tpString,
                            tpInteger,
                            tpReal,
                            tpString,
                            tpInteger,
                            tpReal,
                            tpString,
                            tpInteger,
                            tpReal,
                            tpString,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList,
                            tpList
                          };
  return argType[type];
}

int dbUserFunction::getNumberOfParameters()
{
  static byte nArgs[] = {
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          1,
                          2,
                          2,
                          2,
                          2,
                          3,
                          3,
                          3,
                          3
                        };
  return nArgs[type];
}

dbUserFunction* dbUserFunction::list;


void dbUserFunction::bind(char* fname, void* f, funcType ftype)
{
  name = fname;

  dbSymbolTable::add
    (name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER);

  next = list;

  list = this;

  fptr = f;

  type = ftype;
}

dbUserFunctionArgument::dbUserFunctionArgument(dbExprNode*             expr,
    dbInheritedAttribute&   iattr,
    dbSynthesizedAttribute& sattr,
    int                     i)
{
  dbDatabase::execute(expr->func.arg[i], iattr, sattr);

  switch (expr->func.arg[i]->type)
  {

  case tpInteger:
    u.intValue = sattr.ivalue;
    type = atInteger;
    break;

  case tpReal:
    u.realValue = sattr.fvalue;
    type = atReal;
    break;

  case tpString:
    u.strValue = sattr.array.base;
    type = atString;
    break;

  case tpBoolean:
    u.boolValue = sattr.bvalue;
    type = atBoolean;
    break;

  case tpReference:
    u.oidValue = sattr.oid;
    type = atReference;
    break;

  case tpRawBinary:
    u.rawValue = sattr.raw;
    type = atRawBinary;
    break;

  default:
    assert(false);
  }
}

⌨️ 快捷键说明

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