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

📄 subsql.h

📁 一个不错的fastdb使用例子
💻 H
字号:
//-< SUBSQL.H >------------------------------------------------------*--------*
// 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 *
//-------------------------------------------------------------------*--------*
// Interactive data manipulation language (subset of SQL)
//-------------------------------------------------------------------*--------*

#ifndef __SUBSQL_H__
#define __SUBSQL_H__

enum SubSqlTokens {
  tkn_alter = tkn_last_token,
  tkn_array,
  tkn_autoincrement,
  tkn_autocommit,
  tkn_backup,
  tkn_bool,
  tkn_commit,
  tkn_compactify,
  tkn_count,
  tkn_create,
  tkn_delete,
  tkn_describe,
  tkn_drop,
  tkn_exit,
  tkn_export,
  tkn_hash,
  tkn_help,
  tkn_http,
  tkn_import,
  tkn_index,
  tkn_int1,
  tkn_int2,
  tkn_int4,
  tkn_int8,
  tkn_inverse,
  tkn_of,
  tkn_off,
  tkn_on,
  tkn_open,
  tkn_real4,
  tkn_real8,
  tkn_reference,
  tkn_rollback,
  tkn_server,
  tkn_set,
  tkn_stop,
  tkn_semi,
  tkn_show,
  tkn_to,
  tkn_update,
  tkn_values,
  tkn_version
};



class dbList
{

public:
  enum NodeType {
    nInteger,
    nBool,
    nReal,
    nString,
    nTuple,
    nAutoinc,
    nIdentifier
  };

  dbList* next;
  int     type;
  union {
    bool  bval;
    db_int8  ival;
    real8 fval;
    char* sval;

    struct
    {
      int     nComponents;
      dbList* components;
    }

    aggregate;
  };

  ~dbList()
  {
    if (type == nTuple)
    {
      delete aggregate.components;
    }
    else if (type == nString || type == nIdentifier)
    {
      delete[] sval;
    }
  }

  dbList(int type)
  {
    this->type = type;
    next = NULL;
  }
};


struct tableField
{
  char* name;
  char* refTableName;
  char* inverseRefName;
  int   type;

  tableField()
  {
    name = refTableName = inverseRefName = NULL;
  }

  ~tableField()
  {
    delete[] name;
    delete[] refTableName;
    delete[] inverseRefName;
  }
};

class dbUpdateElement
{

public:
  dbUpdateElement*   next;
  dbFieldDescriptor* field;
  dbExprNode*        value;
  char*              strValue;

  dbUpdateElement()
  {
    next = NULL;
    strValue = NULL;
  }

  ~dbUpdateElement()
  {
    delete[] strValue;
  }
};


#define MAX_HISTORY_SIZE 16

class dbXmlScanner
{

public:
  enum {
    MaxIdentSize = 256
  };
  enum token {
    xml_ident,
    xml_sconst,
    xml_iconst,
    xml_fconst,
    xml_lt,
    xml_gt,
    xml_lts,
    xml_gts,
    xml_eq,
    xml_eof,
    xml_error
  };
  dbXmlScanner(FILE* f)
  {
    in = f;
    sconst = new char[size = 1024];
    line = 1;
    pos = 0;
  }

  token scan();

  char* getString()
  {
    return sconst;
  }

  char* getIdentifier()
  {
    return ident;
  }

  size_t  getStringLength()
  {
    return slen;
  }

  db_int8 getInt()
  {
    return iconst;
  }

  double getReal()
  {
    return fconst;
  }

  bool expect(int sourcePos, token expected)
  {
    token tkn = scan();

    if (tkn != expected)
    {
      fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected token %d\n",
              sourcePos, line, pos, tkn, expected);
      return false;
    }

    return true;
  }

  bool expect(int sourcePos, char* expected)
  {
    token tkn = scan();

    if (tkn != xml_ident)
    {
      fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected identifier\n",
              sourcePos, line, pos, tkn);
      return false;
    }

    if (strcmp(ident, expected) != 0)
    {
      fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get tag '%s' instead of expected '%s'\n",
              sourcePos, line, pos, ident, expected);
      return false;
    }

    return true;
  }

private:

  int   get
    ();

  void  unget(int ch);

  int       line;

  int       pos;

  FILE*     in;

  char*     sconst;

  size_t    size;

  size_t    slen;

  db_int8   iconst;

  double    fconst;

  char      ident[MaxIdentSize];
};

