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_FASTDB_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);
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* 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 buf[dbQueryMaxIdLength];
00060 char* ident;
00061
00062 int get();
00063
00064 void reset(char* stmt) {
00065 p = stmt;
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 class dbSession {
00102 public:
00103 dbSession* next;
00104 dbStatement* stmts;
00105 dbQueryScanner scanner;
00106 socket_t* sock;
00107 bool in_transaction;
00108 dbTableDescriptor* dropped_tables;
00109 dbTableDescriptor* existed_tables;
00110 };
00111
00112 class dbServer {
00113 protected:
00114 static dbServer* chain;
00115 dbServer* next;
00116 char* URL;
00117 dbSession* freeList;
00118 dbSession* waitList;
00119 dbSession* activeList;
00120 int optimalNumberOfThreads;
00121 int nActiveThreads;
00122 int nIdleThreads;
00123 int waitListLength;
00124 bool cancelWait;
00125 bool cancelAccept;
00126 bool cancelSession;
00127 dbMutex mutex;
00128 dbLocalSemaphore go;
00129 dbLocalSemaphore done;
00130 socket_t* globalAcceptSock;
00131 socket_t* localAcceptSock;
00132 dbThread localAcceptThread;
00133 dbThread globalAcceptThread;
00134 dbDatabase* db;
00135
00136 static void thread_proc serverThread(void* arg);
00137 static void thread_proc acceptLocalThread(void* arg);
00138 static void thread_proc acceptGlobalThread(void* arg);
00139
00140 void serveClient();
00141 void acceptConnection(socket_t* sock);
00142
00143
00144 bool freeze(dbSession* session, int stmt_id);
00145 bool unfreeze(dbSession* session, int stmt_id);
00146 bool get_first(dbSession* session, int stmt_id);
00147 bool get_last(dbSession* session, int stmt_id);
00148 bool get_next(dbSession* session, int stmt_id);
00149 bool get_prev(dbSession* session, int stmt_id);
00150 bool seek(dbSession* session, int stmt_id, char* buf);
00151 bool skip(dbSession* session, int stmt_id, char* buf);
00152 bool fetch(dbSession* session, dbStatement* stmt, oid_t result);
00153 bool fetch(dbSession* session, dbStatement* stmt) {
00154 return fetch(session, stmt, stmt->cursor->currId);
00155 }
00156 bool remove(dbSession* session, int stmt_id);
00157 bool remove_current(dbSession* session, int stmt_id);
00158 bool update(dbSession* session, int stmt_id, char* new_data);
00159 bool insert(dbSession* session, int stmt_id, char* data, bool prepare);
00160 bool select(dbSession* session, int stmt_id, char* data, bool prepare);
00161 bool show_tables(dbSession* session);
00162 bool describe_table(dbSession* session, char const* table);
00163 bool create_table(dbSession* session, char* data, bool create);
00164 bool drop_table(dbSession* session, char* data);
00165 bool alter_index(dbSession* session, char* data);
00166
00167 char* checkColumns(dbStatement* stmt, int n_columns,
00168 dbTableDescriptor* desc, char* data,
00169 int4& reponse);
00170
00171 dbStatement* findStatement(dbSession* stmt, int stmt_id);
00172
00173 public:
00174 static dbServer* find(char const* serverURL);
00175 static void cleanup();
00176
00177 void stop();
00178 void start();
00179
00180 dbServer(dbDatabase* db,
00181 char const* serverURL,
00182 int optimalNumberOfThreads = 8,
00183 int connectionQueueLen = 64);
00184 ~dbServer();
00185 };
00186
00187 END_FASTDB_NAMESPACE
00188
00189 #endif