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

📄 cli.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        ;
      continue;

    case cli_pasciiz:
      s = *(char**)pb->var_ptr;

      while ((*p++ = *s++) != '\0')

        ;
      continue;

    default:
      switch (sizeof_type[pb->var_type])
      {

      case 1:
        *p++ = *(char*)pb->var_ptr;
        continue;

      case 2:
        p = pack2(p, *(int2*)pb->var_ptr);
        continue;

      case 4:
        p = pack4(p, *(int4*)pb->var_ptr);
        continue;

      case 8:
        p = pack8(p, *(db_int8*)pb->var_ptr);
        continue;
      }
    }
  }

  assert(msg_size == p - buf.base());

  if (!stmt->session->sock->write(buf, msg_size))
  {
    return cli_network_error;
  }

  int4 response;

  if (!stmt->session->sock->read(&response, sizeof response))
  {
    return cli_network_error;
  }

  unpack4(response);

  if (response >= 0)
  {
    stmt->prepared = true;
  }

  return response;
}

static int cli_send_columns(int statement, int cmd)
{
  statement_desc* s = statements.get(statement);
  column_binding* cb;

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

  long msg_size = sizeof(cli_request);

  if (cmd == cli_cmd_update)
  {
    if (!s->prepared)
    {
      return cli_not_fetched;
    }

    if (s->oid == 0)
    {
      return cli_not_found;
    }

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

    if (!s->for_update)
    {
      return cli_not_update_mode;
    }
  }
  else
  {
    if (!s->prepared)
    {
      cmd = cli_cmd_prepare_and_insert;
      msg_size += 1 + s->stmt_len + s->n_columns + s->columns_len;
    }
  }

  s->autoincrement = false;

  for (cb = s->columns; cb != NULL; cb = cb->next)
  {
    if (cb->get_fnc != NULL)
    {
      cb->arr_ptr = cb->get_fnc(cb->var_type, cb->var_ptr, &cb->arr_len,
                                cb->name, statement);
      int len = cb->arr_len;
      msg_size += 4;

      if (cb->var_type == cli_array_of_string)
      {
        char** p = (char**)cb->arr_ptr;

        while (--len >= 0)
        {
          msg_size += strlen(*p++) + 1;
        }
      }
      else if (cb->var_type >= cli_array_of_oid)
      {
        msg_size += len * sizeof_type[cb->var_type - cli_array_of_oid];
      }
      else
      {
        msg_size += len;
      }
    }
    else
    {
      if (cb->var_type == cli_asciiz)
      {
        msg_size += 4 + strlen((char*)cb->var_ptr) + 1;
      }
      else if (cb->var_type == cli_pasciiz)
      {
        msg_size += 4 + strlen(*(char**)cb->var_ptr) + 1;
      }
      else if (cb->var_type == cli_autoincrement)
      {
        s->autoincrement = true;
      }
      else if (cb->var_type == cli_array_of_string)
      {
        char** p = (char**)cb->var_ptr;
        msg_size += 4;

        for (int len = *cb->var_len; --len >= 0;)
        {
          msg_size += strlen(*p++) + 1;
        }
      }
      else if (cb->var_type >= cli_array_of_oid)
      {
        msg_size += 4 +
                    *cb->var_len * sizeof_type[cb->var_type-cli_array_of_oid];
      }
      else
      {
        msg_size += sizeof_type[cb->var_type];
      }
    }
  }

  dbSmallBuffer buf(msg_size);
  char* p = buf;
  cli_request* req = (cli_request*)p;
  req->length  = msg_size;
  req->cmd     = cmd;
  req->stmt_id = statement;
  req->pack();
  p += sizeof(cli_request);

  if (cmd == cli_cmd_prepare_and_insert)
  {
    char* cmd = s->stmt;

    while ((*p++ = *cmd++) != '\0')

      ;
    *p++ = s->n_columns;

    for (cb = s->columns; cb != NULL; cb = cb->next)
    {
      char* src = cb->name;
      *p++ = cb->var_type;

      while ((*p++ = *src++) != '\0')

        ;
    }
  }

  for (cb = s->columns; cb != NULL; cb = cb->next)
  {
    int n = 0;
    char* src;

    if (cb->get_fnc != NULL)
    {
      src = (char*)cb->arr_ptr;
      n = cb->arr_len;
    }
    else
    {
      src = (char*)cb->var_ptr;

      if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8)
      {
        n = *cb->var_len;
      }
    }

    if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8)
    {
      p = pack4(p, n);

      if (cb->var_type == cli_array_of_string)
      {
        while (--n >= 0)
        {
          strcpy(p, *(char**)src);
          p += strlen(p) + 1;
          src += sizeof(char*);
        }
      }
      else
      {
        switch (sizeof_type[cb->var_type-cli_array_of_oid])
        {

        case 2:

          while (--n >= 0)
          {
            p = pack2(p, src);
            src += 2;
          }

          break;

        case 4:

          while (--n >= 0)
          {
            p = pack4(p, src);
            src += 4;
          }

          break;

        case 8:

          while (--n >= 0)
          {
            p = pack8(p, src);
            src += 8;
          }

          break;

        default:
          memcpy(p, src, n);
          p += n;
        }
      }
    }
    else if (cb->var_type == cli_asciiz)
    {
      p = pack4(p, strlen(src)+1);

      while ((*p++ = *src++) != 0)

        ;
    }
    else if (cb->var_type == cli_pasciiz)
    {
      src = *(char**)src;
      p = pack4(p, strlen(src)+1);

      while ((*p++ = *src++) != 0)

        ;
    }
    else if (cb->var_type != cli_autoincrement)
    {
      switch (sizeof_type[cb->var_type])
      {

      case 2:
        p = pack2(p, src);
        break;

      case 4:
        p = pack4(p, src);
        break;

      case 8:
        p = pack8(p, src);
        break;

      default:
        *p++ = *src;
      }
    }
  }

  assert(p - buf.base() == msg_size);

  if (!s->session->sock->write(buf, msg_size))
  {
    return cli_network_error;
  }

  return cli_ok;
}