class dbTmpAllocator
{
  enum {
    CHUNK_SIZE = 4096
  };

  struct Chunk
  {
    Chunk* next;
    Chunk* prev; // is not used, added for alignment
  };

  Chunk* curr;
  size_t used;

public:
  dbTmpAllocator()
  {
    curr = NULL;
    used = CHUNK_SIZE;
  }

  ~dbTmpAllocator()
  {
    reset();
  }

  void reset()
  {
    Chunk *c, *next;

    for (c = curr; c != NULL; c = next)
    {
      next = c->next;
      dbFree(c);
    }

    curr = NULL;
    used = CHUNK_SIZE;
  }


  void* alloc(size_t size)
  {
    size = DOALIGN(size, 8);

    if (size > CHUNK_SIZE/2)
    {
      Chunk* newChunk = (Chunk*)dbMalloc(size + sizeof(Chunk));

      if (curr != NULL)
      {
        newChunk->next = curr->next;
        curr->next = newChunk;
      }
      else
      {
        curr = newChunk;
        newChunk->next = NULL;
        used = CHUNK_SIZE;
      }

      return newChunk+1;
    }
    else if (size <= CHUNK_SIZE - used)
    {
      used += size;
      return (char*)(curr+1) + used - size;
    }
    else
    {
      Chunk* newChunk = (Chunk*)dbMalloc(CHUNK_SIZE);
      used = sizeof(Chunk) + size;
      newChunk->next = curr;
      curr = newChunk;
      return newChunk+1;
    }
  }
};

class dbSubSql : public dbDatabase
{

private:
  int   pos;
  int   line;
  int   tknPos;
  char* buf;
  int   buflen;
  FILE* in;
  bool  opened;
  db_int8  ival;
  real8 fval;
  char* name;

  oid_t*  oidMap;
  oid_t   oidMapSize;

  dbTmpAllocator tmpAlloc;

  static char* prompt;

  dbTableDescriptor* droppedTables;
  dbTableDescriptor* existedTables;

  dbQuery query;
  dbCompiler compiler;

  int      ungetToken;
  bool     autocommit;

  dbThread httpServerThread;
  HTTPapi* httpServer;
  bool     httpServerRunning;
  char*    queryHistory[MAX_HISTORY_SIZE];
  unsigned historyUsed;
  unsigned historyCurr;
  static void thread_proc httpServerThreadProc(void* arg);

  void httpServerLoop();

  void startHttpServer(char const* address);
  void stopHttpServer(char const* address);

  void handleError(dbErrorClass error, char const* msg = NULL,  int arg = 0);

  void error(char const* msg);
  void warning(char const* msg);

  int  get
    ();

  void unget(int ch);

  int  scan();

  bool parse();

  bool expect(char* expected, int token);

  void recovery();

  void exportDatabase(FILE* out);

  bool importDatabase(FILE* in);

  oid_t mapId(long id);

  bool importField(char* terminator, dbFieldDescriptor* fd, byte* rec, dbXmlScanner& scanner);

  bool importRecord(char* terminator, dbFieldDescriptor* fieldList, byte* rec, dbXmlScanner& scanner);

  void insertRecord(dbTableDescriptor* desc, oid_t oid, void const* record);

  bool isValidOid(oid_t oid);

  static void dumpRecord(byte* record, dbFieldDescriptor* first);

  static int calculateRecordSize(dbList* list, int offs,
                                 dbFieldDescriptor* first);

  int  initializeRecordFields(dbList* node, byte* dst, int offs,
                              dbFieldDescriptor* first);

  bool insertRecord(dbList* list, dbTableDescriptor* desc);

  bool readCondition();

  int  readExpression();

  int  readValues(dbList** chain);

  bool updateFields(dbAnyCursor* cursor, dbUpdateElement* elems);

  bool updateTable(bool create);

  int  parseType(char*& refTableName, char*& inverseRefName);

  int  updateRecords(dbTableDescriptor* desc, dbList *fields, dbList *values, dbAnyCursor &cursor, byte *buf);

  dbFieldDescriptor* readFieldName();

public:
  void run(int firstParam, int argc, char* argv[]);

  void selectionPage(WWWconnection& con);

  void queryPage(WWWconnection& con);

  void defaultPage(WWWconnection& con);

  dbSubSql(dbAccessType accessType);

  virtual~dbSubSql();
};


#endif

⌨️ 快捷键说明

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