localcli.cpp

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

CPP
3,024
字号
int cli_get_first(int statement)
{
  return dbCLI::instance.get_first(statement);
}

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

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

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

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

  return fetch_columns(stmt);
}

int cli_get_last(int statement)
{
  return dbCLI::instance.get_last(statement);
}

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

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

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

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

  return fetch_columns(stmt);
}

int cli_get_next(int statement)
{
  return dbCLI::instance.get_next(statement);
}

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

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

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

  if (!((stmt->first_fetch && stmt->cursor.gotoFirst()) ||
        (!stmt->first_fetch && stmt->cursor.gotoNext())))
  {
    return cli_not_found;
  }

  return fetch_columns(stmt);
}

int cli_get_prev(int statement)
{
  return dbCLI::instance.get_prev(statement);
}

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

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

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

  if (!((stmt->first_fetch && stmt->cursor.gotoLast()) ||
        (!stmt->first_fetch && stmt->cursor.gotoPrev())))
  {
    return cli_not_found;
  }

  return fetch_columns(stmt);
}

int cli_skip(int statement, int n)
{
  return dbCLI::instance.skip(statement, n);
}

int dbCLI::skip(int statement, int n)
{
  statement_desc* stmt = statements.get(statement);

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

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

  if ((n > 0 && !((stmt->first_fetch && stmt->cursor.gotoFirst() && stmt->cursor.skip(n-1)
                   || (!stmt->first_fetch && stmt->cursor.skip(n)))))
      || (n < 0 && !((stmt->first_fetch && stmt->cursor.gotoLast() && stmt->cursor.skip(n+1)
                      || (!stmt->first_fetch && stmt->cursor.skip(n))))))
  {
    return cli_not_found;
  }

  return fetch_columns(stmt);
}


int cli_seek(int statement, cli_oid_t oid)
{
  return dbCLI::instance.seek(statement, oid);
}

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

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

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

  int pos = stmt->cursor.seek(oid);

  if (pos < 0)
  {
    return cli_not_found;
  }

  int rc = fetch_columns(stmt);

  if (rc == cli_ok)
  {
    return pos;
  }
  else
  {
    return rc;
  }
}


cli_oid_t cli_get_oid(int statement)
{
  return dbCLI::instance.get_current_oid(statement);
}

cli_oid_t dbCLI::get_current_oid(int statement)
{
  statement_desc* s = statements.get(statement);

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

  return s->cursor.currId;
}


int cli_free(int statement)
{
  return dbCLI::instance.free_statement(statement);
}

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

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

  return free_statement(stmt);
}

int dbCLI::free_statement(statement_desc* stmt)
{
  {
    dbCriticalSection cs(stmt->session->mutex);
    statement_desc *sp, **spp = &stmt->session->stmts;

    while ((sp = *spp) != stmt)
    {
      if (sp == NULL)
      {
        return cli_bad_descriptor;
      }

      spp = &sp->next;
    }

    *spp = stmt->next;
  }

  column_binding *cb, *next_cb;

  for (cb = stmt->columns; cb != NULL; cb = next_cb)
  {
    next_cb = cb->next;
    delete[] cb->name;
    column_allocator.free(cb);
  }

  parameter_binding *pb, *next_pb;

  for (pb = stmt->params; pb != NULL; pb = next_pb)
  {
    next_pb = pb->next;
    delete[] pb->name;
    parameter_allocator.free(pb);
  }

  statements.free(stmt);
  return cli_ok;
}


int cli_commit(int session)
{
  return dbCLI::instance.commit(session);
}

int dbCLI::commit(int session)
{
  session_desc* s = sessions.get(session);

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

  while (s->dropped_tables != NULL)
  {
    dbTableDescriptor* next = s->dropped_tables->nextDbTable;
    delete s->dropped_tables;
    s->dropped_tables = next;
  }

  s->db->commit();
  s->existed_tables = s->db->tables;
  return cli_ok;
}

int cli_precommit(int session)
{
  return dbCLI::instance.precommit(session);
}

int dbCLI::precommit(int session)
{
  session_desc* s = sessions.get(session);

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

  s->db->precommit();
  return cli_ok;
}

int cli_abort(int session)
{
  return dbCLI::instance.abort(session);
}

int dbCLI::abort(int session)
{
  session_desc* s = sessions.get(session);

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

  dbDatabase* db = s->db;

  while (s->dropped_tables != NULL)
  {
    dbTableDescriptor* next = s->dropped_tables->nextDbTable;
    db->linkTable(s->dropped_tables, s->dropped_tables->tableId);
    s->dropped_tables = next;
  }

  s->db->rollback();

  while (db->tables != s->existed_tables)
  {
    dbTableDescriptor* table = db->tables;
    db->unlinkTable(table);
    delete table;
  }

  return cli_ok;
}


int cli_remove(int statement)
{
  return dbCLI::instance.remove(statement);
}

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

  if (stmt == NULL || !stmt->prepared)
  {
    return cli_bad_descriptor;
  }

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

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

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

