subsql.cpp

来自「FastDb是高效的内存数据库系统」· C++ 代码 · 共 3,037 行 · 第 1/5 页

CPP
3,037
字号

      case dbField::tpBool:
        *(bool*)(dst+fd->dbsOffs) = node->bval;
        break;

      case dbField::tpInt1:
        *(int1*)(dst+fd->dbsOffs) = (int1)node->ival;
        break;

      case dbField::tpInt2:
        *(int2*)(dst+fd->dbsOffs) = (int2)node->ival;
        break;

      case dbField::tpInt4:
        *(int4*)(dst+fd->dbsOffs) = (int4)node->ival;
        break;

      case dbField::tpInt8:
        *(db_int8*)(dst+fd->dbsOffs) = node->ival;
        break;

      case dbField::tpReal4:
        *(real4*)(dst+fd->dbsOffs) = (real4)node->fval;
        break;

      case dbField::tpReal8:
        *(real8*)(dst+fd->dbsOffs) = node->fval;
        break;

      case dbField::tpReference:

        if (isValidOid((oid_t)node->ival))
        {
          *(oid_t*)(dst+fd->dbsOffs) = (oid_t)node->ival;
        }
        else
        {
          return -1;
        }

        break;

      case dbField::tpString:
        ((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
        len = strlen(node->sval) + 1;
        ((dbVarying*)(dst+fd->dbsOffs))->size = len;
        memcpy(dst + offs, node->sval, len);
        offs += len;
        break;

      case dbField::tpRawBinary:
        len = node->aggregate.nComponents;
        component = node->aggregate.components;
        elem = dst + fd->dbsOffs;

        while (--len >= 0)
        {
          *elem++ = (byte)component->ival;
          component = component->next;
        }

        break;

      case dbField::tpArray:
        len = node->aggregate.nComponents;
        elem = (byte*)DOALIGN(long(dst) + offs, fd->components->alignment);
        offs = elem - dst;
        ((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
        ((dbVarying*)(dst+fd->dbsOffs))->size = len;
        elemSize = fd->components->dbsSize;
        elemOffs = len*elemSize;
        offs += elemOffs;
        component = node->aggregate.components;

        while (--len >= 0)
        {
          elemOffs = initializeRecordFields(component, elem, elemOffs,
                                            fd->components);
          elemOffs -= elemSize;
          elem += elemSize;
          component = component->next;
        }

        offs += elemOffs;
        break;

      case dbField::tpStructure:
        offs = initializeRecordFields(node->aggregate.components,
                                      dst, offs, fd->components);
      }
    }

    node = node->next;
  }
  while ((fd = fd->next) != first);

  return offs;
}


bool dbSubSql::insertRecord(dbList* list, dbTableDescriptor* desc)
{
  int size = calculateRecordSize(list, desc->fixedSize, desc->columns);

  if (size < 0)
  {
    error("Incompatible types in insert statement");
    return false;
  }

  oid_t oid = allocateRow(desc->tableId, size);
  byte* dst = (byte*)getRow(oid);
  initializeRecordFields(list, dst, desc->fixedSize, desc->columns);

  int nRows = ((dbTable*)getRow(desc->tableId))->nRows;
  dbFieldDescriptor* fd;

  for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField)
  {
    dbHashTable::insert(this, fd->hashTable, oid, fd->type, fd->dbsSize, fd->dbsOffs,
                        nRows);
  }

  for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField)
  {
    dbTtree::insert(this, fd->tTree, oid, fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs);
  }

  return true;
}