int cli_insert(int statement, cli_oid_t* oid)
{
  int rc = cli_send_columns(statement, cli_cmd_insert);

  if (rc == cli_ok)
  {
    char buf[sizeof(cli_oid_t) + 8];
    statement_desc* s = statements.get(statement);

    if (!s->session->sock->read(buf, sizeof buf))
    {
      rc = cli_network_error;
    }
    else
    {
      rc = unpack4(buf);
      s->prepared = true;
      s->oid = unpack_oid(buf + 8);

      if (oid != NULL)
      {
        *oid = s->oid;
      }

      if (s->autoincrement)
      {
        int4 rowid = unpack4(buf + 4);

        for (column_binding* cb = s->columns; cb != NULL; cb = cb->next)
        {
          if (cb->var_type == cli_autoincrement)
          {
            *(int4*)cb->var_ptr = rowid;
          }
        }
      }
    }
  }

  return rc;
}

int cli_update(int statement)
{
  int rc = cli_send_columns(statement, cli_cmd_update);

  if (rc == cli_ok)
  {
    int4 response;
    statement_desc* s = statements.get(statement);
    s->updated = true;

    if (!s->session->sock->read(&response, sizeof response))
    {
      rc = cli_network_error;
    }
    else
    {
      unpack4(response);
      rc = response;
    }
  }

  return rc;
}

static int cli_get(int statement, int cmd, cli_oid_t value = 0)
{
  statement_desc* s = statements.get(statement);

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

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

  struct get_req
  {
    cli_request req;
    cli_oid_t   value;
  }

  get

    ;
  int length = sizeof(cli_request);

  if (cmd == cli_cmd_skip)
  {
    length += 4;
    pack4((char*)(&get.req+1), (int)value);
  }
  else if (cmd == cli_cmd_seek)
  {
    length += sizeof(cli_oid_t);
    pack_oid((char*)(&get.req+1), value);
  }

  get.req.length  = length;
  get.req.cmd     = cmd;
  get.req.stmt_id = statement;
  get.req.pack();

  if (!s->session->sock->write(&get.req, length))
  {
    return cli_network_error;
  }

  int4 response;

  if (!s->session->sock->read(&response, sizeof response))
  {
    return cli_network_error;
  }

  unpack4(response);

  if (response <= 0)
  {
    return response;
  }

  dbSmallBuffer buf(response-4);

  if (!s->session->sock->read(buf, response-4))
  {
    return cli_network_error;
  }

  char* p = buf;
  int result = cli_ok;

  if (cmd == cli_cmd_seek)
  {
    s->oid = value;
    result = unpack_oid(p);
  }
  else
  {
    s->oid = unpack_oid(p);

    if (s->oid == 0)
    {
      return cli_not_found;
    }
  }

  p += sizeof(cli_oid_t);

  for (column_binding* cb = s->columns; cb != NULL; cb = cb->next)
  {
    if (cb->set_fnc != NULL)
    {
      int len = unpack4(p);
      p += 4;
      char* dst = (char*)cb->set_fnc(cb->var_type, cb->var_ptr, len,
                                     cb->name, statement, p);

      if (dst == NULL)
      {
        continue;
      }

      if (cb->var_type == cli_array_of_string)
      {
        char** s = (char**)dst;

        while (--len >= 0)
        {
          *s++ = p;
          p += strlen(p) + 1;
        }
      }
      else if (cb->var_type >= cli_array_of_oid && cb->var_type <= cli_array_of_real8)
      {
        switch (sizeof_type[cb->var_type-cli_array_of_oid])
        {

        case 2:

          while (--len >= 0)
          {
            p = unpack2(dst, p);
            dst += 2;
          }

          break;

        case 4:

          while (--len >= 0)
          {
            p = unpack4(dst, p);
            dst += 4;
          }

          break;

        case 8:

          while (--len >= 0)
          {
            p = unpack8(dst, p);
            dst += 8;
          }

          break;

        default:
          memcpy(dst, p, len);
          p += len;
        }
      }
      else
      {
        memcpy(dst, p, len);
        p += len;
      }
    }
    else
    {
      if (cb->var_type >= cli_asciiz && cb->var_type <= cli_array_of_string)
      {
        int len = unpack4(p);
        p += 4;
        char* dst = (char*)cb->var_ptr;
        char* src = p;
        int n = len;

        if (cb->var_len != NULL)
        {
          if (n > *cb->var_len)
          {
            n = *cb->var_len;
          }

          *cb->var_len = n;
        }

        if (cb->var_type >= cli_array_of_oid)
        {
          if (cb->var_type == cli_array_of_string)
          {
            char** s = (char**)dst;
            len -= n;

            while (--n >= 0)
            {
              *s++ = p;
              p += strlen(p) + 1;
            }

            while (--len >= 0)
            {
              p += strlen(p) + 1;
            }
          }
          else
          {
            switch (sizeof_type[cb->var_type-cli_array_of_oid])
            {

            case 2:

              while (--n >= 0)
              {
                src = unpack2(dst, src);
                dst += 2;
              }

              p += len*2;
              break;

            case 4:

              while (--n >= 0)
              {
                src = unpack4(dst, src);
                dst += 4;
              }

              p += len*4;
              break;

            case 8:

              while (--n >= 0)
              {
                src = unpack8(dst, src);
                dst += 8;
              }

              p += len*8;
              break;

⌨️ 快捷键说明

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