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