int cli_describe(int session, char const* table, cli_field_descriptor** fields)
{
  return dbCLI::instance.describe(session, table, fields);
}

int dbCLI::describe(int session, char const* table, cli_field_descriptor** fields)
{
  session_desc* s = sessions.get(session);

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

  dbDatabase* db = s->db;
  dbTableDescriptor* desc = db->findTableByName(table);

  if (desc == NULL)
  {
    return cli_table_not_found;
  }
  else
  {
    int nColumns = desc->nColumns;
    cli_field_descriptor* fp =
      (cli_field_descriptor*)malloc(nColumns*sizeof(cli_field_descriptor));
    dbFieldDescriptor* fd = desc->columns;
    *fields = fp;

    for (int i = 0; i < nColumns; i++, fp++)
    {
      fp->type = (cli_var_type)map_type(fd);
      fp->name = fd->name;
      fp->refTableName = (fd->type == dbField::tpArray) ? fd->components->refTableName : fd->refTableName;
      fp->inverseRefFieldName = fd->inverseRefName;
      fp->flags = 0;
      fp->size= fd->appSize;
      fp->offs= fd->appOffs;

      if (fd->tTree != 0)
      {
        fp->flags |= cli_indexed;
      }

      if (fd->hashTable != 0)
      {
        fp->flags |= cli_hashed;
      }

      fd = fd->next;
    }

    return nColumns;
  }
}


int cli_show_tables(int session, cli_table_descriptor** tables)
{
  return dbCLI::instance.show_tables(session, tables);
}

int dbCLI::show_tables(int session, cli_table_descriptor** tables)
{
  session_desc* s = sessions.get(session);

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

  dbTableDescriptor* desc;
  int nTables = 0;

  for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable)
  {
    if (strcmp(desc->name, "Metatable"))
    {
      nTables += 1;
    }
  }

  if (nTables != 0)
  {
    cli_table_descriptor* td = (cli_table_descriptor*)malloc(nTables*sizeof(cli_table_descriptor));
    *tables = td;

    for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable)
    {
      if (strcmp(desc->name, "Metatable"))
      {
        td->name = desc->name;
        td += 1;
      }
    }
  }
  else
  {
    *tables = NULL;
  }

  return nTables;
}


#define MAX_QUERY_INDETIFIER_LENGTH 256

int sql_scanner::get
  ()
{
  char buf[MAX_QUERY_INDETIFIER_LENGTH];
  int i = 0, ch;

  do
  {
    ch = *p++;

    if (ch == '\0')
    {
      return tkn_eof;
    }
  }
  while (ch > 0 && ch <= 32);

  if (ch == '*')
  {
    return tkn_all;
  }
  else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-')
  {
    int const_type = tkn_iconst;

    while (true)
    {
      ch = *p++;

      if (ch == '.' || ch == 'e' || ch == 'E')
      {
        const_type = tkn_fconst;
      }
      else if (!((ch >= '0' && ch <= '9') || ch == '+' || ch == '-'))
      {
        break;
      }
    }

    return const_type;
  }
  else if (isalnum(ch) || ch == '$' || ch == '_')
  {
    do
    {
      buf[i++] = ch;

      if (i == MAX_QUERY_INDETIFIER_LENGTH)
      {
        // Identifier too long
        return tkn_error;
      }

      ch = *p++;
    }
    while (ch != EOF && (isalnum(ch) || ch == '$' || ch == '_'));

    p -= 1;

    buf[i] = '\0';

    ident = buf;

    return dbSymbolTable::add
             (ident, tkn_ident);
  }
  else
  {
    // Invalid symbol
    return tkn_error;
  }
}


int cli_create_table(int session, char const* tableName, int nColumns,
                     cli_field_descriptor* columns)
{
  return dbCLI::instance.create_table(session, tableName, nColumns, columns);
}


int dbCLI::create_table(int session, char const* tableName, int nColumns,
                        cli_field_descriptor* columns)
{
  session_desc* s = sessions.get(session);

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

  s->db->beginTransaction(dbDatabase::dbExclusiveLock);

  if (s->existed_tables == NULL)
  {
    s->existed_tables = s->db->tables;
  }

  return create_table(s->db, tableName, nColumns, columns);
}


int dbCLI::create_table(dbDatabase* db, char const* tableName, int nColumns,
                        cli_field_descriptor* columns)
{
  int i;
  db->modified = true;

  if (db->findTableByName(tableName) != NULL)
  {
    return cli_table_already_exists;
  }

  int nFields = nColumns;
  int varyingLength = strlen(tableName) + 1;

  for (i = 0; i < nColumns; i++)
  {
    int type = columns[i].type;
    varyingLength += strlen(columns[i].name) + 3;

    if (type == cli_oid || type == cli_array_of_oid)
    {
      varyingLength += strlen(columns[i].refTableName);

      if (columns[i].inverseRefFieldName != NULL)
      {
        varyingLength += strlen(columns[i].inverseRefFieldName);
      }
    }

    switch (type)

⌨️ 快捷键说明

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