localcli.cpp

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

CPP
3,024
字号
          {
            cli_real4_t* dst_elem = (cli_real4_t*)dst;
            real4*       src_elem = (real4*)src;

            while (--n >= 0)
              *dst_elem++ = *src_elem++;

            continue;
          }

          break;

        case dbField::tpReal8:

          if (cb->var_type == cli_array_of_real8)
          {
            cli_real8_t* dst_elem = (cli_real8_t*)dst;
            real8*       src_elem = (real8*)src;

            while (--n >= 0)
              *dst_elem++ = *src_elem++;

            continue;
          }

          break;

        case dbField::tpReference:

          if (cb->var_type == cli_array_of_oid)
          {
            cli_oid_t* dst_elem = (cli_oid_t*)dst;
            oid_t*     src_elem = (oid_t*)src;

            while (--n >= 0)
              *dst_elem++ = *src_elem++;

            continue;
          }

          break;

        case dbField::tpString:

          if (cb->var_type == cli_array_of_string)
          {
            char** dst_elem = (char**)dst;
            dbVarying* src_elem = (dbVarying*)src;

            while (--n >= 0)
            {
              *dst_elem++ = (char*)((char*)src_elem + src_elem->offs);
              src_elem += 1;
            }

            continue;
          }
        }
      }
    }

    return cli_unsupported_type;
  }

  return cli_ok;
}


