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

📄 subsql.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-< SUBSQL.CPP >----------------------------------------------------*--------*// 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)//-------------------------------------------------------------------*--------*#include <stdio.h>#include <ctype.h>#include "fastdb.h"#include "compiler.h"#include "wwwapi.h"#include "subsql.h"#include "symtab.h"#include "hashtab.h"#include "ttree.h"#include "rtree.h"#if THREADS_SUPPORTED#include "server.h"#endifBEGIN_FASTDB_NAMESPACEstatic char* typeMnem[] = {        "Boolean",        "Int1",        "Int2",        "Int4",        "Int8",        "Real4",        "Real8",        "String",        "Reference",        "Array",        "MethodBool",        "MethodInt1",        "MethodInt2",        "MethodInt4",        "MethodInt8",        "MethodReal4",        "MethodReal8",        "MethodString",        "MethodReference",        "Structure",        "RawBinary",        "StdString",        "Rectangle",        "Unknown" };char* dbSubSql::prompt = ">> ";dbSubSql::dbSubSql(dbAccessType accessType): dbDatabase(accessType){    static struct {         char* name;        int   tag;    } keywords[] = {         {"alter",   tkn_alter},        {"array",   tkn_array},        {"autocommit",   tkn_autocommit},        {"autoincrement",tkn_autoincrement},        {"backup",  tkn_backup},                {"bool",    tkn_bool},        {"commit",  tkn_commit},        {"compactify",tkn_compactify},        {"count",   tkn_count},        {"create",  tkn_create},        {"delete",  tkn_delete},        {"describe",tkn_describe},        {"drop",    tkn_drop},        {"exit",    tkn_exit},        {"export",  tkn_export},        {"hash",    tkn_hash},        {"help",    tkn_help},        {"http",    tkn_http},        {"import",  tkn_import},        {"index",   tkn_index},        {"int1",    tkn_int1},        {"int2",    tkn_int2},        {"int4",    tkn_int4},        {"int8",    tkn_int8},        {"inverse", tkn_inverse},        {"of",      tkn_of},        {"off",     tkn_off},        {"on",      tkn_on},        {"open",    tkn_open},        {"profile", tkn_profile},                {"reference",tkn_reference},        {"real4",   tkn_real4},        {"real8",   tkn_real8},        {"rectangle", tkn_rectangle},        {"rollback",tkn_rollback},        {"server",  tkn_server},        {"set",     tkn_set},        {"stop",    tkn_stop},        {"show",    tkn_show},        {"to",      tkn_to},        {"update",  tkn_update},        {"values",  tkn_values},        {"version", tkn_version}    };    for (unsigned i = 0; i < itemsof(keywords); i++) {         dbSymbolTable::add(keywords[i].name, keywords[i].tag, FASTDB_CLONE_ANY_IDENTIFIER);        }    droppedTables = NULL;    existedTables = NULL;    opened = false;    buflen = 1024;    buf = new char[buflen];    httpServerRunning = false;    databaseName = NULL;    historyUsed = historyCurr = 0;    ungetToken = -1;    dotIsPartOfIdentifier = false;    autocommit = false;    dateFormat = getenv("SUBSQL_DATE_FORMAT");}dbSubSql::~dbSubSql() {        delete[] buf; }//// Find one string within another, ignoring case//inline char* stristr(const char* haystack, const char* needle){    nat4 i, hayLen, ndlLen;    ndlLen = strlen(needle);    hayLen = strlen(haystack);    if (ndlLen > hayLen) {        return NULL;    }    for (i = 0; i <= (hayLen - ndlLen); i++) {        if (strincmp(&haystack[i], needle, ndlLen) == 0) {            return (char*)&haystack[i];        }    }    return NULL;}bool contains(dbUserFunctionArgument& arg1, dbUserFunctionArgument& arg2) {     assert(arg1.type == dbUserFunctionArgument::atString && arg2.type == dbUserFunctionArgument::atString);    return stristr(arg1.u.strValue, arg2.u.strValue) != NULL;}USER_FUNC(contains);char* cmpOidAndStr(dbUserFunctionArgument& arg1, dbUserFunctionArgument& arg2) {     assert(arg1.type == dbUserFunctionArgument::atReference && arg2.type == dbUserFunctionArgument::atString);        printf("arg1.u.oidValue=%x, arg1.u.strValue=%s\n", arg1.u.oidValue, arg2.u.strValue);    char* ptr = new char[16];    sprintf(ptr, "%x", arg1.u.oidValue);    return ptr;}USER_FUNC(cmpOidAndStr);int dbSubSql::get() {    int ch = getc(in);    if (ch == '\n') {         pos = 0;        line += 1;    } else if (ch == '\t') {        pos = DOALIGN(pos + 1, 8);    } else {          pos += 1;    }    return ch;}void dbSubSql::unget(int ch) {     if (ch != EOF) {         if (ch != '\n') {             pos -= 1;        } else {             line -= 1;        }        ungetc(ch, in);    }}void dbSubSql::warning(char const* msg){    fprintf(stderr, "%s at line %d position %d\n", msg, line, tknPos > 0 ? tknPos - 1 : 0);}void dbSubSql::error(char const* msg){#ifdef THROW_EXCEPTION_ON_ERROR   dbDatabaseThreadContext* ctx = threadContext.get();    if (ctx != NULL) {        ctx->interactive = true;    }    try {         handleError(QueryError, msg, tknPos > 0 ? tknPos - 1 : 0);    } catch(dbException) {}#else    dbDatabaseThreadContext* ctx = threadContext.get();    if (ctx != NULL) {         ctx->interactive = true;        ctx->catched = true;        if (setjmp(ctx->unwind) == 0) {             handleError(QueryError, msg, tknPos > 0 ? tknPos - 1 : 0);        }        ctx->catched = false;    } else {         handleError(QueryError, msg, tknPos > 0 ? tknPos - 1 : 0);    }#endif}int dbSubSql::scan() {    int i, ch, digits;        if (ungetToken >= 0) {         int tkn = ungetToken;        ungetToken = -1;        return tkn;    }    bool dotIsIdentifierChar = dotIsPartOfIdentifier;    dotIsPartOfIdentifier = false;  nextToken:    do {         if ((ch = get()) == EOF) {             return tkn_eof;        }    } while (isspace(ch));        tknPos = pos;    switch (ch) {       case '*':        return tkn_all;      case '(':        return tkn_lpar;      case ')':        return tkn_rpar;      case ',':        return tkn_comma;      case '.':        return tkn_dot;      case ';':        return tkn_semi;      case '=':        return tkn_eq;      case '\'':        i = 0;         while (true) {             ch = get();            if (ch == '\'') {                 if ((ch = get()) != '\'') {                     unget(ch);                    break;                }            } else if (ch == '\n' || ch == EOF) {                 unget(ch);                error("New line within character constant");                return tkn_error;            }            if (i+1 == buflen) {                 char* newbuf = new char[buflen*2];                memcpy(newbuf, buf, buflen);                delete[] buf;                buf = newbuf;                buflen *= 2;            }            buf[i++] = ch;        }        buf[i] = '\0';        return tkn_sconst;      case '-':        if ((ch = get()) == '-') {             // ANSI comments            while ((ch = get()) != EOF && ch != '\n');            goto nextToken;        }        unget(ch);        ch = '-';        // no break      case '0': case '1': case '2': case '3': case '4':       case '5': case '6': case '7': case '8': case '9':      case '+':        i = 0;        do {             buf[i++] = ch;            if (i == buflen) {                 error("Numeric constant too long");                return tkn_error;            }            ch = get();        } while (ch != EOF                  && (isdigit(ch) || ch == '+' || ch == '-' || ch == 'e' ||                      ch == 'E' || ch == '.'));        unget(ch);        buf[i] = '\0';        if (sscanf(buf, INT8_FORMAT "%n", &ival, &digits) != 1) {             error("Bad integer constant");            return tkn_error;        }        if (digits != i) {             if (sscanf(buf, "%lf%n", &fval, &digits) != 1 || digits != i) {                error("Bad float constant");                return tkn_error;            }            return tkn_fconst;        }         return tkn_iconst;      case '#':        ival = 0;        while (true) {             ch = get();            if (ch >= '0' && ch <= '9') {                 ival += (ival << 4) + ch-'0';            } else if (ch >= 'a' && ch <= 'f') {                ival += (ival << 4) + ch-'a'+10;            } else if (ch >= 'A' && ch <= 'F') {                ival += (ival << 4) + ch-'A'+10;            } else {                 unget(ch);                return tkn_iconst;            }        }      default:        if (isalpha(ch) || ch == '$' || ch == '_') {             i = 0;            do {                 buf[i++] = ch;                if (i == buflen) {                     error("Identifier too long");                    return tkn_error;                }                ch = get();            } while (ch != EOF && (isalnum(ch) || ch == '$' || ch == '_' || (ch == '.' && dotIsIdentifierChar)));            unget(ch);            buf[i] = '\0';            name = buf;            return dbSymbolTable::add(name, tkn_ident);        } else {             error("Invalid symbol");            return tkn_error;        }    }}bool dbSubSql::expect(char* expected, int token){    int tkn = scan();    if (tkn != token) {         if (tkn != tkn_error) {             char buf[256];            sprintf(buf, "Token '%s' expected", expected);            error(buf);        }        return false;    }    return true;}    bool dbSubSql::updateTable(bool create){    int tkn;    dotIsPartOfIdentifier = true;    if (!expect("table name", tkn_ident) || !expect("(", tkn_lpar)) { 

⌨️ 快捷键说明

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