00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __LOCALCLI_H__
00012 #define __LOCALCLI_H__
00013
00014 #include "gigabase.h"
00015 #include "compiler.h"
00016 #include "cli.h"
00017 #include "cliproto.h"
00018 #include "array.h"
00019
00020 BEGIN_GIGABASE_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 : gb2cli_type_mapping[fd->type]))
00026 : ((fd->type == dbField::tpArray && fd->components->type < dbField::tpArray)
00027 ? cli_array_of_oid + gb2cli_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_t* 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_t* 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 cursor_type;
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<char_t> 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
00090 statement_desc() {}
00091 };
00092
00093
00094 class sql_scanner {
00095 private:
00096 char_t* p;
00097 char_t* ident;
00098
00099 public:
00100 int get();
00101
00102 char_t* current_position() {
00103 return p;
00104 }
00105
00106 char_t* identifier() {
00107 return ident;
00108 }
00109
00110 sql_scanner(char_t* sql) {
00111 p = sql;
00112 }
00113 };
00114
00115 struct session_desc {
00116 int id;
00117 char_t* 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 session_desc(int id, session_desc* next) {
00126 this->id = id;
00127 this->next = next;
00128 }
00129
00130 void reset() {}
00131
00132 session_desc() {}
00133 };
00134
00135 template<class T>
00136 class fixed_size_object_allocator {
00137 protected:
00138 T* free_chain;
00139 dbMutex mutex;
00140 int n_objects;
00141
00142 public:
00143 bool is_empty() {
00144 return n_objects == 0;
00145 }
00146
00147 T* allocate() {
00148 dbCriticalSection cs(mutex);
00149 T* obj = free_chain;
00150 if (obj == NULL) {
00151 obj = new T();
00152 } else {
00153 free_chain = obj->next;
00154 }
00155 n_objects += 1;
00156 return obj;
00157 }
00158
00159 void free(T* desc) {
00160 dbCriticalSection cs(mutex);
00161 desc->next = free_chain;
00162 free_chain = desc;
00163 desc->reset();
00164 n_objects -= 1;
00165 }
00166
00167 fixed_size_object_allocator() {
00168 free_chain = NULL;
00169 }
00170
00171 ~fixed_size_object_allocator() {
00172 T *obj, *next;
00173 for (obj = free_chain; obj != NULL; obj = next) {
00174 next = obj->next;
00175 delete obj;
00176 }
00177 }
00178 };
00179
00180 template<class T>
00181 class descriptor_table : public fixed_size_object_allocator<T> {
00182 protected:
00183 T** table;
00184 int descriptor_table_size;
00185
00186 public:
00187 descriptor_table() {
00188 int i;
00189 descriptor_table_size = 16;
00190 table = new T*[descriptor_table_size];
00191 T* next = NULL;
00192 for (i = 0; i < descriptor_table_size; i++) {
00193 table[i] = next = new T(i, next);
00194 }
00195 this->free_chain = next;
00196 }
00197
00198 ~descriptor_table() {
00199 delete[] table;
00200 }
00201
00202 T* get(int desc) {
00203 dbCriticalSection cs(this->mutex);
00204 return (desc >= descriptor_table_size) ? (T*)0 : table[desc];
00205 }
00206
00207 T* allocate() {
00208 dbCriticalSection cs(this->mutex);
00209 if (this->free_chain == NULL) {
00210 int i, n;
00211 T** desc = new T*[descriptor_table_size * 2];
00212 memcpy(desc, table, descriptor_table_size*sizeof(T*));
00213 delete[] table;
00214 table = desc;
00215 T* next = NULL;
00216 for (i = descriptor_table_size, n = i*2; i < n; i++) {
00217 table[i] = next = new T(i, next);
00218 }
00219 this->free_chain = next;
00220 descriptor_table_size = n;
00221 }
00222 T* desc = this->free_chain;
00223 this->free_chain = desc->next;
00224 return desc;
00225 }
00226 };
00227
00228 class GIGABASE_DLL_ENTRY dbCLI {
00229 private:
00230 fixed_size_object_allocator<column_binding> column_allocator;
00231 fixed_size_object_allocator<parameter_binding> parameter_allocator;
00232
00233 descriptor_table<session_desc> sessions;
00234 descriptor_table<statement_desc> statements;
00235
00236 session_desc* active_session_list;
00237
00238 dbMutex sessionMutex;
00239
00240 static int calculate_varying_length(char_t const* tableName, int& nFields, cli_field_descriptor* columns);
00241 static dbTableDescriptor* create_table_descriptor(dbDatabase* db,
00242 dbTable* table, char_t const* tableName,
00243 int nFields, int nColumns,
00244 cli_field_descriptor* columns);
00245
00246 public:
00247 static dbCLI instance;
00248
00249 dbCLI() {
00250 active_session_list = NULL;
00251 }
00252
00253 int xml_export(int session, FILE* out, char_t const* const* tables, int n_tables, cli_export_method method);
00254 int xml_import(int session, FILE* in);
00255
00256 int create_session(char_t const* databasePath,
00257 time_t transactionCommitDelay,
00258 int openAttr,
00259 size_t poolSize,
00260 char const* password);
00261
00262 int create_statement(int session, char_t const* sql);
00263 int bind_parameter(int statement,
00264 char_t const* param_name,
00265 int var_type,
00266 void* var_ptr);
00267 int bind_column(int statement,
00268 char_t const* column_name,
00269 int var_type,
00270 int* var_len,
00271 void* var_ptr);
00272
00273 int bind_array_column(int statement,
00274 char_t const* column_name,
00275 int var_type,
00276 void* var_ptr,
00277 cli_column_set_ex set,
00278 cli_column_get_ex get,
00279 void* user_data);
00280
00281 int fetch(int statement, int cursor_type);
00282
00283 int fetch_columns(statement_desc* stmt);
00284 int store_columns(char* buf, statement_desc* stmt, bool insert);
00285
00286 int insert(int statement, cli_oid_t* oid, bool batch);
00287 int update(int statement);
00288
00289 int close_cursor(int statement);
00290
00291 int freeze(int statement);
00292 int unfreeze(int statement);
00293
00294 int get_first(int statement);
00295 int get_last(int statement);
00296 int get_next(int statement);
00297 int get_prev(int statement);
00298
00299 int skip(int statement, int n);
00300 int seek(int statement, cli_oid_t oid);
00301
00302 cli_oid_t get_current_oid(int statement);
00303 int free_statement(int statement);
00304 int free_statement(statement_desc* stmt);
00305 int release_statement(statement_desc* stmt);
00306
00307 int commit(int statement);
00308 int precommit(int statement);
00309 int abort(int statement);
00310 int remove(int statement);
00311 int remove_current(int statement);
00312 int lock(int statement);
00313
00314 int describe(int session, char_t const* table, cli_field_descriptor** fields);
00315 int describe_layout(int session, char_t const* table, cli_field_layout** fields, int* rec_size);
00316 int show_tables(int session, cli_table_descriptor** tables);
00317
00318 int match_columns(char_t const* table_name, statement_desc* stmt);
00319
00320 int exec_batch(int session);
00321
00322 int create_table(int session, char_t const* tableName, int nColumns,
00323 cli_field_descriptor* columns);
00324
00325 int alter_table(int session, char_t const* tableName, int nColumns,
00326 cli_field_descriptor* columns);
00327
00328 int drop_table(int session, char_t const* tableName);
00329
00330 int alter_index(int session, char_t const* tableName, char_t const* fieldName, int newFlags);
00331
00332 cli_error_handler set_error_handler(int session, cli_error_handler new_handler, void* context);
00333
00334 int attach(int session);
00335 int detach(int session, int detach_mode);
00336
00337 int close(int session);
00338
00339 int prepare_query(int session, char_t const* query);
00340 int execute_query(int statement, int cursor_type, void* record_struct, va_list params);
00341 int execute_query(int statement, int cursor_type, void* record_struct, int n_params, int* param_types, void** param_values);
00342 int insert_struct(int session, char_t const* table_name, void* record_struct, cli_oid_t* oid);
00343
00344 int join_transaction(int session, cli_transaction_context_t ctx);
00345
00346 int backup(int session, char_t const* file_name, int compactify);
00347 int schedule_backup(int session, char_t const* file_name, int period);
00348 int get_database_size(int session, cli_nat8_t* size);
00349
00350 static int create_table(dbDatabase* db, char_t const* tableName, int nColumns,
00351 cli_field_descriptor* columns);
00352
00353 static int alter_table(dbDatabase* db, char_t const* tableName, int nColumns,
00354 cli_field_descriptor* columns);
00355
00356 static int alter_index(dbDatabase* db, char_t const* tableName, char_t const* fieldName, int newFlags);
00357
00358 };
00359
00360 END_GIGABASE_NAMESPACE
00361
00362 #endif