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 class dbColumnBinding {
00017 public:
00018 dbColumnBinding* next;
00019 dbFieldDescriptor* fd;
00020 int cliType;
00021 int len;
00022 char* ptr;
00023
00024 int unpackArray(char* dst, size_t offs);
00025 void unpackScalar(char* dst);
00026
00027 dbColumnBinding(dbFieldDescriptor* field, int type) {
00028 fd = field;
00029 cliType = type;
00030 next = NULL;
00031 }
00032 };
00033
00034 struct dbParameterBinding {
00035 union {
00036 int1 i1;
00037 int2 i2;
00038 int4 i4;
00039 db_int8 i8;
00040 real4 r4;
00041 real8 r8;
00042 oid_t oid;
00043 bool b;
00044 char* str;
00045 } u;
00046 int type;
00047 };
00048
00049 const int dbQueryMaxIdLength = 256;
00050
00051 class dbQueryScanner {
00052 public:
00053 char* p;
00054 db_int8 ival;
00055 real8 fval;
00056 char buf[dbQueryMaxIdLength];
00057 char* ident;
00058
00059 int get();
00060
00061 void reset(char* stmt) {
00062 p = stmt;
00063 }
00064 };
00065
00066 class dbStatement {
00067 public:
00068 int id;
00069 bool firstFetch;
00070 dbStatement* next;
00071 dbAnyCursor* cursor;
00072 dbQuery query;
00073 dbColumnBinding* columns;
00074 char* buf;
00075 int buf_size;
00076 int n_params;
00077 int n_columns;
00078 dbParameterBinding* params;
00079 dbTableDescriptor* table;
00080
00081 void reset();
00082
00083 dbStatement(int stmt_id) {
00084 id = stmt_id;
00085 columns = NULL;
00086 params = NULL;
00087 buf = NULL;
00088 buf_size = 0;
00089 table = NULL;
00090 cursor = NULL;
00091 }
00092 ~dbStatement() {
00093 reset();
00094 delete[] buf;
00095 }
00096 };
00097
00098 class dbSession {
00099 public:
00100 dbSession* next;
00101 dbStatement* stmts;
00102 dbQueryScanner scanner;
00103 socket_t* sock;
00104 bool in_transaction;
00105 };
00106
00107 class dbServer {
00108 protected:
00109 static dbServer* chain;
00110 dbServer* next;
00111 char* URL;
00112 dbSession* freeList;
00113 dbSession* waitList;
00114 dbSession* activeList;
00115 int optimalNumberOfThreads;
00116 int nActiveThreads;
00117 int nIdleThreads;
00118 bool cancelWait;
00119 bool cancelAccept;
00120 bool cancelSession;
00121 dbMutex mutex;
00122 dbLocalSemaphore go;
00123 dbLocalSemaphore done;
00124 socket_t* globalAcceptSock;
00125 socket_t* localAcceptSock;
00126 dbThread localAcceptThread;
00127 dbThread globalAcceptThread;
00128 dbDatabase* db;
00129
00130 static void thread_proc serverThread(void* arg);
00131 static void thread_proc acceptLocalThread(void* arg);
00132 static void thread_proc acceptGlobalThread(void* arg);
00133
00134 void serveClient();
00135 void acceptConnection(socket_t* sock);
00136
00137 bool get_first(dbSession* session, int stmt_id);
00138 bool get_last(dbSession* session, int stmt_id);
00139 bool get_next(dbSession* session, int stmt_id);
00140 bool get_prev(dbSession* session, int stmt_id);
00141 bool fetch(dbSession* session, dbStatement* stmt);
00142 bool remove(dbSession* session, int stmt_id);
00143 bool update(dbSession* session, int stmt_id, char* new_data);
00144 bool insert(dbSession* session, int stmt_id, char* data, bool prepare);
00145 bool select(dbSession* session, int stmt_id, char* data, bool prepare);
00146 bool show_tables(dbSession* session);
00147 bool describe_table(dbSession* session, char const* table);
00148
00149 char* checkColumns(dbStatement* stmt, int n_columns,
00150 dbTableDescriptor* desc, char* data,
00151 int4& reponse);
00152
00153 dbStatement* findStatement(dbSession* stmt, int stmt_id);
00154
00155 public:
00156 static dbServer* find(char const* serverURL);
00157 static void cleanup();
00158
00159 void stop();
00160 void start();
00161
00162 dbServer(dbDatabase* db,
00163 char const* serverURL,
00164 int optimalNumberOfThreads = 8,
00165 int connectionQueueLen = 64);
00166 ~dbServer();
00167 };
00168
00169 #endif