Main Page | Class Hierarchy | Class List | File List | Class Members

subsql.h

00001 //-< SUBSQL.H >------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Interactive data manipulation language (subset of SQL)
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __SUBSQL_H__
00012 #define __SUBSQL_H__
00013 
00014 BEGIN_GIGABASE_NAMESPACE
00015 
00016 enum SubSqlTokens {
00017     tkn_alter = tkn_last_token,
00018     tkn_array,
00019     tkn_autoincrement,
00020     tkn_autocommit,
00021     tkn_backup,
00022     tkn_bool,
00023     tkn_commit,
00024     tkn_compactify,
00025     tkn_count,
00026     tkn_create,
00027     tkn_delete,
00028     tkn_describe,
00029     tkn_drop,
00030     tkn_exit,
00031     tkn_export,
00032     tkn_hash,
00033     tkn_help,
00034     tkn_http, 
00035     tkn_import,
00036     tkn_index,
00037     tkn_int1,
00038     tkn_int2,
00039     tkn_int4,
00040     tkn_int8,
00041     tkn_inverse,
00042     tkn_of,
00043     tkn_off,
00044     tkn_on,
00045     tkn_open,
00046     tkn_real4,
00047     tkn_real8,
00048     tkn_rectangle,
00049     tkn_reference,
00050     tkn_restore,
00051     tkn_rollback,
00052     tkn_server,
00053     tkn_set,
00054     tkn_stop,
00055     tkn_semi,
00056     tkn_show,
00057     tkn_to,
00058     tkn_update,
00059     tkn_values,
00060     tkn_version
00061 };
00062 
00063 struct tableField {
00064     char_t* name;
00065     char_t* refTableName;
00066     char_t* inverseRefName;
00067     int     type;
00068 
00069     tableField() { name = refTableName = inverseRefName = NULL; }
00070     ~tableField() { delete[] name; delete[] refTableName; delete[] inverseRefName; }
00071 };
00072 
00073 
00074 class dbList {
00075   public:
00076     enum NodeType {
00077         nInteger,
00078         nBool,
00079         nReal,
00080         nString,
00081         nTuple,
00082         nAutoinc
00083     };
00084 
00085     dbList* next;
00086     int type;
00087     union {
00088         bool    bval;
00089         db_int8 ival;
00090         real8   fval;
00091         char_t* sval;
00092         struct {
00093             int     nComponents;
00094             dbList* components;
00095         } aggregate;
00096     };
00097 
00098     ~dbList() {
00099         if (type == nTuple) {
00100             dbList* list = aggregate.components;
00101             while (list != NULL) { 
00102                 dbList* tail = list->next;
00103                 delete list;
00104                 list = tail;
00105             }
00106         } else if (type == nString) {
00107             delete[] sval;
00108         }
00109     }
00110 
00111     dbList(int type) {
00112         this->type = type;
00113         next = NULL;
00114     }
00115 };
00116 
00117 class dbUpdateElement { 
00118   public:
00119     dbUpdateElement*   next;
00120     dbFieldDescriptor* field;
00121     dbExprNode*        value;
00122     char_t*            strValue;
00123 
00124     dbUpdateElement() { 
00125         next = NULL;
00126         strValue = NULL;
00127         value = NULL;
00128     }
00129     ~dbUpdateElement() { 
00130         delete[] strValue;
00131         delete value;
00132     }
00133 };
00134 
00135 
00136 #define MAX_HISTORY_SIZE 16
00137 
00138 class dbXmlScanner { 
00139   public:
00140     enum { 
00141         MaxIdentSize = 256
00142     };
00143     enum token { 
00144         xml_ident, 
00145         xml_sconst, 
00146         xml_iconst, 
00147         xml_fconst, 
00148         xml_lt, 
00149         xml_gt, 
00150         xml_lts, 
00151         xml_gts,
00152         xml_eq, 
00153         xml_eof,
00154         xml_error
00155     };    
00156     dbXmlScanner(FILE* f) { 
00157         in = f;
00158         sconst = new char_t[size = 1024];
00159         line = 1;
00160         pos = 0;
00161     }
00162     token scan();
00163 
00164     char_t* getString() { 
00165         return sconst;
00166     }
00167 
00168     char_t* getIdentifier() { 
00169         return ident;
00170     }
00171 
00172     size_t  getStringLength() { 
00173         return slen;
00174     }
00175 
00176     db_int8 getInt() { 
00177         return iconst;
00178     }
00179 
00180     double getReal() { 
00181         return fconst;
00182     }
00183 
00184     bool expect(int sourcePos, token expected) { 
00185         return assure(scan(), sourcePos, expected);
00186     }
00187 
00188     bool assure(token tkn, int sourcePos, token expected) { 
00189         if (tkn != expected) { 
00190             fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected token %d\n", 
00191                     sourcePos, line, pos, tkn, expected);
00192             return false;
00193         }
00194         return true;
00195     }
00196 
00197     bool expect(int sourcePos, char_t* expected) { 
00198         token tkn = scan();
00199         if (tkn != xml_ident) { 
00200             fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected identifier\n", 
00201                     sourcePos, line, pos, tkn);
00202             return false;
00203         }
00204         if (STRCMP(ident, expected) != 0) { 
00205             FPRINTF(stderr, STRLITERAL("subsql.cpp:%d: line %d, column %d: Get tag '%s' instead of expected '%s'\n"), 
00206                     sourcePos, line, pos, ident, expected);
00207             return false;
00208         }
00209         return true;
00210     }
00211 
00212   private:
00213     int   get();
00214     void  unget(int ch);
00215 
00216     int       line;
00217     int       pos;
00218     FILE*     in;
00219     char_t*   sconst;
00220     size_t    size;
00221     size_t    slen;
00222     db_int8   iconst;
00223     double    fconst;
00224     char_t    ident[MaxIdentSize];
00225 };
00226 
00227 class dbTmpAllocator { 
00228     enum { 
00229         CHUNK_SIZE = 4096
00230     };
00231     struct Chunk { 
00232         Chunk* next;
00233         Chunk* prev; // is not used, added for alignment
00234     };
00235     Chunk* curr;
00236     size_t used;
00237 
00238   public:
00239     dbTmpAllocator() { 
00240         curr = NULL;
00241         used = CHUNK_SIZE;
00242     }
00243 
00244     ~dbTmpAllocator() { 
00245         reset();
00246     }
00247 
00248     void reset() { 
00249         Chunk *c, *next; 
00250         for (c = curr; c != NULL; c = next) { 
00251             next = c->next;
00252             dbFree(c);
00253         }
00254         curr = NULL;
00255         used = CHUNK_SIZE;
00256     }
00257 
00258 
00259     void* alloc(size_t size) { 
00260         size = DOALIGN(size, 8);
00261         if (size > CHUNK_SIZE/2) { 
00262             Chunk* newChunk = (Chunk*)dbMalloc(size + sizeof(Chunk));
00263             if (curr != NULL) { 
00264                 newChunk->next = curr->next;
00265                 curr->next = newChunk;
00266             } else { 
00267                 curr = newChunk;
00268                 newChunk->next = NULL;
00269                 used = CHUNK_SIZE;
00270             }
00271             return newChunk+1;
00272         } else if (size <= CHUNK_SIZE - used) { 
00273             used += size;
00274             return (char*)curr + used - size;
00275         } else { 
00276             Chunk* newChunk = (Chunk*)dbMalloc(CHUNK_SIZE);
00277             used = sizeof(Chunk) + size;
00278             newChunk->next = curr;
00279             curr = newChunk;
00280             return newChunk+1;
00281         }
00282     }
00283 };
00284 
00285     
00286 class dbSubSql : public dbDatabase {
00287   private:
00288     int     pos;
00289     int     line;
00290     int     tknPos;
00291     char_t* buf;
00292     int     buflen;
00293     FILE*   in;
00294     bool    opened;
00295     db_int8 ival;
00296     real8   fval;
00297     char_t* name;
00298 
00299     oid_t*  oidMap;
00300     oid_t   oidMapSize;
00301 
00302     dbTmpAllocator tmpAlloc;
00303     
00304     dbTableDescriptor* metatable;
00305     static char const* prompt;
00306 
00307     dbTableDescriptor* droppedTables;
00308     dbTableDescriptor* existedTables;
00309 
00310     dbQuery query;
00311     dbCompiler compiler;
00312 
00313     int      ungetToken;
00314     bool     autocommit;
00315 
00316     bool     dotIsPartOfIdentifier;
00317 
00318     char_t*  dateFormat;
00319 
00320     dbEvent  daemonTerminationEvent;
00321     dbThread httpServerThread;
00322     HTTPapi* httpServer;
00323     bool     httpServerRunning;
00324     char_t*  databasePath;
00325     char*    queryHistory[MAX_HISTORY_SIZE];
00326     unsigned historyUsed;
00327     unsigned historyCurr;
00328 
00329     static void thread_proc httpServerThreadProc(void* arg);
00330 
00331     void deleteColumns(dbFieldDescriptor* columns);
00332     
00333     void httpServerLoop();
00334 
00335     void startHttpServer(char_t const* address);
00336     void stopHttpServer(char_t const* address);
00337 
00338     void handleError(dbErrorClass error, char const* msg = NULL,  int arg = 0);
00339 
00340     void warning(char const* msg);
00341     void error(char const* msg);
00342 
00343     int  get();
00344     void unget(int ch);
00345     int  scan();
00346     bool parse();
00347 
00348     bool expect(char const* expected, int token);
00349 
00350     void recovery();
00351 
00352     void exportDatabase(FILE* out);
00353     bool importDatabase(FILE* in);
00354    
00355     oid_t mapId(long id);
00356     bool importField(char_t* terminator, dbFieldDescriptor* fd, byte* rec, dbXmlScanner& scanner);
00357     bool importRecord(char_t* terminator, dbFieldDescriptor* fieldList, byte* rec, dbXmlScanner& scanner);
00358     void insertRecord(dbTableDescriptor* desc, oid_t oid, void const* record);
00359 
00360     bool isValidOid(oid_t oid);
00361 
00362     void dumpRecord(byte* record, dbFieldDescriptor* first);
00363     static int calculateRecordSize(dbList* list, int offs,
00364                                    dbFieldDescriptor* first);
00365     int  initializeRecordFields(dbList* node, byte* dst, int offs,
00366                                       dbFieldDescriptor* first);
00367     bool insertRecord(dbList* list, dbTableDescriptor* desc);
00368     bool readCondition();
00369     int  readExpression();
00370     int  readValues(dbList** chain);
00371     bool updateFields(dbAnyCursor* cursor, dbUpdateElement* elems);
00372     bool updateTable(bool create);
00373     int  parseType(char_t*& reftableName, char_t*& inverseRefName);
00374     int  updateRecords(dbTableDescriptor* desc, dbList *fields, dbList *values, dbAnyCursor &cursor, byte *buf);
00375 
00376     dbFieldDescriptor* readFieldName();
00377   public:
00378     void run(int argc, char* argv[]);
00379     void selectionPage(WWWconnection& con);
00380     void queryPage(WWWconnection& con);
00381     void defaultPage(WWWconnection& con);
00382 
00383     dbSubSql(dbAccessType type = dbAllAccess, size_t poolSize = 0);
00384     virtual~dbSubSql();
00385 };
00386 
00387 END_GIGABASE_NAMESPACE
00388 
00389 
00390 #endif

Generated on Thu Nov 24 23:14:30 2005 for GigaBASE by doxygen 1.3.5