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