00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "fastdb.h"
00012 #include "compiler.h"
00013 #include "cli.h"
00014 #include "cliproto.h"
00015 #include "array.h"
00016
00017 inline int map_type(dbFieldDescriptor* fd) {
00018 return (fd->type < dbField::tpArray)
00019 ? fd2cli_type_mapping[fd->type]
00020 : (fd->type == dbField::tpArray && fd->components->type < dbField::tpArray)
00021 ? cli_array_of_oid + fd2cli_type_mapping[fd->components->type]
00022 : cli_unknown;
00023 }
00024
00025
00026 struct parameter_binding {
00027 parameter_binding* next;
00028 char* name;
00029 int var_type;
00030 int var_len;
00031 void* var_ptr;
00032 };
00033
00034 struct column_binding {
00035 column_binding* next;
00036 dbFieldDescriptor* field;
00037 char* name;
00038 int var_type;
00039 int* var_len;
00040 void* var_ptr;
00041 cli_column_get_ex get_fnc;
00042 cli_column_set_ex set_fnc;
00043 };
00044
00045 struct session_desc;
00046
00047 struct statement_desc {
00048 int id;
00049 char* sql;
00050 statement_desc* next;
00051 dbQuery query;
00052 dbAnyCursor cursor;
00053 dbTableDescriptor* table;
00054 column_binding* columns;
00055 parameter_binding* params;
00056 session_desc* session;
00057 bool first_fetch;
00058 bool for_update;
00059 bool prepared;
00060 bool updated;
00061 cli_oid_t oid;
00062 int n_params;
00063 int n_columns;
00064 int n_autoincremented_columns;
00065
00066 statement_desc(int id, statement_desc* next)
00067 {
00068 this->id = id;
00069 this->next = next;
00070 }
00071 };
00072
00073
00074 class sql_scanner {
00075 private:
00076 char* p;
00077 char* ident;
00078
00079 public:
00080 int get();
00081
00082 char* current_position() {
00083 return p;
00084 }
00085
00086 char* identifier() {
00087 return ident;
00088 }
00089
00090 sql_scanner(char* sql) {
00091 p = sql;
00092 }
00093 };
00094
00095 struct session_desc {
00096 int id;
00097 char* name;
00098 session_desc* next;
00099 statement_desc* stmts;
00100 dbDatabase* db;
00101 dbTableDescriptor* dropped_tables;
00102 dbTableDescriptor* existed_tables;
00103
00104 session_desc(int id, session_desc* next) {
00105 this->id = id;
00106 this->next = next;
00107 }
00108 };
00109
00110 template<class T>
00111 class fixed_size_object_allocator {
00112 protected:
00113 T* free_chain;
00114 dbMutex mutex;
00115
00116 public:
00117 T* allocate() {
00118 dbCriticalSection cs(mutex);
00119 T* obj = free_chain;
00120 if (obj == NULL) {
00121 obj = new T();
00122 } else {
00123 free_chain = obj->next;
00124 }
00125 return obj;
00126 }
00127
00128 void free(T* desc) {
00129 dbCriticalSection cs(mutex);
00130 desc->next = free_chain;
00131 free_chain = desc;
00132 }
00133
00134 fixed_size_object_allocator() {
00135 free_chain = NULL;
00136 }
00137
00138 ~fixed_size_object_allocator() {
00139 T *obj, *next;
00140 for (obj = free_chain; obj != NULL; obj = next) {
00141 next = obj->next;
00142 delete obj;
00143 }
00144 }
00145 };
00146
00147 template<class T>
00148 class descriptor_table : public fixed_size_object_allocator<T> {
00149 protected:
00150 T** table;
00151 int descriptor_table_size;
00152
00153 public:
00154 descriptor_table() {
00155 int i;
00156 descriptor_table_size = 16;
00157 table = new T*[descriptor_table_size];
00158 T* next = NULL;
00159 for (i = 0; i < descriptor_table_size; i++) {
00160 table[i] = next = new T(i, next);
00161 }
00162 free_chain = next;
00163 }
00164
00165 ~descriptor_table() {
00166 delete[] table;
00167 }
00168
00169 T* get(int desc) {
00170 dbCriticalSection cs(mutex);
00171 return (desc >= descriptor_table_size) ? (T*)0 : table[desc];
00172 }
00173
00174 T* allocate() {
00175 dbCriticalSection cs(mutex);
00176 if (free_chain == NULL) {
00177 int i, n;
00178 T** desc = new T*[descriptor_table_size * 2];
00179 memcpy(desc, table, descriptor_table_size*sizeof(T*));
00180 delete[] table;
00181 table = desc;
00182 T* next = NULL;
00183 for (i = descriptor_table_size, n = i*2; i < n; i++) {
00184 table[i] = next = new T(i, next);
00185 }
00186 free_chain = next;
00187 descriptor_table_size = n;
00188 }
00189 T* desc = free_chain;
00190 free_chain = desc->next;
00191 return desc;
00192 }
00193 };
00194
00195 class FASTDB_DLL_ENTRY dbCLI {
00196 private:
00197 fixed_size_object_allocator<column_binding> column_allocator;
00198 fixed_size_object_allocator<parameter_binding> parameter_allocator;
00199
00200 descriptor_table<session_desc> sessions;
00201 descriptor_table<statement_desc> statements;
00202
00203 session_desc* active_session_list;
00204
00205 dbMutex sessionMutex;
00206
00207 public:
00208 static dbCLI instance;
00209
00210 dbCLI() {
00211 active_session_list = NULL;
00212 }
00213
00214 int create_session(char const* databasePath,
00215 char const* filePath,
00216 unsigned transactionCommitDelay,
00217 int openAttr,
00218 size_t initDatabaseSize);
00219
00220 int create_statement(int session, char const* sql);
00221
00222 int bind_parameter(int statement,
00223 char const* param_name,
00224 int var_type,
00225 void* var_ptr);
00226
00227 int bind_column(int statement,
00228 char const* column_name,
00229 int var_type,
00230 int* var_len,
00231 void* var_ptr);
00232
00233 int bind_array_column(int statement,
00234 char const* column_name,
00235 int var_type,
00236 void* var_ptr,
00237 cli_column_set_ex set,
00238 cli_column_get_ex get);
00239
00240 int fetch(int statement, int for_update);
00241
00242 int fetch_columns(statement_desc* stmt);
00243 int store_columns(char* buf, statement_desc* stmt);
00244
00245 int insert(int statement, cli_oid_t* oid);
00246 int update(int statement);
00247
00248 int get_first(int statement);
00249 int get_last(int statement);
00250 int get_next(int statement);
00251 int get_prev(int statement);
00252
00253 cli_oid_t get_current_oid(int statement);
00254 int free_statement(int statement);
00255 int free_statement(statement_desc* stmt);
00256
00257 int commit(int session);
00258 int precommit(int session);
00259 int abort(int session);
00260
00261 int remove(int statement);
00262
00263 int describe(int session, char const* table, cli_field_descriptor** fields);
00264 int show_tables(int session, cli_table_descriptor** tables);
00265
00266 int match_columns(char const* table_name, statement_desc* stmt);
00267
00268 int create_table(int session, char const* tableName, int nColumns,
00269 cli_field_descriptor* columns);
00270
00271 int drop_table(int session, char const* tableName);
00272
00273 int alter_index(int session, char const* tableName, char const* fieldName, int newFlags);
00274
00275 cli_error_handler set_error_handler(int session, cli_error_handler new_handler);
00276
00277 int close(int session);
00278 };