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

Generated on Mon Oct 23 13:22:59 2006 for GigaBASE by doxygen1.2.18