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

Generated on Thu Aug 23 19:35:52 2007 for GigaBASE by doxygen1.2.18