int dbSubSql::readValues(dbList** chain)
{
  int i, n = 0;
  int tkn;
  dbList* node;

  while (true)
  {
    switch (scan())
    {

    case tkn_lpar:
      node = new dbList(dbList::nTuple);
      node->aggregate.components = NULL;
      i = readValues(&node->aggregate.components);

      if (i < 0)
      {
        return -1;
      }

      node->aggregate.nComponents = i;
      break;

    case tkn_rpar:
      return -n; // valid only in case of empty list

    case tkn_iconst:
      node = new dbList(dbList::nInteger);
      node->ival = ival;
      break;

    case tkn_true:
      node = new dbList(dbList::nBool);
      node->bval = true;
      break;

    case tkn_false:
      node = new dbList(dbList::nBool);
      node->bval = false;
      break;

    case tkn_fconst:
      node = new dbList(dbList::nReal);
      node->fval = fval;
      break;

    case tkn_sconst:
      node = new dbList(dbList::nString);
      node->sval = new char[strlen(buf)+1];
      strcpy(node->sval, buf);
      break;

    case tkn_autoincrement:
      node =  new dbList(dbList::nAutoinc);
      break;

    case tkn_error:
      return -1;

    default:
      error("Syntax error in insert list");
      return -1;
    }

    *chain = node;
    chain = &node->next;
    n += 1;

    if ((tkn = scan()) == tkn_rpar)
    {
      return n;
    }

    if (tkn != tkn_comma)
    {
      error("',' expected");
      return -1;
    }
  }
}


dbFieldDescriptor* dbSubSql::readFieldName()
{
  int tkn;

  if (expect("table name", tkn_ident))
  {
    dbTableDescriptor* desc;
    dbFieldDescriptor* fd;

    if ((desc = findTable(name)) == NULL)
    {
      error("No such table in database");
      return NULL;
    }

    if (expect(".", tkn_dot) && expect("field name", tkn_ident))
    {
      if ((fd = desc->findSymbol(name)) == NULL)
      {
        error("No such field in the table");
        return NULL;
      }
      else if (fd->type == dbField::tpArray)
      {
        error("Array components can not be indexed");
        return NULL;
      }
    }
    else
    {
      return NULL;
    }

    while ((tkn = scan()) != tkn_semi)
    {
      if (tkn != tkn_dot)
      {
        error("'.' expected");
        return NULL;
      }

      if (expect("field name", tkn_ident))
      {
        if ((fd = fd->find(name)) == NULL)
        {
          error("No such field in the table");
          return NULL;
        }
        else if (fd->type == dbField::tpArray)
        {
          error("Array components can not be indexed");
          return NULL;
        }
      }
      else
      {
        return NULL;
      }
    }

    if (fd->type == dbField::tpStructure)
    {
      error("Structures can not be indexed");
      return NULL;
    }

    return fd;
  }

  return NULL;
}


