00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __LOCALCLI_H__
00012 #define __LOCALCLI_H__
00013
00014 #include "fastdb.h"
00015 #include "compiler.h"
00016 #include "cli.h"
00017 #include "cliproto.h"
00018 #include "array.h"
00019
00020 BEGIN_FASTDB_NAMESPACE
00021
00022 inline int map_type(dbFieldDescriptor* fd) {
00023 return (fd->type < dbField::tpArray)
00024 ? ((fd->indexType & DB_TIMESTAMP) ? cli_datetime
00025 : ((fd->indexType & AUTOINCREMENT) ? cli_autoincrement : fd2cli_type_mapping[fd->type]))
00026 : ((fd->type == dbField::tpArray && fd->components->type < dbField::tpArray)
00027 ? cli_array_of_oid + fd2cli_type_mapping[fd->components->type]
00028 : ((fd->type == dbField::tpRectangle) ? cli_rectangle : cli_unknown));
00029 }
00030
00031
00032 struct parameter_binding {
00033 parameter_binding* next;
00034 char* name;
00035 int var_type;
00036 int var_len;
00037 void* var_ptr;
00038
00039 void reset() {}
00040 };
00041
00042 struct column_binding {
00043 column_binding* next;
00044 dbFieldDescriptor* field;
00045 char* name;
00046 int var_type;
00047 int* var_len;
00048 void* var_ptr;
00049 cli_column_get_ex get_fnc;
00050 cli_column_set_ex set_fnc;
00051 void* user_data;
00052
00053 void reset() {}
00054 };
00055
00056 struct session_desc;
00057
00058 struct statement_desc {
00059 int id;
00060 statement_desc* next;
00061 dbQuery query;
00062 dbAnyCursor cursor;
00063 dbTableDescriptor* table;
00064 column_binding* columns;
00065 parameter_binding* params;
00066 session_desc* session;
00067 bool first_fetch;
00068 bool for_update;
00069 bool prepared;
00070 bool updated;
00071 cli_oid_t oid;
00072 int n_params;
00073 int n_columns;
00074 int n_autoincremented_columns;
00075 int param_size;
00076 void* record_struct;
00077 dbSmallBuffer sql;
00078
00079 void reset()
00080 {
00081 query.reset();
00082 }
00083
00084 statement_desc(int id, statement_desc* next)
00085 {
00086 this->id = id;
00087 this->next = next;
00088 }
00089 statement_desc() {}
00090 };
00091
00092
00093 class sql_scanner {
00094 private:
00095 char* p;
00096 char* ident;
00097
00098 public:
00099 int get();
00100
00101 char* current_position() {
00102 return p;
00103 }
00104
00105 char* identifier() {
00106 return ident;
00107 }
00108
00109 sql_scanner(char* sql) {
00110 p = sql;
00111 }
00112 };
00113
00114 struct session_desc {
00115 int id;
00116 char* name;
00117 session_desc* next;
00118 statement_desc* stmts;
00119 dbDatabase* db;
00120 dbMutex mutex;
00121 dbTableDescriptor* dropped_tables;
00122 dbTableDescriptor* existed_tables;
00123
00124 void reset() {}
00125
00126 session_desc(int id, session_desc* next) {
00127 this->id = id;
00128 this->next = next;
00129 }
00130 session_desc() {}
00131 };
00132
00133 template<class T>
00134 class fixed_size_object_allocator {
00135 protected:
00136 T* free_chain;
00137 dbMutex mutex;
00138
00139 public:
00140 T* allocate() {
00141 dbCriticalSection cs(mutex);
00142 T* obj = free_chain;
00143 if (obj == NULL) {
00144 obj = new T();
00145 } else {
00146 free_chain = obj->next;
00147 }
00148 return obj;
00149 }
00150
00151 void free(T* desc) {
00152 dbCriticalSection cs(mutex);
00153 desc->next = free_chain;
00154 free_chain = desc;
00155 desc->reset();
00156 }
00157
00158 fixed_size_object_allocator() {
00159 free_chain = NULL;
00160 }
00161
00162 ~fixed_size_object_allocator() {
00163 T *obj, *next;
00164 for (obj = free_chain; obj != NULL; obj = next) {
00165 next = obj->next;
00166 delete obj;
00167 }
00168 }
00169 };
00170
00171 template<class T>
00172 class descriptor_table : public fixed_size_object_allocator<T> {
00173 protected:
00174 T** table;
00175 int descriptor_table_size;
00176
00177 public:
00178 descriptor_table() {
00179 int i;
00180 descriptor_table_size = 16;
00181 table = new T*[descriptor_table_size];
00182 T* next = NULL;
00183 for (i = 0; i < descriptor_table_size; i++) {
00184 table[i] = next = new T(i, next);
00185 }
00186 this->free_chain = next;
00187 }
00188
00189 ~descriptor_table() {
00190 delete[] table;
00191 }
00192
00193 T* get(int desc) {
00194 dbCriticalSection cs(this->mutex);
00195 return (desc >= descriptor_table_size) ? (T*)0 : table[desc];
00196 }
00197
00198 T* allocate() {
00199 dbCriticalSection cs(this->mutex);
00200 if (this->free_chain == NULL) {
00201 int i, n;
00202 T** desc = new T*[descriptor_table_size * 2];
00203 memcpy(desc, table, descriptor_table_size*sizeof(T*));
00204 delete[] table;
00205 table = desc;
00206 T* next = NULL;
00207 for (i = descriptor_table_size, n = i*2; i < n; i++) {
00208 table[i] = next = new T(i, next);
00209 }
00210 this->free_chain = next;
00211 descriptor_table_size = n;
00212 }
00213 T* desc = this->free_chain;
00214 this->free_chain = desc->next;
00215 return desc;
00216 }
00217 };
00218
00219 class FASTDB_DLL_ENTRY dbCLI {
00220 private:
00221 fixed_size_object_allocator<column_binding> column_allocator;
00222 fixed_size_object_allocator<parameter_binding> parameter_allocator;
00223
00224 descriptor_table<session_desc> sessions;
00225 descriptor_table<statement_desc> statements;
00226
00227 session_desc* active_session_list;
00228
00229 dbMutex sessionMutex;
00230
00231 static int calculate_varying_length(char const* tableName, int& nFields, cli_field_descriptor* columns);
00232 static dbTableDescriptor* create_table_descriptor(dbDatabase* db,
00233 oid_t oid,
00234 dbTable* table,
00235 char const* tableName,
00236 int nFields,
00237 int nColumns,
00238 cli_field_descriptor* columns);
00239
00240 public:
00241 static dbCLI instance;
00242
00243 dbCLI() {
00244 active_session_list = NULL;
00245 }
00246
00247 int create_session(char const* databasePath,
00248 char const* filePath,
00249 unsigned transactionCommitDelay,
00250 int openAttr,
00251 size_t initDatabaseSize,
00252 size_t extensionQuantum,
00253 size_t initIndexSize,
00254 size_t fileSizeLimit);
00255
00256
00257 int create_replication_node(int nodeId,
00258 int nServers,
00259 char* nodeNames[],
00260 char const* databaseName,
00261 char const* filePath,
00262 int openAttr,
00263 size_t initDatabaseSize,
00264 size_t extensionQuantum,
00265 size_t initIndexSize,
00266 size_t fileSizeLimit);
00267
00268 int create_statement(int session, char const* sql);
00269
00270 int bind_parameter(int statement,
00271 char const* param_name,
00272 int var_type,
00273 void* var_ptr);
00274
00275 int bind_column(int statement,
00276 char const* column_name,
00277 int var_type,
00278 int* var_len,
00279 void* var_ptr);
00280
00281 int bind_array_column(int statement,
00282 char const* column_name,
00283 int var_type,
00284 void* var_ptr,
00285 cli_column_set_ex set,
00286 cli_column_get_ex get,
00287 void* user_data);
00288
00289 int fetch(int statement, int for_update);
00290
00291 int fetch_columns(statement_desc* stmt);
00292 int store_columns(char* buf, statement_desc* stmt, bool insert);
00293
00294 int insert(int statement, cli_oid_t* oid);
00295 int update(int statement);
00296
00297 int close_cursor(int statement);
00298
00299 int freeze(int statement);
00300 int unfreeze(int statement);
00301
00302 int get_first(int statement);
00303 int get_last(int statement);
00304 int get_next(int statement);
00305 int get_prev(int statement);
00306 int skip(int statement, int n);
00307 int seek(int statement, cli_oid_t oid);
00308
00309 cli_oid_t get_current_oid(int statement);
00310 int free_statement(int statement);
00311 int free_statement(statement_desc* stmt);
00312 int release_statement(statement_desc* stmt);
00313
00314 int commit(int session);
00315 int precommit(int session);
00316 int abort(int session);
00317
00318 int remove(int statement);
00319 int remove_current(int statement);
00320
00321 int describe(int session, char const* table, cli_field_descriptor** fields);
00322 int describe_layout(int session, char const* table, cli_field_layout** fields, int* rec_size);
00323 int show_tables(int session, cli_table_descriptor** tables);
00324
00325 int match_columns(char const* table_name, statement_desc* stmt);
00326
00327 int create_table(int session, char const* tableName, int nColumns,
00328 cli_field_descriptor* columns);
00329 int alter_table(int session, char const* tableName, int nColumns,
00330 cli_field_descriptor* columns);
00331
00332 int drop_table(int session, char const* tableName);
00333
00334 int alter_index(int session, char const* tableName, char const* fieldName, int newFlags);
00335
00336 cli_error_handler set_error_handler(int session, cli_error_handler new_handler, void* context);
00337
00338 int attach(int session);
00339 int detach(int session, int detach_mode);
00340
00341 int get_database_state(int session, cli_database_monitor* monitor);
00342
00343 int close(int session);
00344
00345 int prepare_query(int session, char const* query);
00346 int execute_query(int statement, int for_update, void* record_struct, va_list params);
00347 int execute_query(int statement, int for_update, void* record_struct, int n_params, int* param_types, void** param_values);
00348 int insert_struct(int session, char const* table_name, void* record_struct, cli_oid_t* oid);
00349
00350 int join_transaction(int session, cli_transaction_context_t ctx);
00351
00352 static int create_table(dbDatabase* db, char const* tableName, int nColumns,
00353 cli_field_descriptor* columns);
00354
00355 static int alter_table(dbDatabase* db, char const* tableName, int nColumns,
00356 cli_field_descriptor* columns);
00357
00358 static int alter_index(dbDatabase* db, char const* tableName, char const* fieldName, int newFlags);
00359 };
00360
00361 END_FASTDB_NAMESPACE
00362
00363 #endif