1 //-< SERVER.CPP >----------------------------------------------------*--------*
2 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
3 // (Main Memory Database Management System)                          *   /\|  *
4 //                                                                   *  /  \  *
5 //                          Created:     13-Jan-2000  K.A. Knizhnik  * / [] \ *
6 //                          Last update: 13-Jan-2000  K.A. Knizhnik  * GARRET *
7 //-------------------------------------------------------------------*--------*
8 // CLI multithreaded server class
9 //-------------------------------------------------------------------*--------*
10 
11 #ifndef __SERVER_H__
12 #define __SERVER_H__
13 
14 #include "sockio.h"
15 
16 BEGIN_FASTDB_NAMESPACE
17 
18 class dbColumnBinding {
19   public:
20     dbColumnBinding*   next;
21     dbFieldDescriptor* fd;
22     int                cliType;
23     int                len;
24     char*              ptr;
25 
26     int  unpackArray(char* dst, size_t& offs);
27     void unpackScalar(char* dst, bool insert);
28 
dbColumnBinding(dbFieldDescriptor * field,int type)29     dbColumnBinding(dbFieldDescriptor* field, int type) {
30         fd = field;
31         cliType = type;
32         next = NULL;
33     }
34 };
35 
36 struct dbParameterBinding {
37     union {
38         int1       i1;
39         int2       i2;
40         int4       i4;
41         db_int8    i8;
42         real4      r4;
43         real8      r8;
44         oid_t      oid;
45         bool       b;
46         char*      str;
47         rectangle  rect;
48     } u;
49     int type;
50 };
51 
52 const int dbQueryMaxIdLength = 256;
53 
54 class dbQueryScanner {
55   public:
56     char*    p;
57     db_int8     ival;
58     real8    fval;
59     char     buf[dbQueryMaxIdLength];
60     char*    ident;
61 
62     int  get();
63 
reset(char * stmt)64     void reset(char* stmt) {
65         p = stmt;
66     }
67 };
68 
69 class dbStatement {
70   public:
71     int                 id;
72     bool                firstFetch;
73     dbStatement*        next;
74     dbAnyCursor*        cursor;
75     dbQuery             query;
76     dbColumnBinding*    columns;
77     char*               buf;
78     int                 buf_size;
79     int                 n_params;
80     int                 n_columns;
81     dbParameterBinding* params;
82     dbTableDescriptor*  table;
83 
84     void reset();
85 
dbStatement(int stmt_id)86     dbStatement(int stmt_id) {
87         id = stmt_id;
88         columns = NULL;
89         params = NULL;
90         buf = NULL;
91         buf_size = 0;
92         table = NULL;
93         cursor = NULL;
94     }
~dbStatement()95     ~dbStatement() {
96         reset();
97         delete[] buf;
98     }
99 };
100 
101 class dbSession {
102   public:
103     dbSession*         next;
104     dbStatement*       stmts;
105     dbQueryScanner     scanner;
106     socket_t*          sock;
107     bool               in_transaction;
108     dbTableDescriptor* dropped_tables;
109     dbTableDescriptor* existed_tables;
110 };
111 
112 class FASTDB_DLL_ENTRY dbServer {
113   protected:
114     static dbServer* chain;
115     dbServer*        next;
116     char*            URL;
117     dbSession*       freeList;
118     dbSession*       waitList;
119     dbSession*       activeList;
120     int              optimalNumberOfThreads;
121     int              nActiveThreads;
122     int              nIdleThreads;
123     int              waitListLength;
124     bool             cancelWait;
125     bool             cancelAccept;
126     bool             cancelSession;
127     dbMutex          mutex;
128     dbLocalSemaphore go;
129     dbLocalSemaphore done;
130     socket_t*        globalAcceptSock;
131     socket_t*        localAcceptSock;
132     dbThread         localAcceptThread;
133     dbThread         globalAcceptThread;
134     dbDatabase*      db;
135 
136     static void thread_proc serverThread(void* arg);
137     static void thread_proc acceptLocalThread(void* arg);
138     static void thread_proc acceptGlobalThread(void* arg);
139 
140     void serveClient();
141     void acceptConnection(socket_t* sock);
142 
143 
144     bool freeze(dbSession* session, int stmt_id);
145     bool unfreeze(dbSession* session, int stmt_id);
146     bool get_first(dbSession* session, int stmt_id);
147     bool get_last(dbSession* session, int stmt_id);
148     bool get_next(dbSession* session, int stmt_id);
149     bool get_prev(dbSession* session, int stmt_id);
150     bool seek(dbSession* session, int stmt_id, char* buf);
151     bool skip(dbSession* session, int stmt_id, char* buf);
152     bool fetch(dbSession* session, dbStatement* stmt, oid_t result);
fetch(dbSession * session,dbStatement * stmt)153     bool fetch(dbSession* session, dbStatement* stmt) {
154         return fetch(session, stmt, stmt->cursor->currId);
155     }
156     bool remove(dbSession* session, int stmt_id);
157     bool remove_current(dbSession* session, int stmt_id);
158     bool update(dbSession* session, int stmt_id, char* new_data);
159     bool insert(dbSession* session, int stmt_id, char* data, bool prepare);
160     bool select(dbSession* session, int stmt_id, char* data, bool prepare);
161     bool show_tables(dbSession* session);
162     bool describe_table(dbSession* session, char const* table);
163     bool create_table(dbSession* session, char* data, bool create);
164     bool drop_table(dbSession* session, char* data);
165     bool alter_index(dbSession* session, char* data);
166 
167     char* checkColumns(dbStatement* stmt, int n_columns,
168                        dbTableDescriptor* desc, char* data,
169                        int4& reponse, bool select);
170 
171     dbStatement* findStatement(dbSession* stmt, int stmt_id);
172 
173   public:
174     static dbServer* find(char const* serverURL);
175     static void      cleanup();
176 
177     void stop();
178     void start();
179 
180     dbServer(dbDatabase* db,
181              char const* serverURL,
182              int optimalNumberOfThreads = 8,
183              int connectionQueueLen = 64);
184     ~dbServer();
185 };
186 
187 END_FASTDB_NAMESPACE
188 
189 #endif
190