00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __SERVER_H__
00012 #define __SERVER_H__
00013
00014 #include "sockio.h"
00015
00016 BEGIN_GIGABASE_NAMESPACE
00017
00018 class dbColumnBinding {
00019 public:
00020 dbColumnBinding* next;
00021 dbFieldDescriptor* fd;
00022 int cliType;
00023 int len;
00024 char* ptr;
00025
00026 int unpackArray(char* dst, size_t& offs);
00027 void unpackScalar(char* dst, bool insert);
00028
00029 dbColumnBinding(dbFieldDescriptor* field, int type) {
00030 fd = field;
00031 cliType = type;
00032 next = NULL;
00033 }
00034 };
00035
00036 struct dbParameterBinding {
00037 union {
00038 int1 i1;
00039 int2 i2;
00040 int4 i4;
00041 db_int8 i8;
00042 real4 r4;
00043 real8 r8;
00044 oid_t oid;
00045 bool b;
00046 char_t* str;
00047 rectangle rect;
00048 } u;
00049 int type;
00050 };
00051
00052 const int dbQueryMaxIdLength = 256;
00053
00054 class dbQueryScanner {
00055 public:
00056 char* p;
00057 db_int8 ival;
00058 real8 fval;
00059 char_t buf[dbQueryMaxIdLength];
00060 char_t* ident;
00061
00062 int get();
00063
00064 void reset(char* sql) {
00065 p = sql;
00066 }
00067 };
00068
00069 class dbStatement {
00070 public:
00071 int id;
00072 bool firstFetch;
00073 dbStatement* next;
00074 dbAnyCursor* cursor;
00075 dbQuery query;
00076 dbColumnBinding* columns;
00077 char* buf;
00078 int buf_size;
00079 int n_params;
00080 int n_columns;
00081 dbParameterBinding* params;
00082 dbTableDescriptor* table;
00083
00084 void reset();
00085
00086 dbStatement(int stmt_id) {
00087 id = stmt_id;
00088 columns = NULL;
00089 params = NULL;
00090 buf = NULL;
00091 buf_size = 0;
00092 table = NULL;
00093 cursor = NULL;
00094 }
00095 ~dbStatement() {
00096 reset();
00097 delete[] buf;
00098 }
00099 };
00100
00101 struct UserInfo {
00102 char_t const* user;
00103 char_t const* password;
00104
00105 TYPE_DESCRIPTOR((KEY(user, INDEXED), FIELD(password)));
00106 };
00107
00108
00109 class dbClientSession {
00110 public:
00111 dbClientSession* next;
00112 dbStatement* stmts;
00113 dbQueryScanner scanner;
00114 socket_t* sock;
00115 bool in_transaction;
00116 dbTableDescriptor* dropped_tables;
00117 dbTableDescriptor* existed_tables;
00118 };
00119 class GIGABASE_DLL_ENTRY dbServer {
00120 protected:
00121 static dbServer* chain;
00122 dbServer* next;
00123 char_t* URL;
00124 char* address;
00125 dbClientSession* freeList;
00126 dbClientSession* waitList;
00127 dbClientSession* activeList;
00128 int optimalNumberOfThreads;
00129 int connectionQueueLen;
00130 int nActiveThreads;
00131 int nIdleThreads;
00132 int waitListLength;
00133 bool cancelWait;
00134 bool cancelAccept;
00135 bool cancelSession;
00136 dbMutex mutex;
00137 dbSemaphore go;
00138 dbSemaphore done;
00139 socket_t* globalAcceptSock;
00140 socket_t* localAcceptSock;
00141 dbThread localAcceptThread;
00142 dbThread globalAcceptThread;
00143 dbDatabase* db;
00144
00145 static void thread_proc serverThread(void* arg);
00146 static void thread_proc acceptLocalThread(void* arg);
00147 static void thread_proc acceptGlobalThread(void* arg);
00148
00149 void serveClient();
00150 void acceptConnection(socket_t* sock);
00151
00152 bool freeze(dbClientSession* session, int stmt_id);
00153 bool unfreeze(dbClientSession* session, int stmt_id);
00154 bool get_first(dbClientSession* session, int stmt_id);
00155 bool get_last(dbClientSession* session, int stmt_id);
00156 bool get_next(dbClientSession* session, int stmt_id);
00157 bool get_prev(dbClientSession* session, int stmt_id);
00158 bool seek(dbClientSession* session, int stmt_id, char* buf);
00159 bool skip(dbClientSession* session, int stmt_id, char* buf);
00160 bool fetch(dbClientSession* session, dbStatement* stmt, oid_t result);
00161 bool fetch(dbClientSession* session, dbStatement* stmt) {
00162 return fetch(session, stmt, stmt->cursor->currId);
00163 }
00164 bool insert_cpp(dbClientSession* session, char* data);
00165 bool update_cpp(dbClientSession* session, char* data);
00166 bool remove_cpp(dbClientSession* session, char* data);
00167 bool select_cpp(dbClientSession* session, char* data);
00168 bool reload_schema(dbClientSession* session, char* data);
00169 bool remove_cond(dbClientSession* session, char* data);
00170 int execute_query(char* data, dbQuery& q, dbAnyCursor& cursor);
00171
00172 bool remove(dbClientSession* session, int stmt_id);
00173 bool remove_current(dbClientSession* session, int stmt_id);
00174 bool update(dbClientSession* session, int stmt_id, char* new_data);
00175 bool insert(dbClientSession* session, int stmt_id, char* data, bool prepare);
00176 bool select(dbClientSession* session, int stmt_id, char* data, bool prepare);
00177 bool show_tables(dbClientSession* session);
00178 bool describe_table(dbClientSession* session, char* data);
00179 bool update_table(dbClientSession* session, char* data, bool create);
00180 bool drop_table(dbClientSession* session, char* data);
00181 bool alter_index(dbClientSession* session, char* data);
00182 bool authenticate(char* buf);
00183
00184 char* checkColumns(dbStatement* stmt, int n_columns,
00185 dbTableDescriptor* desc, char* data,
00186 int4& reponse, bool select);
00187
00188 dbStatement* findStatement(dbClientSession* stmt, int stmt_id);
00189
00190 public:
00191
00192 static dbServer* find(char_t const* serverURL);
00193 static void cleanup();
00194
00195 void stop();
00196 void start();
00197
00198 dbServer(dbDatabase* db,
00199 char_t const* serverURL,
00200 int optimalNumberOfThreads = 8,
00201 int connectionQueueLen = 64);
00202 ~dbServer();
00203 };
00204
00205 END_GIGABASE_NAMESPACE
00206
00207 #endif