int dbCLI::store_columns(char* data, statement_desc* stmt)
{
  for (column_binding* cb = stmt->columns; cb != NULL; cb = cb->next)
  {
    dbFieldDescriptor* fd = cb->field;
    char* dst = data + fd->appOffs;
    char* src = (char*)cb->var_ptr;
    // Allow storing to structures with one component

    if (fd->type == dbField::tpStructure && fd->components->next == NULL)
    {
      fd = fd->components;
    }

    switch (fd->type)
    {

    case dbField::tpBool:

      switch (cb->var_type)
      {

      case cli_bool:
        *(bool*)dst = *(cli_bool_t*)src;
        continue;

      case cli_int1:
        *(bool*)dst = *(cli_int1_t*)src != 0;
        continue;

      case cli_int2:
        *(bool*)dst = *(cli_int2_t*)src != 0;
        continue;

      case cli_int4:
        *(bool*)dst = *(cli_int4_t*)src != 0;
        continue;

      case cli_int8:
        *(bool*)dst = *(db_int8*)src != 0;
        continue;

      case cli_real4:
        *(bool*)dst = *(cli_real4_t*)src != 0;
        continue;

      case cli_real8:
        *(bool*)dst = *(cli_real8_t*)src != 0;
        continue;
      }

      break;

    case dbField::tpInt1:

      switch (cb->var_type)
      {

      case cli_bool:
        *(int1*)dst = *(cli_bool_t*)src ? 1 : 0;
        continue;

      case cli_int1:
        *(int1*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(int1*)dst = (int1)*(cli_int2_t*)src;
        continue;

      case cli_int4:
        *(int1*)dst = (int1)*(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(int1*)dst = (int1)*(db_int8*)src;
        continue;

      case cli_real4:
        *(int1*)dst = (int1)*(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(int1*)dst = (int1)*(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpInt2:

      switch (cb->var_type)
      {

      case cli_bool:
        *(int2*)dst = *(cli_bool_t*)src ? 1 : 0;
        continue;

      case cli_int1:
        *(int2*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(int2*)dst = *(cli_int2_t*)src;
        continue;

      case cli_int4:
        *(int2*)dst = (int2)*(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(int2*)dst = (int2)*(db_int8*)src;
        continue;

      case cli_real4:
        *(int2*)dst = (int2)*(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(int2*)dst = (int2)*(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpInt4:

      switch (cb->var_type)
      {

      case cli_bool:
        *(int4*)dst = *(cli_bool_t*)src ? 1 : 0;
        continue;

      case cli_int1:
        *(int4*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(int4*)dst = *(cli_int2_t*)src;
        continue;

      case cli_autoincrement:
#ifdef AUTOINCREMENT_SUPPORT

        *(int4*)dst = cb->field->defTable->autoincrementCount;
#endif

        continue;

      case cli_int4:
        *(int4*)dst = *(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(int4*)dst = (int4)*(db_int8*)src;
        continue;

      case cli_real4:
        *(int4*)dst = (int4)*(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(int4*)dst = (int4)*(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpInt8:

      switch (cb->var_type)
      {

      case cli_bool:
        *(db_int8*)dst = *(cli_bool_t*)src ? 1 : 0;
        continue;

      case cli_int1:
        *(db_int8*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(db_int8*)dst = *(cli_int2_t*)src;
        continue;

      case cli_int4:
        *(db_int8*)dst = *(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(db_int8*)dst = *(db_int8*)src;
        continue;

      case cli_real4:
        *(db_int8*)dst = (db_int8)*(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(db_int8*)dst = (db_int8)*(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpReal4:

      switch (cb->var_type)
      {

      case cli_bool:
        *(real4*)dst = (real4)(*(cli_bool_t*)src ? 1 : 0);
        continue;

      case cli_int1:
        *(real4*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(real4*)dst = *(cli_int2_t*)src;
        continue;

      case cli_int4:
        *(real4*)dst = (real4)*(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(real4*)dst = (real4)*(db_int8*)src;
        continue;

      case cli_real4:
        *(real4*)dst = *(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(real4*)dst = (real4)*(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpReal8:

      switch (cb->var_type)
      {

      case cli_bool:
        *(real8*)dst = *(cli_bool_t*)src ? 1 : 0;
        continue;

      case cli_int1:
        *(real8*)dst = *(cli_int1_t*)src;
        continue;

      case cli_int2:
        *(real8*)dst = *(cli_int2_t*)src;
        continue;

      case cli_int4:
        *(real8*)dst = *(cli_int4_t*)src;
        continue;

      case cli_int8:
        *(real8*)dst = (real8)*(db_int8*)src;
        continue;

      case cli_real4:
        *(real8*)dst = *(cli_real4_t*)src;
        continue;

      case cli_real8:
        *(real8*)dst = *(cli_real8_t*)src;
        continue;
      }

      break;

    case dbField::tpReference:

      if (cb->var_type == cli_oid)
      {
        *(oid_t*)dst = *(cli_oid_t*)src;
        continue;
      }

      break;

    case dbField::tpString:

      if (cb->var_type == cli_pasciiz)
      {
        *(char**)dst = *(char**)src;
        continue;
      }
      else if (cb->var_type == cli_asciiz)
      {
        if (cb->get_fnc != NULL)
        {
          int len;
          src = (char*)cb->get_fnc(cb->var_type, src, &len,
                                   cb->name, stmt->id);
        }

        *(char**)dst = src;
        continue;
      }

      break;

    case dbField::tpArray:

      if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_string)
      {
        int size = 0;

        if (cb->get_fnc != NULL)
        {
          src = (char*)cb->get_fnc(cb->var_type, src, &size,
                                   cb->name, stmt->id);
        }
        else
        {
          if (cb->var_len != NULL)
          {
            size = *cb->var_len;
          }
          else
          {
            return cli_incompatible_type;
          }
        }

        if (cb->var_type == cli_array_of_string)
        {
          if (fd->components->type != dbField::tpString)
          {
            return cli_incompatible_type;
          }
        }
        else if ((size_t)sizeof_type[cb->var_type - cli_array_of_oid] != fd->components->appSize)
        {
          return cli_incompatible_type;
        }

        dbAnyArray::arrayAllocator((dbAnyArray*)dst, src, size);
        continue;
      }
    }

    return cli_unsupported_type;
  }

  return cli_ok;
}



int cli_insert(int statement, cli_oid_t* oid)
{
  return dbCLI::instance.insert(statement, oid);
}

int dbCLI::insert(int statement, cli_oid_t* oid)
{
  statement_desc* stmt = statements.get(statement);

  if (stmt == NULL)
  {
    return cli_bad_descriptor;
  }

  if (!stmt->prepared)
  {
    sql_scanner scanner(stmt->sql.base());

    if (scanner.get() != tkn_insert
        || scanner.get() != tkn_into
        || scanner.get() != tkn_ident)
    {
      return cli_bad_statement;
    }

    int rc = match_columns(scanner.identifier(), stmt);

    if (rc != cli_ok)
    {
      return rc;
    }

    stmt->prepared = true;
  }

  dbSmallBuffer buf(stmt->table->appSize);
  char* obj = buf.base();
  memset(obj, 0, stmt->table->appSize);
  dbFieldDescriptor *first = stmt->table->columns, *fd = first;

  do
  {
    if (fd->appType == dbField::tpString)
    {
      *(char**)(obj + fd->appOffs) = "";
    }
  }
  while ((fd = fd->next) != first);

  int rc = store_columns(buf.base(), stmt);

  if (rc != cli_ok)
  {
    return rc;
  }

  dbAnyReference ref;
  stmt->session->db->insertRecord(stmt->table, &ref, buf.base());
  stmt->oid = ref.getOid();

  if (oid != NULL)
  {
    *oid = ref.getOid();
  }

  if (stmt->n_autoincremented_columns > 0)
  {
    for (column_binding* cb = stmt->columns; cb != NULL; cb = cb->next)
    {
      if (cb->var_type == cli_autoincrement)
      {
        *(cli_int4_t*)cb->var_ptr = ref.getOid();
      }
    }
  }

  return cli_ok;
}

int cli_update(int statement)
{
  return dbCLI::instance.update(statement);
}

int dbCLI::update(int statement)
{
  statement_desc* stmt = statements.get(statement);

  if (stmt == NULL)
  {
    return cli_bad_descriptor;
  }

  if (!stmt->prepared)
  {
    return cli_not_fetched;
  }

  if (!stmt->for_update)
  {
    return cli_not_update_mode;
  }

  if (stmt->updated)
  {
    return cli_already_updated;
  }

  if (stmt->cursor.isEmpty())
  {
    return cli_not_found;
  }

  if (stmt->record_struct == NULL)
  {
    dbSmallBuffer buf(stmt->table->appSize);
    char* record = buf.base();
    memset(record, 0, stmt->table->appSize);
    stmt->cursor.setRecord((byte*)record);
    stmt->cursor.fetch();

    int rc = store_columns(buf.base(), stmt);

    if (rc != cli_ok)
    {
      return rc;
    }
  }

  stmt->cursor.update();
  stmt->updated = true;
  return cli_ok;
}

int cli_freeze(int statement)
{
  return dbCLI::instance.freeze(statement);
}

int dbCLI::freeze(int statement)
{
  statement_desc* stmt = statements.get(statement);

  if (stmt == NULL)
  {
    return cli_bad_descriptor;
  }

  if (!stmt->prepared)
  {
    return cli_not_fetched;
  }

  stmt->cursor.freeze();
  return cli_ok;
}

int cli_unfreeze(int statement)
{
  return dbCLI::instance.unfreeze(statement);
}

int dbCLI::unfreeze(int statement)
{
  statement_desc* stmt = statements.get(statement);

  if (stmt == NULL)
  {
    return cli_bad_descriptor;
  }

  if (!stmt->prepared)
  {
    return cli_not_fetched;
  }

  stmt->cursor.unfreeze();
  return cli_ok;
}

⌨️ 快捷键说明

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