bool dbSubSql::updateFields(dbAnyCursor* cursor, dbUpdateElement* elems)
{
  char buf[64], *src;
  dbInheritedAttribute iattr;
  dbSynthesizedAttribute sattr;
  iattr.db = this;
  iattr.oid = cursor->currId;
  iattr.table = (dbTable*)getRow(cursor->table->tableId);
  iattr.record = (byte*)getRow(cursor->currId);
  iattr.paramBase = (size_t)cursor->paramBase;

  do
  {
    dbExprNode* expr = elems->value;
    dbFieldDescriptor* fd = elems->field;
    execute(expr, iattr, sattr);
    byte* dst = cursor->record + fd->appOffs;

    switch (fd->type)
    {

    case dbField::tpBool:

      switch (expr->type)
      {

      case tpInteger:
        *(bool*)dst = sattr.ivalue != 0;
        continue;

      case tpBoolean:
        *(bool*)dst = sattr.bvalue;
        continue;

      case tpReal:
        *(bool*)dst = sattr.fvalue != 0;
        continue;

      case tpString:
        *(bool*)dst = *sattr.base == 'T' || *sattr.base == 't' || *sattr.base == '1';
        continue;
      }

      break;

    case dbField::tpInt1:

      switch (expr->type)
      {

      case tpInteger:
        *(int1*)dst = (int1)sattr.ivalue;
        continue;

      case tpBoolean:
        *(int1*)dst = sattr.bvalue ? 1 : 0;
        continue;

      case tpReal:
        *(int1*)dst = (int1)sattr.fvalue;
        continue;

      case tpString:
        *(int1*)dst = (int1)atoi((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpInt2:

      switch (expr->type)
      {

      case tpInteger:
        *(int2*)dst = (int2)sattr.ivalue;
        continue;

      case tpBoolean:
        *(int2*)dst = sattr.bvalue ? 1 : 0;
        continue;

      case tpReal:
        *(int2*)dst = (int2)sattr.fvalue;
        continue;

      case tpString:
        *(int2*)dst = (int2)atoi((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpInt4:

      switch (expr->type)
      {

      case tpInteger:
        *(int4*)dst = (int4)sattr.ivalue;
        continue;

      case tpBoolean:
        *(int4*)dst = sattr.bvalue ? 1 : 0;
        continue;

      case tpReal:
        *(int4*)dst = (int4)sattr.fvalue;
        continue;

      case tpString:
        *(int4*)dst = (int1)atoi((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpInt8:

      switch (expr->type)
      {

      case tpInteger:
        *(db_int8*)dst = sattr.ivalue;
        continue;

      case tpBoolean:
        *(db_int8*)dst = sattr.bvalue ? 1 : 0;
        continue;

      case tpReal:
        *(db_int8*)dst = (db_int8)sattr.fvalue;
        continue;

      case tpString:
        *(db_int8*)dst = (db_int8)atoi((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpReal4:

      switch (expr->type)
      {

      case tpInteger:
        *(real4*)dst = (real4)sattr.ivalue;
        continue;

      case tpBoolean:
        *(real4*)dst = (real4)(sattr.bvalue ? 1 : 0);
        continue;

      case tpReal:
        *(real4*)dst = (real4)sattr.fvalue;
        continue;

      case tpString:
        *(real4*)dst = (real4)atof((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpReal8:

      switch (expr->type)
      {

      case tpInteger:
        *(real8*)dst = (real8)sattr.ivalue;
        continue;

      case tpBoolean:
        *(real8*)dst = sattr.bvalue ? 1.0 : 0.0;
        continue;

      case tpReal:
        *(real8*)dst = sattr.fvalue;
        continue;

      case tpString:
        *(real8*)dst = atof((char*)sattr.base);
        continue;
      }

      break;

    case dbField::tpString:
      src = buf;

      switch (expr->type)
      {

      case tpInteger:
        sprintf(buf, INT8_FORMAT, sattr.ivalue);
        break;

      case tpBoolean:
        strcpy(buf, sattr.bvalue ? "t" : "f");
        break;

      case tpReal:
        sprintf(buf, "%f", sattr.fvalue);
        break;

      case tpString:
        src = (char*)sattr.base;
        break;
      }

      *(char**)dst = new char[strlen(src)+1];
      strcpy(*(char**)dst, src);
      elems->strValue = *(char**)dst;
      continue;

    case dbField::tpReference:

      if (expr->type == tpInteger)
      {
        *(oid_t*)dst = sattr.oid;
        continue;
      }
    }

    assert(false);
  }
  while ((elems = elems->next) != NULL);

  return true;
}

bool dbSubSql::parse()
{
  dbTableDescriptor* desc;
  dbFieldDescriptor* fd;
  int tkn;
  bool count, outputOid, compactify;

  line = 1;
  pos = 0;

  while (true)
  {
    if (in == stdin)
    {
      printf(prompt);
      tkn = scan();
      pos += strlen(prompt);
    }
    else
    {
      tkn = scan();
    }

    switch (tkn)
    {

    case tkn_update:

      if (!opened)
      {
        error("Database not opened");
        continue;
      }

      if (accessType == dbReadOnly)
      {
        error("Operation is not possible in read-only mode");
        continue;
      }

      if (expect("table name", tkn_ident))
      {
        if ((desc = findTable(name)) == NULL)
        {
          error("No such table in database");
          continue;
        }

        if (!expect("set", tkn_set))
        {
          continue;
        }

        dbDatabaseThreadContext* ctx = threadContext.get();
        byte *record = dbMalloc(desc->appSize);
        ctx->interactive = true;
        ctx->catched = true;
        dbUpdateElement* elems = NULL;

        if (!expect("field name", tkn_ident))
        {
          goto updateCleanup;
        }

#ifdef THROW_EXCEPTION_ON_ERROR
        try
        {
#else

        if (setjmp(ctx->unwind) == 0)
        {
#endif

          char* condition = NULL;
          int startPos = pos;

          while (true)
          {
            dbUpdateElement* elem = new dbUpdateElement;
            dbFieldDescriptor* fd = desc->findSymbol(name);

            if (fd == NULL)
            {
              error("No such field in the table");
              goto updateCleanup;
            }

            if (fd->type > dbField::tpReference)

⌨️ 快捷键说明

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