Functions | |
INT | db_open_database (const char *xdatabase_name, INT database_size, HNDLE *hDB, const char *client_name) |
INT | db_close_database (HNDLE hDB) |
INT | db_lock_database (HNDLE hDB) |
INT | db_unlock_database (HNDLE hDB) |
INT | db_get_lock_cnt (HNDLE hDB) |
INT | db_protect_database (HNDLE hDB) |
const char * | extract_key (const char *key_list, char *key_name, int key_name_length) |
BOOL | equal_ustring (const char *str1, const char *str2) |
INT | db_create_key (HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type) |
INT | db_create_link (HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination) |
INT | db_delete_key1 (HNDLE hDB, HNDLE hKey, INT level, BOOL follow_links) |
INT | db_delete_key (HNDLE hDB, HNDLE hKey, BOOL follow_links) |
INT | db_find_key (HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey) |
INT | db_set_value (HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type) |
INT | db_set_value_index (HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT idx, DWORD type, BOOL trunc) |
INT | db_get_value (HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create) |
INT | db_enum_key (HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle) |
INT | db_get_key (HNDLE hDB, HNDLE hKey, KEY *key) |
INT | db_get_link (HNDLE hDB, HNDLE hKey, KEY *key) |
INT | db_get_key_time (HNDLE hDB, HNDLE hKey, DWORD *delta) |
INT | db_get_key_info (HNDLE hDB, HNDLE hKey, char *name, INT name_size, INT *type, INT *num_values, INT *item_size) |
INT | db_get_data (HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type) |
INT | db_get_link_data (HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type) |
INT | db_get_data_index (HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type) |
INT | db_set_data (HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type) |
INT | db_set_link_data (HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type) |
INT | db_set_data_index (HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type) |
INT | db_set_link_data_index (HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type) |
INT | db_load (HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote) |
INT | db_copy (HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, char *path) |
INT | db_paste (HNDLE hDB, HNDLE hKeyRoot, const char *buffer) |
int | db_paste_node (HNDLE hDB, HNDLE hKeyRoot, PMXML_NODE node) |
INT | db_paste_xml (HNDLE hDB, HNDLE hKeyRoot, const char *buffer) |
INT | db_copy_xml (HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size) |
INT | db_save (HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote) |
void | xml_encode (char *src, int size) |
INT | db_save_xml_key (HNDLE hDB, HNDLE hKey, INT level, MXML_WRITER *writer) |
INT | db_save_xml (HNDLE hDB, HNDLE hKey, const char *filename) |
INT | db_save_struct (HNDLE hDB, HNDLE hKey, const char *file_name, const char *struct_name, BOOL append) |
INT | db_sprintf (char *string, const void *data, INT data_size, INT idx, DWORD type) |
INT | db_sprintff (char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type) |
INT | db_get_record_size (HNDLE hDB, HNDLE hKey, INT align, INT *buf_size) |
INT | db_get_record (HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align) |
INT | db_set_record (HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align) |
INT | db_create_record (HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str) |
INT | db_check_record (HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct) |
INT | db_open_record (HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info) |
INT | db_close_record (HNDLE hDB, HNDLE hKey) |
INT | db_close_all_records () |
INT | db_update_record (INT hDB, INT hKey, int s) |
INT | db_send_changed_records () |
INT db_check_record | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | keyname, | |||
const char * | rec_str, | |||
BOOL | correct | |||
) |
This function ensures that a certain ODB subtree matches a given C structure, by comparing the init_str with the current ODB structure. If the record does not exist at all, it is created with the default values in init_str. If it does exist but does not match the variables in init_str, the function returns an error if correct=FALSE or calls db_create_record() if correct=TRUE.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
keyname | Name of key to search, can contain directories. | |
rec_str | ASCII representation of ODB record in the format | |
correct | If TRUE, correct ODB record if necessary |
Definition at line 8158 of file odb.c.
Referenced by al_check(), al_trigger_alarm(), cm_connect_experiment1(), init_module_parameters(), logger_init(), main(), mana_init(), register_equipment(), register_requests(), rpc_server_dispatch(), show_custom_gif(), show_status_page(), and tr_start().
08159 { 08160 char line[MAX_STRING_LENGTH]; 08161 char title[MAX_STRING_LENGTH]; 08162 char key_name[MAX_STRING_LENGTH]; 08163 char info_str[MAX_STRING_LENGTH + 50]; 08164 char *pc; 08165 const char *pold, *rec_str_orig; 08166 DWORD tid; 08167 INT i, j, n_data, string_length, status; 08168 HNDLE hKeyRoot, hKeyTest; 08169 KEY key; 08170 BOOL multi_line; 08171 08172 if (rpc_is_remote()) 08173 return rpc_call(RPC_DB_CHECK_RECORD, hDB, hKey, keyname, rec_str, correct); 08174 08175 /* check if record exists */ 08176 status = db_find_key(hDB, hKey, keyname, &hKeyRoot); 08177 08178 /* create record if not */ 08179 if (status == DB_NO_KEY) { 08180 if (correct) 08181 return db_create_record(hDB, hKey, keyname, rec_str); 08182 return DB_NO_KEY; 08183 } 08184 08185 assert(hKeyRoot); 08186 08187 title[0] = 0; 08188 multi_line = FALSE; 08189 rec_str_orig = rec_str; 08190 08191 db_get_key(hDB, hKeyRoot, &key); 08192 if (key.type == TID_KEY) 08193 /* get next subkey which is not of type TID_KEY */ 08194 db_get_next_link(hDB, hKeyRoot, &hKeyTest); 08195 else 08196 /* test root key itself */ 08197 hKeyTest = hKeyRoot; 08198 08199 if (hKeyTest == 0 && *rec_str != 0) { 08200 if (correct) 08201 return db_create_record(hDB, hKey, keyname, rec_str_orig); 08202 08203 return DB_STRUCT_MISMATCH; 08204 } 08205 08206 do { 08207 if (*rec_str == 0) 08208 break; 08209 08210 for (i = 0; *rec_str != '\n' && *rec_str && i < MAX_STRING_LENGTH; i++) 08211 line[i] = *rec_str++; 08212 08213 if (i == MAX_STRING_LENGTH) { 08214 cm_msg(MERROR, "db_check_record", "line too long"); 08215 return DB_TRUNCATED; 08216 } 08217 08218 line[i] = 0; 08219 if (*rec_str == '\n') 08220 rec_str++; 08221 08222 /* check if it is a section title */ 08223 if (line[0] == '[') { 08224 /* extract title and append '/' */ 08225 strcpy(title, line + 1); 08226 if (strchr(title, ']')) 08227 *strchr(title, ']') = 0; 08228 if (title[0] && title[strlen(title) - 1] != '/') 08229 strcat(title, "/"); 08230 } else { 08231 /* valid data line if it includes '=' and no ';' */ 08232 if (strchr(line, '=') && line[0] != ';') { 08233 /* copy type info and data */ 08234 pc = strchr(line, '=') + 1; 08235 while (*pc == ' ') 08236 pc++; 08237 strcpy(info_str, pc); 08238 08239 /* extract key name */ 08240 *strchr(line, '=') = 0; 08241 08242 pc = &line[strlen(line) - 1]; 08243 while (*pc == ' ') 08244 *pc-- = 0; 08245 08246 strlcpy(key_name, line, sizeof(key_name)); 08247 08248 /* evaluate type info */ 08249 strcpy(line, info_str); 08250 if (strchr(line, ' ')) 08251 *strchr(line, ' ') = 0; 08252 08253 n_data = 1; 08254 if (strchr(line, '[')) { 08255 n_data = atol(strchr(line, '[') + 1); 08256 *strchr(line, '[') = 0; 08257 } 08258 08259 for (tid = 0; tid < TID_LAST; tid++) 08260 if (strcmp(tid_name[tid], line) == 0) 08261 break; 08262 08263 string_length = 0; 08264 08265 if (tid == TID_LAST) 08266 cm_msg(MERROR, "db_check_record", "found unknown data type \"%s\" in ODB file", line); 08267 else { 08268 /* skip type info */ 08269 pc = info_str; 08270 while (*pc != ' ' && *pc) 08271 pc++; 08272 while ((*pc == ' ' || *pc == ':') && *pc) 08273 pc++; 08274 08275 if (n_data > 1) { 08276 info_str[0] = 0; 08277 if (!*rec_str) 08278 break; 08279 08280 for (j = 0; *rec_str != '\n' && *rec_str; j++) 08281 info_str[j] = *rec_str++; 08282 info_str[j] = 0; 08283 if (*rec_str == '\n') 08284 rec_str++; 08285 } 08286 08287 for (i = 0; i < n_data; i++) { 08288 /* strip trailing \n */ 08289 pc = &info_str[strlen(info_str) - 1]; 08290 while (*pc == '\n' || *pc == '\r') 08291 *pc-- = 0; 08292 08293 if (tid == TID_STRING || tid == TID_LINK) { 08294 if (!string_length) { 08295 if (info_str[1] == '=') 08296 string_length = -1; 08297 else { 08298 pc = strchr(info_str, '['); 08299 if (pc != NULL) 08300 string_length = atoi(pc + 1); 08301 else 08302 string_length = -1; 08303 } 08304 if (string_length > MAX_STRING_LENGTH) { 08305 string_length = MAX_STRING_LENGTH; 08306 cm_msg(MERROR, "db_check_record", "found string exceeding MAX_STRING_LENGTH"); 08307 } 08308 } 08309 08310 if (string_length == -1) { 08311 /* multi-line string */ 08312 if (strstr(rec_str, "\n====#$@$#====\n") != NULL) { 08313 string_length = (POINTER_T) strstr(rec_str, "\n====#$@$#====\n") - (POINTER_T) rec_str + 1; 08314 08315 rec_str = strstr(rec_str, "\n====#$@$#====\n") + strlen("\n====#$@$#====\n"); 08316 } else 08317 cm_msg(MERROR, "db_check_record", "found multi-line string without termination sequence"); 08318 } else { 08319 if (strchr(info_str, ']')) 08320 pc = strchr(info_str, ']') + 1; 08321 else 08322 pc = info_str + 2; 08323 while (*pc && *pc != ' ') 08324 pc++; 08325 while (*pc && *pc == ' ') 08326 pc++; 08327 08328 /* limit string size */ 08329 *(pc + string_length - 1) = 0; 08330 } 08331 } else { 08332 pc = info_str; 08333 08334 if (n_data > 1 && info_str[0] == '[') { 08335 pc = strchr(info_str, ']') + 1; 08336 while (*pc && *pc == ' ') 08337 pc++; 08338 } 08339 } 08340 08341 if (i < n_data - 1) { 08342 info_str[0] = 0; 08343 if (!*rec_str) 08344 break; 08345 08346 pold = rec_str; 08347 08348 for (j = 0; *rec_str != '\n' && *rec_str; j++) 08349 info_str[j] = *rec_str++; 08350 info_str[j] = 0; 08351 if (*rec_str == '\n') 08352 rec_str++; 08353 08354 /* test if valid data */ 08355 if (tid != TID_STRING && tid != TID_LINK) { 08356 if (info_str[0] == 0 || (strchr(info_str, '=') 08357 && strchr(info_str, ':'))) 08358 rec_str = pold; 08359 } 08360 } 08361 } 08362 08363 /* if rec_str contains key, but not ODB, return mismatch */ 08364 if (!hKeyTest) { 08365 if (correct) 08366 return db_create_record(hDB, hKey, keyname, rec_str_orig); 08367 08368 return DB_STRUCT_MISMATCH; 08369 } 08370 08371 status = db_get_key(hDB, hKeyTest, &key); 08372 assert(status == DB_SUCCESS); 08373 08374 /* check rec_str vs. ODB key */ 08375 if (!equal_ustring(key.name, key_name) || key.type != tid || key.num_values != n_data) { 08376 if (correct) 08377 return db_create_record(hDB, hKey, keyname, rec_str_orig); 08378 08379 return DB_STRUCT_MISMATCH; 08380 } 08381 08382 /* get next key in ODB */ 08383 db_get_next_link(hDB, hKeyTest, &hKeyTest); 08384 } 08385 } 08386 } 08387 } while (TRUE); 08388 08389 return DB_SUCCESS; 08390 }
INT db_close_all_records | ( | ) |
Release local memory for open records. This routines is called by db_close_all_databases() and cm_disconnect_experiment()
Definition at line 8629 of file odb.c.
Referenced by cm_disconnect_experiment().
08630 { 08631 INT i; 08632 08633 for (i = 0; i < _record_list_entries; i++) { 08634 if (_record_list[i].handle) { 08635 if (_record_list[i].access_mode & MODE_WRITE) 08636 free(_record_list[i].copy); 08637 08638 if (_record_list[i].access_mode & MODE_ALLOC) 08639 free(_record_list[i].data); 08640 08641 memset(&_record_list[i], 0, sizeof(RECORD_LIST)); 08642 } 08643 } 08644 08645 if (_record_list_entries > 0) { 08646 _record_list_entries = 0; 08647 free(_record_list); 08648 } 08649 08650 return DB_SUCCESS; 08651 }
INT db_close_database | ( | HNDLE | hDB | ) |
Close a database
hDB | ODB handle obtained via cm_get_experiment_database(). |
Definition at line 1100 of file odb.c.
Referenced by rpc_server_dispatch().
01101 { 01102 if (rpc_is_remote()) 01103 return rpc_call(RPC_DB_CLOSE_DATABASE, hDB); 01104 01105 #ifdef LOCAL_ROUTINES 01106 else { 01107 DATABASE_HEADER *pheader; 01108 DATABASE_CLIENT *pclient; 01109 INT idx, destroy_flag, i, j; 01110 01111 if (hDB > _database_entries || hDB <= 0) { 01112 cm_msg(MERROR, "db_close_database", "invalid database handle"); 01113 return DB_INVALID_HANDLE; 01114 } 01115 01116 /* 01117 Check if database was opened by current thread. This is necessary 01118 in the server process where one thread may not close the database 01119 of other threads. 01120 */ 01121 01122 /* first lock database */ 01123 db_lock_database(hDB); 01124 01125 idx = _database[hDB - 1].client_index; 01126 pheader = _database[hDB - 1].database_header; 01127 pclient = &pheader->client[idx]; 01128 01129 if (rpc_get_server_option(RPC_OSERVER_TYPE) == ST_SINGLE && 01130 _database[hDB - 1].index != rpc_get_server_acception()) { 01131 db_unlock_database(hDB); 01132 return DB_INVALID_HANDLE; 01133 } 01134 01135 if (rpc_get_server_option(RPC_OSERVER_TYPE) != ST_SINGLE && _database[hDB - 1].index != ss_gettid()) { 01136 db_unlock_database(hDB); 01137 return DB_INVALID_HANDLE; 01138 } 01139 01140 if (!_database[hDB - 1].attached) { 01141 cm_msg(MERROR, "db_close_database", "invalid database handle"); 01142 db_unlock_database(hDB); 01143 return DB_INVALID_HANDLE; 01144 } 01145 01146 /* close all open records */ 01147 for (i = 0; i < pclient->max_index; i++) 01148 if (pclient->open_record[i].handle) 01149 db_remove_open_record(hDB, pclient->open_record[i].handle, FALSE); 01150 01151 /* mark entry in _database as empty */ 01152 _database[hDB - 1].attached = FALSE; 01153 01154 /* clear entry from client structure in database header */ 01155 memset(&(pheader->client[idx]), 0, sizeof(DATABASE_CLIENT)); 01156 01157 /* calculate new max_client_index entry */ 01158 for (i = MAX_CLIENTS - 1; i >= 0; i--) 01159 if (pheader->client[i].pid != 0) 01160 break; 01161 pheader->max_client_index = i + 1; 01162 01163 /* count new number of clients */ 01164 for (i = MAX_CLIENTS - 1, j = 0; i >= 0; i--) 01165 if (pheader->client[i].pid != 0) 01166 j++; 01167 pheader->num_clients = j; 01168 01169 destroy_flag = (pheader->num_clients == 0); 01170 01171 /* flush shared memory to disk */ 01172 ss_shm_flush(pheader->name, pheader, sizeof(DATABASE_HEADER) + 2 * pheader->data_size, _database[hDB - 1].shm_handle); 01173 01174 /* unmap shared memory, delete it if we are the last */ 01175 ss_shm_close(pheader->name, pheader, _database[hDB - 1].shm_handle, destroy_flag); 01176 01177 /* unlock database */ 01178 db_unlock_database(hDB); 01179 01180 /* delete semaphore */ 01181 ss_semaphore_delete(_database[hDB - 1].semaphore, destroy_flag); 01182 01183 /* update _database_entries */ 01184 if (hDB == _database_entries) 01185 _database_entries--; 01186 01187 if (_database_entries > 0) 01188 _database = (DATABASE *) realloc(_database, sizeof(DATABASE) * (_database_entries)); 01189 else { 01190 free(_database); 01191 _database = NULL; 01192 } 01193 01194 /* if we are the last one, also delete other semaphores */ 01195 if (destroy_flag) { 01196 extern INT _semaphore_elog, _semaphore_alarm, _semaphore_history, _semaphore_msg; 01197 01198 if (_semaphore_elog) 01199 ss_semaphore_delete(_semaphore_elog, TRUE); 01200 if (_semaphore_alarm) 01201 ss_semaphore_delete(_semaphore_alarm, TRUE); 01202 if (_semaphore_history) 01203 ss_semaphore_delete(_semaphore_history, TRUE); 01204 if (_semaphore_msg) 01205 ss_semaphore_delete(_semaphore_msg, TRUE); 01206 } 01207 01208 } 01209 #endif /* LOCAL_ROUTINES */ 01210 01211 return DB_SUCCESS; 01212 }
INT db_close_record | ( | HNDLE | hDB, | |
HNDLE | hKey | |||
) |
Close a record previously opend with db_open_record.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. |
Definition at line 8592 of file odb.c.
Referenced by banks_changed(), close_channels(), close_history(), command_loop(), init_module_parameters(), tr_start(), and tr_stop().
08593 { 08594 #ifdef LOCAL_ROUTINES 08595 { 08596 INT i; 08597 08598 for (i = 0; i < _record_list_entries; i++) 08599 if (_record_list[i].handle == hKey && _record_list[i].hDB == hDB) 08600 break; 08601 08602 if (i == _record_list_entries) 08603 return DB_INVALID_HANDLE; 08604 08605 /* remove record entry from database structure */ 08606 db_remove_open_record(hDB, hKey, TRUE); 08607 08608 /* free local memory */ 08609 if (_record_list[i].access_mode & MODE_ALLOC) 08610 free(_record_list[i].data); 08611 08612 if (_record_list[i].access_mode & MODE_WRITE) 08613 free(_record_list[i].copy); 08614 08615 memset(&_record_list[i], 0, sizeof(RECORD_LIST)); 08616 } 08617 #endif /* LOCAL_ROUTINES */ 08618 08619 return DB_SUCCESS; 08620 }
Copy an ODB subtree in ASCII format to a buffer
This function converts the binary ODB contents to an ASCII. The function db_paste() can be used to convert the ASCII representation back to binary ODB contents. The functions db_load() and db_save() internally use db_copy() and db_paste(). This function converts the binary ODB contents to an ASCII representation of the form:
key name = STRING : [size] string contents
key name = type[size] : [0] value0 [1] value1 [2] value2 ...
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
buffer | ASCII buffer which receives ODB contents. | |
buffer_size | Size of buffer, returns remaining space in buffer. | |
path | Internal use only, must be empty (""). |
Definition at line 5632 of file odb.c.
Referenced by command_loop(), db_create_record(), and db_save().
05633 { 05634 INT i, j, size, status; 05635 KEY key; 05636 HNDLE hSubkey; 05637 char full_path[MAX_ODB_PATH], str[MAX_STRING_LENGTH * 2]; 05638 char *data, line[MAX_STRING_LENGTH * 2]; 05639 BOOL bWritten; 05640 05641 strcpy(full_path, path); 05642 05643 bWritten = FALSE; 05644 05645 /* first enumerate this level */ 05646 for (i = 0;; i++) { 05647 db_enum_link(hDB, hKey, i, &hSubkey); 05648 05649 if (i == 0 && !hSubkey) { 05650 /* If key has no subkeys, just write this key */ 05651 status = db_get_link(hDB, hKey, &key); 05652 if (status != DB_SUCCESS) 05653 continue; 05654 size = key.total_size; 05655 data = (char *) malloc(size); 05656 if (data == NULL) { 05657 cm_msg(MERROR, "db_copy", "cannot allocate data buffer"); 05658 return DB_NO_MEMORY; 05659 } 05660 line[0] = 0; 05661 05662 if (key.type != TID_KEY) { 05663 status = db_get_link_data(hDB, hKey, data, &size, key.type); 05664 if (status != DB_SUCCESS) 05665 continue; 05666 if (key.num_values == 1) { 05667 sprintf(line, "%s = %s : ", key.name, tid_name[key.type]); 05668 05669 if (key.type == TID_STRING && strchr(data, '\n') != NULL) { 05670 /* multiline string */ 05671 sprintf(line + strlen(line), "[====#$@$#====]\n"); 05672 05673 /* copy line to buffer */ 05674 if ((INT) (strlen(line) + 1) > *buffer_size) { 05675 free(data); 05676 return DB_TRUNCATED; 05677 } 05678 05679 strcpy(buffer, line); 05680 buffer += strlen(line); 05681 *buffer_size -= strlen(line); 05682 05683 /* copy multiple lines to buffer */ 05684 if (key.item_size > *buffer_size) { 05685 free(data); 05686 return DB_TRUNCATED; 05687 } 05688 05689 strcpy(buffer, data); 05690 buffer += strlen(data); 05691 *buffer_size -= strlen(data); 05692 05693 strcpy(line, "\n====#$@$#====\n"); 05694 } else { 05695 db_sprintf(str, data, key.item_size, 0, key.type); 05696 05697 if (key.type == TID_STRING || key.type == TID_LINK) 05698 sprintf(line + strlen(line), "[%d] ", key.item_size); 05699 05700 sprintf(line + strlen(line), "%s\n", str); 05701 } 05702 } else { 05703 sprintf(line, "%s = %s[%d] :\n", key.name, tid_name[key.type], key.num_values); 05704 05705 for (j = 0; j < key.num_values; j++) { 05706 if (key.type == TID_STRING || key.type == TID_LINK) 05707 sprintf(line + strlen(line), "[%d] ", key.item_size); 05708 else 05709 sprintf(line + strlen(line), "[%d] ", j); 05710 05711 db_sprintf(str, data, key.item_size, j, key.type); 05712 sprintf(line + strlen(line), "%s\n", str); 05713 05714 /* copy line to buffer */ 05715 if ((INT) (strlen(line) + 1) > *buffer_size) { 05716 free(data); 05717 return DB_TRUNCATED; 05718 } 05719 05720 strcpy(buffer, line); 05721 buffer += strlen(line); 05722 *buffer_size -= strlen(line); 05723 line[0] = 0; 05724 } 05725 } 05726 } 05727 05728 /* copy line to buffer */ 05729 if ((INT) (strlen(line) + 1) > *buffer_size) { 05730 free(data); 05731 return DB_TRUNCATED; 05732 } 05733 05734 strcpy(buffer, line); 05735 buffer += strlen(line); 05736 *buffer_size -= strlen(line); 05737 05738 free(data); 05739 } 05740 05741 if (!hSubkey) 05742 break; 05743 05744 status = db_get_link(hDB, hSubkey, &key); 05745 if (status != DB_SUCCESS) 05746 continue; 05747 05748 if (strcmp(key.name, "arr2") == 0) 05749 printf("\narr2\n"); 05750 size = key.total_size; 05751 data = (char *) malloc(size); 05752 if (data == NULL) { 05753 cm_msg(MERROR, "db_copy", "cannot allocate data buffer"); 05754 return DB_NO_MEMORY; 05755 } 05756 05757 line[0] = 0; 05758 05759 if (key.type == TID_KEY) { 05760 /* new line */ 05761 if (bWritten) { 05762 if (*buffer_size < 2) { 05763 free(data); 05764 return DB_TRUNCATED; 05765 } 05766 05767 strcpy(buffer, "\n"); 05768 buffer += 1; 05769 *buffer_size -= 1; 05770 } 05771 05772 strcpy(str, full_path); 05773 if (str[0] && str[strlen(str) - 1] != '/') 05774 strcat(str, "/"); 05775 strcat(str, key.name); 05776 05777 /* recurse */ 05778 status = db_copy(hDB, hSubkey, buffer, buffer_size, str); 05779 if (status != DB_SUCCESS) { 05780 free(data); 05781 return status; 05782 } 05783 05784 buffer += strlen(buffer); 05785 bWritten = FALSE; 05786 } else { 05787 status = db_get_link_data(hDB, hSubkey, data, &size, key.type); 05788 if (status != DB_SUCCESS) 05789 continue; 05790 05791 if (!bWritten) { 05792 if (path[0] == 0) 05793 sprintf(line, "[.]\n"); 05794 else 05795 sprintf(line, "[%s]\n", path); 05796 bWritten = TRUE; 05797 } 05798 05799 if (key.num_values == 1) { 05800 sprintf(line + strlen(line), "%s = %s : ", key.name, tid_name[key.type]); 05801 05802 if (key.type == TID_STRING && strchr(data, '\n') != NULL) { 05803 /* multiline string */ 05804 sprintf(line + strlen(line), "[====#$@$#====]\n"); 05805 05806 /* ensure string limiter */ 05807 data[size - 1] = 0; 05808 05809 /* copy line to buffer */ 05810 if ((INT) (strlen(line) + 1) > *buffer_size) { 05811 free(data); 05812 return DB_TRUNCATED; 05813 } 05814 05815 strcpy(buffer, line); 05816 buffer += strlen(line); 05817 *buffer_size -= strlen(line); 05818 05819 /* copy multiple lines to buffer */ 05820 if (key.item_size > *buffer_size) { 05821 free(data); 05822 return DB_TRUNCATED; 05823 } 05824 05825 strcpy(buffer, data); 05826 buffer += strlen(data); 05827 *buffer_size -= strlen(data); 05828 05829 strcpy(line, "\n====#$@$#====\n"); 05830 } else { 05831 db_sprintf(str, data, key.item_size, 0, key.type); 05832 05833 if (key.type == TID_STRING || key.type == TID_LINK) 05834 sprintf(line + strlen(line), "[%d] ", key.item_size); 05835 05836 sprintf(line + strlen(line), "%s\n", str); 05837 } 05838 } else { 05839 sprintf(line + strlen(line), "%s = %s[%d] :\n", key.name, tid_name[key.type], key.num_values); 05840 05841 for (j = 0; j < key.num_values; j++) { 05842 if (key.type == TID_STRING || key.type == TID_LINK) 05843 sprintf(line + strlen(line), "[%d] ", key.item_size); 05844 else 05845 sprintf(line + strlen(line), "[%d] ", j); 05846 05847 db_sprintf(str, data, key.item_size, j, key.type); 05848 sprintf(line + strlen(line), "%s\n", str); 05849 05850 /* copy line to buffer */ 05851 if ((INT) (strlen(line) + 1) > *buffer_size) { 05852 free(data); 05853 return DB_TRUNCATED; 05854 } 05855 05856 strcpy(buffer, line); 05857 buffer += strlen(line); 05858 *buffer_size -= strlen(line); 05859 line[0] = 0; 05860 } 05861 } 05862 05863 /* copy line to buffer */ 05864 if ((INT) (strlen(line) + 1) > *buffer_size) { 05865 free(data); 05866 return DB_TRUNCATED; 05867 } 05868 05869 strcpy(buffer, line); 05870 buffer += strlen(line); 05871 *buffer_size -= strlen(line); 05872 } 05873 05874 free(data); 05875 } 05876 05877 if (bWritten) { 05878 if (*buffer_size < 2) 05879 return DB_TRUNCATED; 05880 05881 strcpy(buffer, "\n"); 05882 buffer += 1; 05883 *buffer_size -= 1; 05884 } 05885 05886 return DB_SUCCESS; 05887 }
Copy an ODB subtree in XML format to a buffer
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
buffer | ASCII buffer which receives ODB contents. | |
buffer_size | Size of buffer, returns remaining space in buffer. |
Definition at line 6343 of file odb.c.
Referenced by log_odb_dump().
06344 { 06345 #ifdef LOCAL_ROUTINES 06346 { 06347 INT len; 06348 char *p, str[256]; 06349 MXML_WRITER *writer; 06350 06351 /* open file */ 06352 writer = mxml_open_buffer(); 06353 if (writer == NULL) { 06354 cm_msg(MERROR, "db_copy_xml", "Cannot allocate buffer"); 06355 return DB_NO_MEMORY; 06356 } 06357 06358 db_get_path(hDB, hKey, str, sizeof(str)); 06359 06360 /* write XML header */ 06361 mxml_start_element(writer, "odb"); 06362 mxml_write_attribute(writer, "root", str); 06363 mxml_write_attribute(writer, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 06364 mxml_write_attribute(writer, "xsi:noNamespaceSchemaLocation", "http://midas.psi.ch/odb.xsd"); 06365 06366 db_save_xml_key(hDB, hKey, 0, writer); 06367 06368 mxml_end_element(writer); // "odb" 06369 p = mxml_close_buffer(writer); 06370 06371 strlcpy(buffer, p, *buffer_size); 06372 len = strlen(p); 06373 free(p); 06374 if (len > *buffer_size) { 06375 *buffer_size = 0; 06376 return DB_TRUNCATED; 06377 } 06378 06379 *buffer_size -= len; 06380 } 06381 #endif /* LOCAL_ROUTINES */ 06382 06383 return DB_SUCCESS; 06384 }
Create a new key in a database
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Key handle to start with, 0 for root | |
key_name | Name of key in the form "/key/key/key" | |
type | Type of key, one of TID_xxx (see Midas Data Types) |
Definition at line 1584 of file odb.c.
Referenced by add_event(), command_loop(), db_create_record(), db_get_value(), db_paste(), db_paste_node(), db_set_value(), db_set_value_index(), open_history(), register_equipment(), rpc_server_dispatch(), show_create_page(), show_custom_page(), show_elog_page(), show_hist_page(), and xdb_find_key().
01585 { 01586 if (rpc_is_remote()) 01587 return rpc_call(RPC_DB_CREATE_KEY, hDB, hKey, key_name, type); 01588 01589 #ifdef LOCAL_ROUTINES 01590 { 01591 DATABASE_HEADER *pheader; 01592 KEYLIST *pkeylist; 01593 KEY *pkey, *pprev_key, *pkeyparent; 01594 const char *pkey_name; 01595 char str[MAX_STRING_LENGTH]; 01596 INT i; 01597 01598 if (hDB > _database_entries || hDB <= 0) { 01599 cm_msg(MERROR, "db_create_key", "invalid database handle"); 01600 return DB_INVALID_HANDLE; 01601 } 01602 01603 if (!_database[hDB - 1].attached) { 01604 cm_msg(MERROR, "db_create_key", "invalid database handle"); 01605 return DB_INVALID_HANDLE; 01606 } 01607 01608 /* check type */ 01609 if (type <= 0 || type >= TID_LAST) { 01610 cm_msg(MERROR, "db_create_key", "invalid key type %d for \'%s\'", type, key_name); 01611 return DB_INVALID_PARAM; 01612 } 01613 01614 /* lock database */ 01615 db_lock_database(hDB); 01616 01617 pheader = _database[hDB - 1].database_header; 01618 if (!hKey) 01619 hKey = pheader->root_key; 01620 pkey = (KEY *) ((char *) pheader + hKey); 01621 01622 /* check if hKey argument is correct */ 01623 if (!db_validate_hkey(pheader, hKey)) { 01624 db_unlock_database(hDB); 01625 return DB_INVALID_HANDLE; 01626 } 01627 01628 if (pkey->type != TID_KEY) { 01629 db_unlock_database(hDB); 01630 cm_msg(MERROR, "db_create_key", "key has no subkeys"); 01631 return DB_NO_KEY; 01632 } 01633 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 01634 01635 pkey_name = key_name; 01636 do { 01637 /* extract single key from key_name */ 01638 pkey_name = extract_key(pkey_name, str, sizeof(str)); 01639 01640 /* do not allow empty names, like '/dir/dir//dir/' */ 01641 if (str[0] == 0) { 01642 db_unlock_database(hDB); 01643 return DB_INVALID_PARAM; 01644 } 01645 01646 /* check if parent or current directory */ 01647 if (strcmp(str, "..") == 0) { 01648 if (pkey->parent_keylist) { 01649 pkeylist = (KEYLIST *) ((char *) pheader + pkey->parent_keylist); 01650 pkey = (KEY *) ((char *) pheader + pkeylist->parent); 01651 } 01652 continue; 01653 } 01654 if (strcmp(str, ".") == 0) 01655 continue; 01656 01657 /* check if key is in keylist */ 01658 pkey = (KEY *) ((char *) pheader + pkeylist->first_key); 01659 pprev_key = NULL; 01660 01661 for (i = 0; i < pkeylist->num_keys; i++) { 01662 if (!db_validate_key_offset(pheader, pkey->next_key)) { 01663 cm_msg(MERROR, "db_create_key", 01664 "Warning: database corruption, key %s, next_key 0x%08X", 01665 key_name, pkey->next_key - sizeof(DATABASE_HEADER)); 01666 db_unlock_database(hDB); 01667 return DB_CORRUPTED; 01668 } 01669 01670 if (equal_ustring(str, pkey->name)) 01671 break; 01672 01673 pprev_key = pkey; 01674 pkey = (KEY *) ((char *) pheader + pkey->next_key); 01675 } 01676 01677 if (i == pkeylist->num_keys) { 01678 /* not found: create new key */ 01679 01680 /* check parent for write access */ 01681 pkeyparent = (KEY *) ((char *) pheader + pkeylist->parent); 01682 if (!(pkeyparent->access_mode & MODE_WRITE) || (pkeyparent->access_mode & MODE_EXCLUSIVE)) { 01683 db_unlock_database(hDB); 01684 return DB_NO_ACCESS; 01685 } 01686 01687 pkeylist->num_keys++; 01688 01689 if (*pkey_name == '/' || type == TID_KEY) { 01690 /* create new key with keylist */ 01691 pkey = (KEY *) malloc_key(pheader, sizeof(KEY)); 01692 01693 if (pkey == NULL) { 01694 db_unlock_database(hDB); 01695 cm_msg(MERROR, "db_create_key", "online database full"); 01696 return DB_FULL; 01697 } 01698 01699 /* append key to key list */ 01700 if (pprev_key) 01701 pprev_key->next_key = (POINTER_T) pkey - (POINTER_T) pheader; 01702 else 01703 pkeylist->first_key = (POINTER_T) pkey - (POINTER_T) pheader; 01704 01705 /* set key properties */ 01706 pkey->type = TID_KEY; 01707 pkey->num_values = 1; 01708 pkey->access_mode = MODE_READ | MODE_WRITE | MODE_DELETE; 01709 strlcpy(pkey->name, str, sizeof(pkey->name)); 01710 pkey->parent_keylist = (POINTER_T) pkeylist - (POINTER_T) pheader; 01711 01712 /* find space for new keylist */ 01713 pkeylist = (KEYLIST *) malloc_key(pheader, sizeof(KEYLIST)); 01714 01715 if (pkeylist == NULL) { 01716 db_unlock_database(hDB); 01717 cm_msg(MERROR, "db_create_key", "online database full"); 01718 return DB_FULL; 01719 } 01720 01721 /* store keylist in data field */ 01722 pkey->data = (POINTER_T) pkeylist - (POINTER_T) pheader; 01723 pkey->item_size = sizeof(KEYLIST); 01724 pkey->total_size = sizeof(KEYLIST); 01725 01726 pkeylist->parent = (POINTER_T) pkey - (POINTER_T) pheader; 01727 pkeylist->num_keys = 0; 01728 pkeylist->first_key = 0; 01729 } else { 01730 /* create new key with data */ 01731 pkey = (KEY *) malloc_key(pheader, sizeof(KEY)); 01732 01733 if (pkey == NULL) { 01734 db_unlock_database(hDB); 01735 cm_msg(MERROR, "db_create_key", "online database full"); 01736 return DB_FULL; 01737 } 01738 01739 /* append key to key list */ 01740 if (pprev_key) 01741 pprev_key->next_key = (POINTER_T) pkey - (POINTER_T) pheader; 01742 else 01743 pkeylist->first_key = (POINTER_T) pkey - (POINTER_T) pheader; 01744 01745 pkey->type = type; 01746 pkey->num_values = 1; 01747 pkey->access_mode = MODE_READ | MODE_WRITE | MODE_DELETE; 01748 strlcpy(pkey->name, str, sizeof(pkey->name)); 01749 pkey->parent_keylist = (POINTER_T) pkeylist - (POINTER_T) pheader; 01750 01751 /* zero data */ 01752 if (type != TID_STRING && type != TID_LINK) { 01753 pkey->item_size = rpc_tid_size(type); 01754 pkey->data = (POINTER_T) malloc_data(pheader, pkey->item_size); 01755 pkey->total_size = pkey->item_size; 01756 01757 if (pkey->data == 0) { 01758 db_unlock_database(hDB); 01759 cm_msg(MERROR, "db_create_key", "online database full"); 01760 return DB_FULL; 01761 } 01762 01763 pkey->data -= (POINTER_T) pheader; 01764 } else { 01765 /* first data is empty */ 01766 pkey->item_size = 0; 01767 pkey->total_size = 0; 01768 pkey->data = 0; 01769 } 01770 } 01771 } else { 01772 /* key found: descend */ 01773 01774 /* resolve links */ 01775 if (pkey->type == TID_LINK && pkey_name[0]) { 01776 /* copy destination, strip '/' */ 01777 strcpy(str, (char *) pheader + pkey->data); 01778 if (str[strlen(str) - 1] == '/') 01779 str[strlen(str) - 1] = 0; 01780 01781 /* append rest of key name */ 01782 strcat(str, pkey_name); 01783 01784 db_unlock_database(hDB); 01785 01786 return db_create_key(hDB, 0, str, type); 01787 } 01788 01789 if (!(*pkey_name == '/')) { 01790 if ((WORD) pkey->type != type) 01791 cm_msg(MERROR, "db_create_key", "redefinition of key type mismatch"); 01792 01793 db_unlock_database(hDB); 01794 return DB_KEY_EXIST; 01795 } 01796 01797 if (pkey->type != TID_KEY) { 01798 db_unlock_database(hDB); 01799 cm_msg(MERROR, "db_create_key", "key used with value and as parent key"); 01800 return DB_KEY_EXIST; 01801 } 01802 01803 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 01804 } 01805 } while (*pkey_name == '/'); 01806 01807 db_unlock_database(hDB); 01808 } 01809 #endif /* LOCAL_ROUTINES */ 01810 01811 return DB_SUCCESS; 01812 }
INT db_create_link | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | link_name, | |||
const char * | destination | |||
) |
Create a link to a key or set the destination of and existing link.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Key handle to start with, 0 for root | |
link_name | Name of key in the form "/key/key/key" | |
destination | Destination of link in the form "/key/key/key" |
Definition at line 1823 of file odb.c.
Referenced by command_loop(), open_history(), rpc_server_dispatch(), and show_create_page().
01824 { 01825 HNDLE hkey; 01826 int status; 01827 01828 if (rpc_is_remote()) 01829 return rpc_call(RPC_DB_CREATE_LINK, hDB, hKey, link_name, destination); 01830 01831 /* check if destination exists */ 01832 status = db_find_key(hDB, hKey, destination, &hkey); 01833 if (status != DB_SUCCESS) { 01834 cm_msg(MERROR, "db_create_link", "Link destination \"%s\" does not exist", destination); 01835 return DB_NO_KEY; 01836 } 01837 01838 return db_set_value(hDB, hKey, link_name, destination, strlen(destination) + 1, 1, TID_LINK); 01839 }
INT db_create_record | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | orig_key_name, | |||
const char * | init_str | |||
) |
Create a record. If a part of the record exists alreay, merge it with the init_str (use values from the init_str only when they are not in the existing record).
This functions creates a ODB sub-tree according to an ASCII representation of that tree. See db_copy() for a description. It can be used to create a sub-tree which exactly matches a C structure. The sub-tree can then later mapped to the C structure ("hot-link") via the function db_open_record().
If a sub-tree exists already which exactly matches the ASCII representation, it is not modified. If part of the tree exists, it is merged with the ASCII representation where the ODB values have priority, only values not present in the ODB are created with the default values of the ASCII representation. It is therefore recommended that before creating an ODB hot-link the function db_create_record() is called to insure that the ODB tree and the C structure contain exactly the same values in the same order.
Following example creates a record under /Equipment/Trigger/Settings, opens a hot-link between that record and a local C structure trigger_settings and registers a callback function trigger_update() which gets called each time the record is changed.
struct { INT level1; INT level2; } trigger_settings; char *trigger_settings_str = "[Settings]\n\ level1 = INT : 0\n\ level2 = INT : 0"; void trigger_update(INT hDB, INT hkey, void *info) { printf("New levels: %d %d\n", trigger_settings.level1, trigger_settings.level2); } main() { HNDLE hDB, hkey; char[128] info; ... cm_get_experiment_database(&hDB, NULL); db_create_record(hDB, 0, "/Equipment/Trigger", trigger_settings_str); db_find_key(hDB, 0,"/Equipment/Trigger/Settings", &hkey); db_open_record(hDB, hkey, &trigger_settings, sizeof(trigger_settings), MODE_READ, trigger_update, info); ... }
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
orig_key_name | Name of key to search, can contain directories. | |
init_str | Initialization string in the format of the db_copy/db_save functions. |
Definition at line 7989 of file odb.c.
Referenced by al_check(), al_trigger_alarm(), analyzer_init(), cm_set_client_info(), db_check_record(), frontend_init(), init_module_parameters(), logger_init(), main(), mana_init(), register_equipment(), register_requests(), rpc_server_dispatch(), and tr_start().
07990 { 07991 char str[256], key_name[256], *buffer; 07992 INT status, size, i, buffer_size; 07993 HNDLE hKeyTmp, hKeyTmpO, hKeyOrig, hSubkey; 07994 07995 if (rpc_is_remote()) 07996 return rpc_call(RPC_DB_CREATE_RECORD, hDB, hKey, orig_key_name, init_str); 07997 07998 /* make this function atomic */ 07999 db_lock_database(hDB); 08000 08001 /* strip trailing '/' */ 08002 strlcpy(key_name, orig_key_name, sizeof(key_name)); 08003 if (strlen(key_name) > 1 && key_name[strlen(key_name) - 1] == '/') 08004 key_name[strlen(key_name) - 1] = 0; 08005 08006 /* merge temporay record and original record */ 08007 status = db_find_key(hDB, hKey, key_name, &hKeyOrig); 08008 if (status == DB_SUCCESS) { 08009 assert(hKeyOrig != 0); 08010 /* check if key or subkey is opened */ 08011 open_count = 0; 08012 db_scan_tree_link(hDB, hKeyOrig, 0, check_open_keys, NULL); 08013 if (open_count) { 08014 db_unlock_database(hDB); 08015 return DB_OPEN_RECORD; 08016 } 08017 08018 /* create temporary records */ 08019 sprintf(str, "/System/Tmp/%1dI", ss_gettid()); 08020 db_find_key(hDB, 0, str, &hKeyTmp); 08021 if (hKeyTmp) 08022 db_delete_key(hDB, hKeyTmp, FALSE); 08023 db_create_key(hDB, 0, str, TID_KEY); 08024 status = db_find_key(hDB, 0, str, &hKeyTmp); 08025 if (status != DB_SUCCESS) { 08026 db_unlock_database(hDB); 08027 return status; 08028 } 08029 08030 sprintf(str, "/System/Tmp/%1dO", ss_gettid()); 08031 db_find_key(hDB, 0, str, &hKeyTmpO); 08032 if (hKeyTmpO) 08033 db_delete_key(hDB, hKeyTmpO, FALSE); 08034 db_create_key(hDB, 0, str, TID_KEY); 08035 status = db_find_key(hDB, 0, str, &hKeyTmpO); 08036 if (status != DB_SUCCESS) { 08037 db_unlock_database(hDB); 08038 return status; 08039 } 08040 08041 status = db_paste(hDB, hKeyTmp, init_str); 08042 if (status != DB_SUCCESS) { 08043 db_unlock_database(hDB); 08044 return status; 08045 } 08046 08047 buffer_size = 10000; 08048 buffer = (char *) malloc(buffer_size); 08049 do { 08050 size = buffer_size; 08051 status = db_copy(hDB, hKeyOrig, buffer, &size, ""); 08052 if (status == DB_TRUNCATED) { 08053 buffer_size += 10000; 08054 buffer = (char *) realloc(buffer, buffer_size); 08055 continue; 08056 } 08057 if (status != DB_SUCCESS) { 08058 db_unlock_database(hDB); 08059 return status; 08060 } 08061 08062 } while (status != DB_SUCCESS); 08063 08064 status = db_paste(hDB, hKeyTmpO, buffer); 08065 if (status != DB_SUCCESS) { 08066 free(buffer); 08067 db_unlock_database(hDB); 08068 return status; 08069 } 08070 08071 /* merge temporay record and original record */ 08072 db_scan_tree_link(hDB, hKeyTmpO, 0, merge_records, NULL); 08073 08074 /* delete original record */ 08075 for (i = 0;; i++) { 08076 db_enum_link(hDB, hKeyOrig, 0, &hSubkey); 08077 if (!hSubkey) 08078 break; 08079 08080 status = db_delete_key(hDB, hSubkey, FALSE); 08081 if (status != DB_SUCCESS) { 08082 free(buffer); 08083 db_unlock_database(hDB); 08084 return status; 08085 } 08086 } 08087 08088 /* copy merged record to original record */ 08089 do { 08090 size = buffer_size; 08091 status = db_copy(hDB, hKeyTmp, buffer, &size, ""); 08092 if (status == DB_TRUNCATED) { 08093 buffer_size += 10000; 08094 buffer = (char *) realloc(buffer, buffer_size); 08095 continue; 08096 } 08097 if (status != DB_SUCCESS) { 08098 free(buffer); 08099 db_unlock_database(hDB); 08100 return status; 08101 } 08102 08103 } while (status != DB_SUCCESS); 08104 08105 status = db_paste(hDB, hKeyOrig, buffer); 08106 if (status != DB_SUCCESS) { 08107 free(buffer); 08108 db_unlock_database(hDB); 08109 return status; 08110 } 08111 08112 /* delete temporary records */ 08113 db_delete_key(hDB, hKeyTmp, FALSE); 08114 db_delete_key(hDB, hKeyTmpO, FALSE); 08115 08116 free(buffer); 08117 } else if (status == DB_NO_KEY) { 08118 /* create fresh record */ 08119 db_create_key(hDB, hKey, key_name, TID_KEY); 08120 status = db_find_key(hDB, hKey, key_name, &hKeyTmp); 08121 if (status != DB_SUCCESS) { 08122 db_unlock_database(hDB); 08123 return status; 08124 } 08125 08126 status = db_paste(hDB, hKeyTmp, init_str); 08127 if (status != DB_SUCCESS) { 08128 db_unlock_database(hDB); 08129 return status; 08130 } 08131 } else { 08132 cm_msg(MERROR, "db_create_record", 08133 "aborting on unexpected failure of db_find_key(%s), status %d", key_name, status); 08134 abort(); 08135 } 08136 08137 db_unlock_database(hDB); 08138 08139 return DB_SUCCESS; 08140 }
Delete a subtree in a database starting from a key (including this key).
... status = db_find_link(hDB, 0, str, &hkey); if (status != DB_SUCCESS) { cm_msg(MINFO,"my_delete"," "Cannot find key %s", str); return; } status = db_delete_key(hDB, hkey, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR,"my_delete"," "Cannot delete key %s", str); return; } ...
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | for key where search starts, zero for root. | |
follow_links | Follow links when TRUE. |
Definition at line 2020 of file odb.c.
Referenced by add_event(), cm_deregister_transition(), cm_set_client_info(), command_loop(), db_create_record(), del_tree(), export_hist(), generate_hist_graph(), main(), rpc_server_dispatch(), show_delete_page(), and show_hist_page().
02021 { 02022 if (rpc_is_remote()) 02023 return rpc_call(RPC_DB_DELETE_KEY, hDB, hKey, follow_links); 02024 02025 return db_delete_key1(hDB, hKey, 0, follow_links); 02026 }
Delete a subtree, using level information (only called internally by db_delete_key())
For internal use only.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Key handle to start with, 0 for root | |
level | Recursion level, must be zero when | |
follow_links | Follow links when TRUE called from a user routine |
Definition at line 1851 of file odb.c.
Referenced by cm_delete_client_info(), and db_delete_key().
01852 { 01853 #ifdef LOCAL_ROUTINES 01854 { 01855 DATABASE_HEADER *pheader; 01856 KEYLIST *pkeylist; 01857 KEY *pkey, *pnext_key, *pkey_tmp; 01858 HNDLE hKeyLink; 01859 BOOL deny_delete; 01860 INT status; 01861 01862 if (hDB > _database_entries || hDB <= 0) { 01863 cm_msg(MERROR, "db_delete_key1", "invalid database handle"); 01864 return DB_INVALID_HANDLE; 01865 } 01866 01867 if (!_database[hDB - 1].attached) { 01868 cm_msg(MERROR, "db_delete_key1", "invalid database handle"); 01869 return DB_INVALID_HANDLE; 01870 } 01871 01872 if (hKey < (int) sizeof(DATABASE_HEADER)) { 01873 cm_msg(MERROR, "db_delete_key1", "invalid key handle"); 01874 return DB_INVALID_HANDLE; 01875 } 01876 01877 /* lock database at the top level */ 01878 if (level == 0) 01879 db_lock_database(hDB); 01880 01881 pheader = _database[hDB - 1].database_header; 01882 01883 pkey = (KEY *) ((char *) pheader + hKey); 01884 01885 /* check if hKey argument is correct */ 01886 if (!db_validate_hkey(pheader, hKey)) { 01887 db_unlock_database(hDB); 01888 return DB_INVALID_HANDLE; 01889 } 01890 01891 /* check if someone has opened key or parent */ 01892 if (level == 0) 01893 do { 01894 if (pkey->notify_count) { 01895 db_unlock_database(hDB); 01896 return DB_OPEN_RECORD; 01897 } 01898 01899 if (pkey->parent_keylist == 0) 01900 break; 01901 01902 pkeylist = (KEYLIST *) ((char *) pheader + pkey->parent_keylist); 01903 pkey = (KEY *) ((char *) pheader + pkeylist->parent); 01904 } while (TRUE); 01905 01906 pkey = (KEY *) ((char *) pheader + hKey); 01907 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 01908 01909 deny_delete = FALSE; 01910 01911 /* first recures subtree for keys */ 01912 if (pkey->type == TID_KEY && pkeylist->first_key) { 01913 pkey = (KEY *) ((char *) pheader + pkeylist->first_key); 01914 01915 do { 01916 pnext_key = (KEY *) (POINTER_T) pkey->next_key; 01917 01918 status = db_delete_key1(hDB, (POINTER_T) pkey - (POINTER_T) pheader, level + 1, follow_links); 01919 01920 if (status == DB_NO_ACCESS) 01921 deny_delete = TRUE; 01922 01923 if (pnext_key) 01924 pkey = (KEY *) ((char *) pheader + (POINTER_T) pnext_key); 01925 } while (pnext_key); 01926 } 01927 01928 /* follow links if requested */ 01929 if (pkey->type == TID_LINK && follow_links) { 01930 status = db_find_key(hDB, 0, (char *) pheader + pkey->data, &hKeyLink); 01931 if (status == DB_SUCCESS && follow_links < 100) 01932 db_delete_key1(hDB, hKeyLink, level + 1, follow_links + 1); 01933 01934 if (follow_links == 100) 01935 cm_msg(MERROR, "db_delete_key1", "try to delete cyclic link"); 01936 } 01937 01938 pkey = (KEY *) ((char *) pheader + hKey); 01939 01940 /* return if key was already deleted by cyclic link */ 01941 if (pkey->parent_keylist == 0) { 01942 if (level == 0) 01943 db_unlock_database(hDB); 01944 return DB_SUCCESS; 01945 } 01946 01947 /* now delete key */ 01948 if (hKey != pheader->root_key) { 01949 if (!(pkey->access_mode & MODE_DELETE) || deny_delete) { 01950 if (level == 0) 01951 db_unlock_database(hDB); 01952 return DB_NO_ACCESS; 01953 } 01954 01955 if (pkey->notify_count) { 01956 if (level == 0) 01957 db_unlock_database(hDB); 01958 return DB_OPEN_RECORD; 01959 } 01960 01961 /* delete key data */ 01962 if (pkey->type == TID_KEY) 01963 free_key(pheader, (char *) pheader + pkey->data, pkey->total_size); 01964 else 01965 free_data(pheader, (char *) pheader + pkey->data, pkey->total_size); 01966 01967 /* unlink key from list */ 01968 pnext_key = (KEY *) (POINTER_T) pkey->next_key; 01969 pkeylist = (KEYLIST *) ((char *) pheader + pkey->parent_keylist); 01970 01971 if ((KEY *) ((char *) pheader + pkeylist->first_key) == pkey) { 01972 /* key is first in list */ 01973 pkeylist->first_key = (POINTER_T) pnext_key; 01974 } else { 01975 /* find predecessor */ 01976 pkey_tmp = (KEY *) ((char *) pheader + pkeylist->first_key); 01977 while ((KEY *) ((char *) pheader + pkey_tmp->next_key) != pkey) 01978 pkey_tmp = (KEY *) ((char *) pheader + pkey_tmp->next_key); 01979 pkey_tmp->next_key = (POINTER_T) pnext_key; 01980 } 01981 01982 /* delete key */ 01983 free_key(pheader, pkey, sizeof(KEY)); 01984 pkeylist->num_keys--; 01985 } 01986 01987 if (level == 0) 01988 db_unlock_database(hDB); 01989 } 01990 #endif /* LOCAL_ROUTINES */ 01991 01992 return DB_SUCCESS; 01993 }
Enumerate subkeys from a key, follow links.
hkey must correspond to a valid ODB directory. The index is usually incremented in a loop until the last key is reached. Information about the sub-keys can be obtained with db_get_key(). If a returned key is of type TID_KEY, it contains itself sub-keys. To scan a whole ODB sub-tree, the function db_scan_tree() can be used.
INT i; HNDLE hkey, hsubkey; KEY key; db_find_key(hdb, 0, "/Runinfo", &hkey); for (i=0 ; ; i++) { db_enum_key(hdb, hkey, i, &hsubkey); if (!hSubkey) break; // end of list reached // print key name db_get_key(hdb, hkey, &key); printf("%s\n", key.name); }
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
idx | Subkey index, sould be initially 0, then incremented in each call until subhKey becomes zero and the function returns DB_NO_MORE_SUBKEYS | |
subkey_handle | Handle of subkey which can be used in db_get_key() and db_get_data() |
Definition at line 3326 of file odb.c.
Referenced by add_event(), al_check(), ascii_write(), book_ntuples(), build_done_list_odb(), close_history(), cm_connect_client(), cm_exist(), cm_set_client_info(), cm_shutdown(), cm_transition1(), command_loop(), create_experim_h(), db_get_event_definition(), do_jrpc_rev0(), dump_write(), exec_script(), export_hist(), gen_odb_attachment(), generate_hist_graph(), get_event_id(), get_variable_id(), get_variable_id_tags(), MidasHistory::GetEventsFromEquipment(), MidasHistory::GetEventsFromOdbEvents(), MidasHistory::GetEventsFromOdbTags(), MidasHistory::GetTagsFromOdb(), interprete(), load_fragment(), log_callback(), log_system_history(), logger_init(), logger_root(), main(), odb_load(), open_history(), rpc_server_dispatch(), show_cnaf_page(), show_custom_gif(), show_delete_page(), show_odb_page(), show_programs_page(), show_sc_page(), show_start_page(), show_status_page(), tr_start(), update_odb(), write_event_ascii(), write_event_hbook(), and write_event_odb().
03327 { 03328 if (rpc_is_remote()) 03329 return rpc_call(RPC_DB_ENUM_KEY, hDB, hKey, idx, subkey_handle); 03330 03331 #ifdef LOCAL_ROUTINES 03332 { 03333 DATABASE_HEADER *pheader; 03334 KEYLIST *pkeylist; 03335 KEY *pkey; 03336 INT i; 03337 char str[256]; 03338 HNDLE parent; 03339 03340 if (hDB > _database_entries || hDB <= 0) { 03341 cm_msg(MERROR, "db_enum_key", "invalid database handle"); 03342 return DB_INVALID_HANDLE; 03343 } 03344 03345 if (!_database[hDB - 1].attached) { 03346 cm_msg(MERROR, "db_enum_key", "invalid database handle"); 03347 return DB_INVALID_HANDLE; 03348 } 03349 03350 *subkey_handle = 0; 03351 03352 /* first lock database */ 03353 db_lock_database(hDB); 03354 03355 pheader = _database[hDB - 1].database_header; 03356 if (!hKey) 03357 hKey = pheader->root_key; 03358 pkey = (KEY *) ((char *) pheader + hKey); 03359 03360 /* check if hKey argument is correct */ 03361 if (!db_validate_hkey(pheader, hKey)) { 03362 db_unlock_database(hDB); 03363 return DB_INVALID_HANDLE; 03364 } 03365 03366 if (pkey->type != TID_KEY) { 03367 db_unlock_database(hDB); 03368 return DB_NO_MORE_SUBKEYS; 03369 } 03370 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 03371 03372 if (idx >= pkeylist->num_keys) { 03373 db_unlock_database(hDB); 03374 return DB_NO_MORE_SUBKEYS; 03375 } 03376 03377 pkey = (KEY *) ((char *) pheader + pkeylist->first_key); 03378 for (i = 0; i < idx; i++) 03379 pkey = (KEY *) ((char *) pheader + pkey->next_key); 03380 03381 /* resolve links */ 03382 if (pkey->type == TID_LINK) { 03383 strcpy(str, (char *) pheader + pkey->data); 03384 03385 /* no not reolve if link to array index */ 03386 if (strlen(str) > 0 && str[strlen(str) - 1] == ']') { 03387 *subkey_handle = (POINTER_T) pkey - (POINTER_T) pheader; 03388 db_unlock_database(hDB); 03389 return DB_SUCCESS; 03390 } 03391 03392 if (*str == '/') { 03393 /* absolute path */ 03394 db_unlock_database(hDB); 03395 return db_find_key(hDB, 0, str, subkey_handle); 03396 } else { 03397 /* relative path */ 03398 if (pkey->parent_keylist) { 03399 pkeylist = (KEYLIST *) ((char *) pheader + pkey->parent_keylist); 03400 parent = pkeylist->parent; 03401 db_unlock_database(hDB); 03402 return db_find_key(hDB, parent, str, subkey_handle); 03403 } else { 03404 db_unlock_database(hDB); 03405 return db_find_key(hDB, 0, str, subkey_handle); 03406 } 03407 } 03408 } 03409 03410 *subkey_handle = (POINTER_T) pkey - (POINTER_T) pheader; 03411 db_unlock_database(hDB); 03412 } 03413 #endif /* LOCAL_ROUTINES */ 03414 03415 return DB_SUCCESS; 03416 }
INT db_find_key | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | key_name, | |||
HNDLE * | subhKey | |||
) |
Returns key handle for a key with a specific name.
Keys can be accessed by their name including the directory or by a handle. A key handle is an internal offset to the shared memory where the ODB lives and allows a much faster access to a key than via its name.
The function db_find_key() must be used to convert a key name to a handle. Most other database functions use this key handle in various operations.
HNDLE hkey, hsubkey; // use full name, start from root db_find_key(hDB, 0, "/Runinfo/Run number", &hkey); // start from subdirectory db_find_key(hDB, 0, "/Runinfo", &hkey); db_find_key(hdb, hkey, "Run number", &hsubkey);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
key_name | Name of key to search, can contain directories. | |
subhKey | Returned handle of key, zero if key cannot be found. |
Definition at line 2053 of file odb.c.
Referenced by add_data_dir(), add_event(), al_check(), al_reset_alarm(), al_trigger_alarm(), analyzer_init(), banks_changed(), book_ntuples(), build_done_list_odb(), check_web_password(), close_history(), cm_connect_client(), cm_deregister_transition(), cm_exist(), cm_get_client_info(), cm_msg_log(), cm_msg_log1(), cm_msg_retrieve(), cm_register_deferred_transition(), cm_register_transition(), cm_set_client_info(), cm_shutdown(), cm_transition1(), cmd_dir(), command_loop(), condition_test(), create_experim_h(), db_check_record(), db_create_link(), db_create_record(), db_delete_key1(), db_enum_key(), db_get_data(), db_get_event_definition(), db_get_key(), db_get_value(), db_paste(), db_paste_xml(), db_set_data(), db_set_data_index(), db_set_value(), db_set_value_index(), do_jrpc_rev0(), evaluate_src(), export_hist(), frontend_init(), gen_odb_attachment(), generate_hist_graph(), get_event_id(), get_variable_id(), get_variable_id_tags(), MidasHistory::GetEventsFromEquipment(), MidasHistory::GetEventsFromOdbEvents(), MidasHistory::GetEventsFromOdbTags(), MidasHistory::GetTagsFromEquipment(), MidasHistory::GetTagsFromOdb(), MidasHistory::hs_connect(), init_module_parameters(), interprete(), is_editable(), lazy_main(), lazy_maintain_free_space(), load_fragment(), load_parameters(), log_callback(), logger_init(), logger_root(), main(), mana_init(), odb_load(), open_history(), print_key(), register_equipment(), register_requests(), rpc_server_dispatch(), set_equipment_status(), show_alarm_page(), show_cnaf_page(), show_create_page(), show_custom_gif(), show_custom_page(), show_delete_page(), show_elog_new(), show_elog_page(), show_elog_query(), show_find_page(), show_form_query(), show_hist_page(), show_odb_page(), show_odb_tag(), show_programs_page(), show_sc_page(), show_start_page(), show_status_page(), submit_elog(), submit_form(), tr_start(), update_odb(), write_event_odb(), xdb_find_key(), and xdb_get_data_index().
02054 { 02055 if (rpc_is_remote()) 02056 return rpc_call(RPC_DB_FIND_KEY, hDB, hKey, key_name, subhKey); 02057 02058 #ifdef LOCAL_ROUTINES 02059 { 02060 DATABASE_HEADER *pheader; 02061 KEYLIST *pkeylist; 02062 KEY *pkey; 02063 const char *pkey_name; 02064 char str[MAX_STRING_LENGTH]; 02065 INT i, status; 02066 02067 *subhKey = 0; 02068 02069 if (hDB > _database_entries || hDB <= 0) { 02070 cm_msg(MERROR, "db_find_key", "invalid database handle"); 02071 return DB_INVALID_HANDLE; 02072 } 02073 02074 if (!_database[hDB - 1].attached) { 02075 cm_msg(MERROR, "db_find_key", "invalid database handle"); 02076 return DB_INVALID_HANDLE; 02077 } 02078 02079 db_lock_database(hDB); 02080 02081 pheader = _database[hDB - 1].database_header; 02082 02083 if (!hKey) 02084 hKey = pheader->root_key; 02085 02086 pkey = (KEY *) ((char *) pheader + hKey); 02087 02088 /* check if hKey argument is correct */ 02089 if (!db_validate_hkey(pheader, hKey)) { 02090 db_unlock_database(hDB); 02091 return DB_INVALID_HANDLE; 02092 } 02093 02094 if (pkey->type != TID_KEY) { 02095 db_get_path(hDB, hKey, str, sizeof(str)); 02096 cm_msg(MERROR, "db_find_key", "key \"%s\" has no subkeys", str); 02097 *subhKey = 0; 02098 db_unlock_database(hDB); 02099 return DB_NO_KEY; 02100 } 02101 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 02102 02103 if (key_name[0] == 0 || strcmp(key_name, "/") == 0) { 02104 if (!(pkey->access_mode & MODE_READ)) { 02105 *subhKey = 0; 02106 db_unlock_database(hDB); 02107 return DB_NO_ACCESS; 02108 } 02109 02110 *subhKey = (POINTER_T) pkey - (POINTER_T) pheader; 02111 02112 db_unlock_database(hDB); 02113 return DB_SUCCESS; 02114 } 02115 02116 pkey_name = key_name; 02117 do { 02118 /* extract single subkey from key_name */ 02119 pkey_name = extract_key(pkey_name, str, sizeof(str)); 02120 02121 /* strip trailing '[n]' */ 02122 if (strchr(str, '[') && str[strlen(str) - 1] == ']') 02123 *strchr(str, '[') = 0; 02124 02125 /* check if parent or current directory */ 02126 if (strcmp(str, "..") == 0) { 02127 if (pkey->parent_keylist) { 02128 pkeylist = (KEYLIST *) ((char *) pheader + pkey->parent_keylist); 02129 pkey = (KEY *) ((char *) pheader + pkeylist->parent); 02130 } 02131 continue; 02132 } 02133 if (strcmp(str, ".") == 0) 02134 continue; 02135 02136 /* check if key is in keylist */ 02137 pkey = (KEY *) ((char *) pheader + pkeylist->first_key); 02138 02139 for (i = 0; i < pkeylist->num_keys; i++) { 02140 if (pkey->name[0] == 0 || !db_validate_key_offset(pheader, pkey->next_key)) { 02141 cm_msg(MERROR, "db_find_key", 02142 "Warning: database corruption, key %s, next_key 0x%08X", 02143 key_name, pkey->next_key - sizeof(DATABASE_HEADER)); 02144 *subhKey = 0; 02145 db_unlock_database(hDB); 02146 return DB_CORRUPTED; 02147 } 02148 02149 if (equal_ustring(str, pkey->name)) 02150 break; 02151 02152 pkey = (KEY *) ((char *) pheader + pkey->next_key); 02153 } 02154 02155 if (i == pkeylist->num_keys) { 02156 *subhKey = 0; 02157 db_unlock_database(hDB); 02158 return DB_NO_KEY; 02159 } 02160 02161 /* resolve links */ 02162 if (pkey->type == TID_LINK) { 02163 /* copy destination, strip '/' */ 02164 strcpy(str, (char *) pheader + pkey->data); 02165 if (str[strlen(str) - 1] == '/') 02166 str[strlen(str) - 1] = 0; 02167 02168 /* if link is pointer to array index, return link instead of destination */ 02169 if (str[strlen(str) - 1] == ']') 02170 break; 02171 02172 /* append rest of key name if existing */ 02173 if (pkey_name[0]) { 02174 strcat(str, pkey_name); 02175 db_unlock_database(hDB); 02176 return db_find_key(hDB, 0, str, subhKey); 02177 } else { 02178 /* if last key in chain is a link, return its destination */ 02179 db_unlock_database(hDB); 02180 status = db_find_link(hDB, 0, str, subhKey); 02181 if (status == DB_NO_KEY) 02182 return DB_INVALID_LINK; 02183 return status; 02184 } 02185 } 02186 02187 /* key found: check if last in chain */ 02188 if (*pkey_name == '/') { 02189 if (pkey->type != TID_KEY) { 02190 *subhKey = 0; 02191 db_unlock_database(hDB); 02192 return DB_NO_KEY; 02193 } 02194 } 02195 02196 /* descend one level */ 02197 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 02198 02199 } while (*pkey_name == '/' && *(pkey_name + 1)); 02200 02201 *subhKey = (POINTER_T) pkey - (POINTER_T) pheader; 02202 02203 db_unlock_database(hDB); 02204 } 02205 #endif /* LOCAL_ROUTINES */ 02206 02207 return DB_SUCCESS; 02208 }
Get key data from a handle
The function returns single values or whole arrays which are contained in an ODB key. Since the data buffer is of type void, no type checking can be performed by the compiler. Therefore the type has to be explicitly supplied, which is checked against the type stored in the ODB.
HNLDE hkey; INT run_number, size; // get key handle for run number db_find_key(hDB, 0, "/Runinfo/Run number", &hkey); // return run number size = sizeof(run_number); db_get_data(hDB, hkey, &run_number, &size,TID_INT);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer to the return data. | |
buf_size | Size of data buffer. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 4180 of file odb.c.
Referenced by add_data_dir(), add_event(), build_done_list_odb(), check_web_password(), cm_connect_client(), cm_get_client_info(), cm_set_client_info(), command_loop(), db_get_record(), exec_script(), gen_odb_attachment(), get_event_id(), get_variable_id(), MidasHistory::GetEventsFromOdbEvents(), MidasHistory::GetTagsFromOdb(), interprete(), log_system_history(), main(), print_key(), rpc_server_dispatch(), scan_tree(), search_callback(), search_key(), show_custom_page(), show_elog_new(), show_elog_query(), show_form_query(), show_odb_page(), show_sc_page(), show_set_page(), show_start_page(), show_status_page(), submit_elog(), submit_form(), and tr_start().
04181 { 04182 if (rpc_is_remote()) 04183 return rpc_call(RPC_DB_GET_DATA, hDB, hKey, data, buf_size, type); 04184 04185 #ifdef LOCAL_ROUTINES 04186 { 04187 DATABASE_HEADER *pheader; 04188 KEY *pkey; 04189 char str[256]; 04190 04191 if (hDB > _database_entries || hDB <= 0) { 04192 cm_msg(MERROR, "db_get_data", "Invalid database handle"); 04193 return DB_INVALID_HANDLE; 04194 } 04195 04196 if (!_database[hDB - 1].attached) { 04197 cm_msg(MERROR, "db_get_data", "invalid database handle"); 04198 return DB_INVALID_HANDLE; 04199 } 04200 04201 if (hKey < (int) sizeof(DATABASE_HEADER)) { 04202 cm_msg(MERROR, "db_get_data", "invalid key handle"); 04203 return DB_INVALID_HANDLE; 04204 } 04205 04206 db_lock_database(hDB); 04207 04208 pheader = _database[hDB - 1].database_header; 04209 pkey = (KEY *) ((char *) pheader + hKey); 04210 04211 /* check if hKey argument is correct */ 04212 if (!db_validate_hkey(pheader, hKey)) { 04213 db_unlock_database(hDB); 04214 return DB_INVALID_HANDLE; 04215 } 04216 04217 /* check for read access */ 04218 if (!(pkey->access_mode & MODE_READ)) { 04219 db_unlock_database(hDB); 04220 return DB_NO_ACCESS; 04221 } 04222 04223 if (!pkey->type) { 04224 db_unlock_database(hDB); 04225 cm_msg(MERROR, "db_get_data", "invalid key type %d", pkey->type); 04226 return DB_INVALID_HANDLE; 04227 } 04228 04229 /* follow links to array index */ 04230 if (pkey->type == TID_LINK) { 04231 char link_name[256]; 04232 int i; 04233 HNDLE hkey; 04234 KEY key; 04235 04236 strlcpy(link_name, (char *) pheader + pkey->data, sizeof(link_name)); 04237 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] == ']') { 04238 db_unlock_database(hDB); 04239 if (strchr(link_name, '[') == NULL) 04240 return DB_INVALID_LINK; 04241 i = atoi(strchr(link_name, '[') + 1); 04242 *strchr(link_name, '[') = 0; 04243 if (db_find_key(hDB, 0, link_name, &hkey) != DB_SUCCESS) 04244 return DB_INVALID_LINK; 04245 db_get_key(hDB, hkey, &key); 04246 return db_get_data_index(hDB, hkey, data, buf_size, i, key.type); 04247 } 04248 } 04249 04250 if (pkey->type != type) { 04251 db_unlock_database(hDB); 04252 db_get_path(hDB, hKey, str, sizeof(str)); 04253 cm_msg(MERROR, "db_get_data", "\"%s\" is of type %s, not %s", 04254 str, rpc_tid_name(pkey->type), rpc_tid_name(type)); 04255 return DB_TYPE_MISMATCH; 04256 } 04257 04258 /* keys cannot contain data */ 04259 if (pkey->type == TID_KEY) { 04260 db_unlock_database(hDB); 04261 db_get_path(hDB, hKey, str, sizeof(str)); 04262 cm_msg(MERROR, "db_get_data", "Key \"%s\" cannot contain data", str); 04263 return DB_TYPE_MISMATCH; 04264 } 04265 04266 /* check if key has data */ 04267 if (pkey->data == 0) { 04268 memset(data, 0, *buf_size); 04269 *buf_size = 0; 04270 db_unlock_database(hDB); 04271 return DB_SUCCESS; 04272 } 04273 04274 /* check if buffer is too small */ 04275 if (pkey->num_values * pkey->item_size > *buf_size) { 04276 memcpy(data, (char *) pheader + pkey->data, *buf_size); 04277 db_unlock_database(hDB); 04278 db_get_path(hDB, hKey, str, sizeof(str)); 04279 cm_msg(MERROR, "db_get_data", "data for key \"%s\" truncated", str); 04280 return DB_TRUNCATED; 04281 } 04282 04283 /* copy key data */ 04284 memcpy(data, (char *) pheader + pkey->data, pkey->num_values * pkey->item_size); 04285 *buf_size = pkey->num_values * pkey->item_size; 04286 04287 db_unlock_database(hDB); 04288 04289 } 04290 #endif /* LOCAL_ROUTINES */ 04291 04292 return DB_SUCCESS; 04293 }
returns a single value of keys containing arrays of values.
The function returns a single value of keys containing arrays of values.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Size of data buffer. | |
buf_size | Return size of the record. | |
idx | Index of array [0..n-1]. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 4531 of file odb.c.
Referenced by cm_transition1(), condition_test(), db_get_data(), export_hist(), gen_odb_attachment(), generate_hist_graph(), get_variable_id_tags(), MidasHistory::GetEventsFromOdbTags(), MidasHistory::GetTagsFromEquipment(), MidasHistory::GetTagsFromOdb(), is_editable(), open_history(), rpc_server_dispatch(), show_custom_gif(), show_custom_page(), show_elog_page(), show_hist_page(), show_odb_page(), show_odb_tag(), show_sc_page(), and xdb_get_data_index().
04532 { 04533 if (rpc_is_remote()) 04534 return rpc_call(RPC_DB_GET_DATA_INDEX, hDB, hKey, data, buf_size, idx, type); 04535 04536 #ifdef LOCAL_ROUTINES 04537 { 04538 DATABASE_HEADER *pheader; 04539 KEY *pkey; 04540 char str[256]; 04541 04542 if (hDB > _database_entries || hDB <= 0) { 04543 cm_msg(MERROR, "db_get_data", "Invalid database handle"); 04544 return DB_INVALID_HANDLE; 04545 } 04546 04547 if (!_database[hDB - 1].attached) { 04548 cm_msg(MERROR, "db_get_data", "invalid database handle"); 04549 return DB_INVALID_HANDLE; 04550 } 04551 04552 if (hKey < (int) sizeof(DATABASE_HEADER)) { 04553 cm_msg(MERROR, "db_get_data", "invalid key handle"); 04554 return DB_INVALID_HANDLE; 04555 } 04556 04557 db_lock_database(hDB); 04558 04559 pheader = _database[hDB - 1].database_header; 04560 pkey = (KEY *) ((char *) pheader + hKey); 04561 04562 /* check if hKey argument is correct */ 04563 if (!db_validate_hkey(pheader, hKey)) { 04564 db_unlock_database(hDB); 04565 return DB_INVALID_HANDLE; 04566 } 04567 04568 /* check for read access */ 04569 if (!(pkey->access_mode & MODE_READ)) { 04570 db_unlock_database(hDB); 04571 return DB_NO_ACCESS; 04572 } 04573 04574 if (!pkey->type) { 04575 db_unlock_database(hDB); 04576 cm_msg(MERROR, "db_get_data_index", "invalid key type %d", pkey->type); 04577 return DB_INVALID_HANDLE; 04578 } 04579 04580 if (pkey->type != type) { 04581 db_unlock_database(hDB); 04582 cm_msg(MERROR, "db_get_data_index", 04583 "\"%s\" is of type %s, not %s", pkey->name, rpc_tid_name(pkey->type), rpc_tid_name(type)); 04584 return DB_TYPE_MISMATCH; 04585 } 04586 04587 /* keys cannot contain data */ 04588 if (pkey->type == TID_KEY) { 04589 db_unlock_database(hDB); 04590 cm_msg(MERROR, "db_get_data_index", "Key cannot contain data"); 04591 return DB_TYPE_MISMATCH; 04592 } 04593 04594 /* check if key has data */ 04595 if (pkey->data == 0) { 04596 memset(data, 0, *buf_size); 04597 *buf_size = 0; 04598 db_unlock_database(hDB); 04599 return DB_SUCCESS; 04600 } 04601 04602 /* check if index in range */ 04603 if (idx < 0 || idx >= pkey->num_values) { 04604 memset(data, 0, *buf_size); 04605 db_unlock_database(hDB); 04606 04607 db_get_path(hDB, hKey, str, sizeof(str)); 04608 cm_msg(MERROR, "db_get_data_index", 04609 "index (%d) exceeds array length (%d) for key \"%s\"", idx, pkey->num_values, str); 04610 return DB_OUT_OF_RANGE; 04611 } 04612 04613 /* check if buffer is too small */ 04614 if (pkey->item_size > *buf_size) { 04615 /* copy data */ 04616 memcpy(data, (char *) pheader + pkey->data + idx * pkey->item_size, *buf_size); 04617 db_unlock_database(hDB); 04618 cm_msg(MERROR, "db_get_data_index", "data for key \"%s\" truncated", pkey->name); 04619 return DB_TRUNCATED; 04620 } 04621 04622 /* copy key data */ 04623 memcpy(data, (char *) pheader + pkey->data + idx * pkey->item_size, pkey->item_size); 04624 *buf_size = pkey->item_size; 04625 04626 db_unlock_database(hDB); 04627 04628 } 04629 #endif /* LOCAL_ROUTINES */ 04630 04631 return DB_SUCCESS; 04632 }
Get key structure from a handle.
KEY structure has following format:
typedef struct { DWORD type; // TID_xxx type INT num_values; // number of values char name[NAME_LENGTH]; // name of variable INT data; // Address of variable (offset) INT total_size; // Total size of data block INT item_size; // Size of single data item WORD access_mode; // Access mode WORD notify_count; // Notify counter INT next_key; // Address of next key INT parent_keylist; // keylist to which this key belongs INT last_written; // Time of last write action } KEY;
KEY key; HNDLE hkey; db_find_key(hDB, 0, "/Runinfo/Run number", &hkey); db_get_key(hDB, hkey, &key); printf("The run number is of type %s\n", rpc_tid_name(key.type));
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
key | Pointer to KEY stucture. |
Definition at line 3665 of file odb.c.
Referenced by add_event(), al_check(), al_reset_alarm(), ascii_write(), book_ntuples(), build_done_list(), build_done_list_odb(), cm_check_client(), cm_register_transition(), cm_shutdown(), cm_transition1(), command_loop(), condition_test(), convert_done_list(), create_experim_h(), db_check_record(), db_get_data(), db_get_record(), db_get_record_size(), db_open_record(), db_paste(), db_save_struct(), db_set_record(), del_tree(), dump_write(), evaluate_src(), exec_script(), export_hist(), gen_odb_attachment(), generate_hist_graph(), get_event_id(), get_variable_id(), get_variable_id_tags(), MidasHistory::GetEventsFromEquipment(), MidasHistory::GetEventsFromOdbTags(), MidasHistory::GetTagsFromEquipment(), MidasHistory::GetTagsFromOdb(), interprete(), is_editable(), load_fragment(), load_parameters(), log_system_history(), logger_init(), main(), open_history(), print_key(), rpc_server_dispatch(), save_done_list(), scan_tree(), show_alarm_page(), show_create_page(), show_custom_gif(), show_custom_page(), show_elog_new(), show_elog_page(), show_elog_query(), show_form_query(), show_hist_page(), show_odb_page(), show_odb_tag(), show_programs_page(), show_sc_page(), show_set_page(), show_start_page(), show_status_page(), submit_form(), tr_start(), update_odb(), write_event_ascii(), write_event_hbook(), write_event_odb(), and xdb_get_data_index().
03666 { 03667 if (rpc_is_remote()) 03668 return rpc_call(RPC_DB_GET_KEY, hDB, hKey, key); 03669 03670 #ifdef LOCAL_ROUTINES 03671 { 03672 DATABASE_HEADER *pheader; 03673 KEY *pkey; 03674 HNDLE hkeylink; 03675 char link_name[256]; 03676 03677 if (hDB > _database_entries || hDB <= 0) { 03678 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03679 return DB_INVALID_HANDLE; 03680 } 03681 03682 if (!_database[hDB - 1].attached) { 03683 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03684 return DB_INVALID_HANDLE; 03685 } 03686 03687 if (hKey < (int) sizeof(DATABASE_HEADER) && hKey != 0) { 03688 cm_msg(MERROR, "db_get_key", "invalid key handle"); 03689 return DB_INVALID_HANDLE; 03690 } 03691 03692 db_lock_database(hDB); 03693 03694 pheader = _database[hDB - 1].database_header; 03695 03696 if (!hKey) 03697 hKey = pheader->root_key; 03698 03699 pkey = (KEY *) ((char *) pheader + hKey); 03700 03701 /* check if hKey argument is correct */ 03702 if (!db_validate_hkey(pheader, hKey)) { 03703 db_unlock_database(hDB); 03704 return DB_INVALID_HANDLE; 03705 } 03706 03707 if (!pkey->type) { 03708 db_unlock_database(hDB); 03709 cm_msg(MERROR, "db_get_key", "invalid key type %d", pkey->type); 03710 return DB_INVALID_HANDLE; 03711 } 03712 03713 /* check for link to array index */ 03714 if (pkey->type == TID_LINK) { 03715 strlcpy(link_name, (char *) pheader + pkey->data, sizeof(link_name)); 03716 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] == ']') { 03717 db_unlock_database(hDB); 03718 if (strchr(link_name, '[') == NULL) 03719 return DB_INVALID_LINK; 03720 if (db_find_key(hDB, 0, link_name, &hkeylink) != DB_SUCCESS) 03721 return DB_INVALID_LINK; 03722 db_get_key(hDB, hkeylink, key); 03723 key->num_values = 1; // fake number of values 03724 return DB_SUCCESS; 03725 } 03726 } 03727 03728 memcpy(key, pkey, sizeof(KEY)); 03729 03730 db_unlock_database(hDB); 03731 03732 } 03733 #endif /* LOCAL_ROUTINES */ 03734 03735 return DB_SUCCESS; 03736 }
INT db_get_key_info | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
char * | name, | |||
INT | name_size, | |||
INT * | type, | |||
INT * | num_values, | |||
INT * | item_size | |||
) |
Get key info (separate values instead of structure)
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle of key to operate on | |
name | Key name | |
name_size | Size of the give name (done with sizeof()) | |
type | Key type (see Midas Data Types). | |
num_values | Number of values in key. | |
item_size | Size of individual key value (used for strings) |
Definition at line 3868 of file odb.c.
Referenced by rpc_server_dispatch().
03869 { 03870 if (rpc_is_remote()) 03871 return rpc_call(RPC_DB_GET_KEY_INFO, hDB, hKey, name, name_size, type, num_values, item_size); 03872 03873 #ifdef LOCAL_ROUTINES 03874 { 03875 DATABASE_HEADER *pheader; 03876 KEY *pkey; 03877 KEYLIST *pkeylist; 03878 03879 if (hDB > _database_entries || hDB <= 0) { 03880 cm_msg(MERROR, "db_get_key_info", "invalid database handle"); 03881 return DB_INVALID_HANDLE; 03882 } 03883 03884 if (!_database[hDB - 1].attached) { 03885 cm_msg(MERROR, "db_get_key_info", "invalid database handle"); 03886 return DB_INVALID_HANDLE; 03887 } 03888 03889 if (hKey < (int) sizeof(DATABASE_HEADER)) { 03890 cm_msg(MERROR, "db_get_key_info", "invalid key handle"); 03891 return DB_INVALID_HANDLE; 03892 } 03893 03894 db_lock_database(hDB); 03895 03896 pheader = _database[hDB - 1].database_header; 03897 pkey = (KEY *) ((char *) pheader + hKey); 03898 03899 /* check if hKey argument is correct */ 03900 if (!db_validate_hkey(pheader, hKey)) { 03901 db_unlock_database(hDB); 03902 return DB_INVALID_HANDLE; 03903 } 03904 03905 if ((INT) strlen(pkey->name) + 1 > name_size) { 03906 /* truncate name */ 03907 memcpy(name, pkey->name, name_size - 1); 03908 name[name_size] = 0; 03909 } else 03910 strcpy(name, pkey->name); 03911 03912 /* convert "root" to "/" */ 03913 if (strcmp(name, "root") == 0) 03914 strcpy(name, "/"); 03915 03916 *type = pkey->type; 03917 *num_values = pkey->num_values; 03918 *item_size = pkey->item_size; 03919 03920 if (pkey->type == TID_KEY) { 03921 pkeylist = (KEYLIST *) ((char *) pheader + pkey->data); 03922 *num_values = pkeylist->num_keys; 03923 } 03924 03925 db_unlock_database(hDB); 03926 } 03927 #endif /* LOCAL_ROUTINES */ 03928 03929 return DB_SUCCESS; 03930 }
Get time when key was last modified
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle of key to operate on | |
delta | Seconds since last update |
Definition at line 3810 of file odb.c.
Referenced by print_key(), rpc_server_dispatch(), and scan_tree().
03811 { 03812 if (rpc_is_remote()) 03813 return rpc_call(RPC_DB_GET_KEY_TIME, hDB, hKey, delta); 03814 03815 #ifdef LOCAL_ROUTINES 03816 { 03817 DATABASE_HEADER *pheader; 03818 KEY *pkey; 03819 03820 if (hDB > _database_entries || hDB <= 0) { 03821 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03822 return DB_INVALID_HANDLE; 03823 } 03824 03825 if (!_database[hDB - 1].attached) { 03826 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03827 return DB_INVALID_HANDLE; 03828 } 03829 03830 if (hKey < (int) sizeof(DATABASE_HEADER)) { 03831 cm_msg(MERROR, "db_get_key", "invalid key handle"); 03832 return DB_INVALID_HANDLE; 03833 } 03834 03835 db_lock_database(hDB); 03836 03837 pheader = _database[hDB - 1].database_header; 03838 pkey = (KEY *) ((char *) pheader + hKey); 03839 03840 /* check if hKey argument is correct */ 03841 if (!db_validate_hkey(pheader, hKey)) { 03842 db_unlock_database(hDB); 03843 return DB_INVALID_HANDLE; 03844 } 03845 03846 *delta = ss_time() - pkey->last_written; 03847 03848 db_unlock_database(hDB); 03849 03850 } 03851 #endif /* LOCAL_ROUTINES */ 03852 03853 return DB_SUCCESS; 03854 }
Same as db_get_key, but it does not follow a link to an array index
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
key | Pointer to KEY stucture. |
Definition at line 3746 of file odb.c.
Referenced by cmd_dir(), command_loop(), db_copy(), db_save_xml_key(), rpc_server_dispatch(), set_key(), show_delete_page(), show_odb_page(), and show_start_page().
03747 { 03748 if (rpc_is_remote()) 03749 return rpc_call(RPC_DB_GET_LINK, hDB, hKey, key); 03750 03751 #ifdef LOCAL_ROUTINES 03752 { 03753 DATABASE_HEADER *pheader; 03754 KEY *pkey; 03755 03756 if (hDB > _database_entries || hDB <= 0) { 03757 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03758 return DB_INVALID_HANDLE; 03759 } 03760 03761 if (!_database[hDB - 1].attached) { 03762 cm_msg(MERROR, "db_get_key", "invalid database handle"); 03763 return DB_INVALID_HANDLE; 03764 } 03765 03766 if (hKey < (int) sizeof(DATABASE_HEADER) && hKey != 0) { 03767 cm_msg(MERROR, "db_get_key", "invalid key handle"); 03768 return DB_INVALID_HANDLE; 03769 } 03770 03771 db_lock_database(hDB); 03772 03773 pheader = _database[hDB - 1].database_header; 03774 03775 if (!hKey) 03776 hKey = pheader->root_key; 03777 03778 pkey = (KEY *) ((char *) pheader + hKey); 03779 03780 /* check if hKey argument is correct */ 03781 if (!db_validate_hkey(pheader, hKey)) { 03782 db_unlock_database(hDB); 03783 return DB_INVALID_HANDLE; 03784 } 03785 03786 if (!pkey->type) { 03787 db_unlock_database(hDB); 03788 cm_msg(MERROR, "db_get_key", "invalid key type %d", pkey->type); 03789 return DB_INVALID_HANDLE; 03790 } 03791 03792 memcpy(key, pkey, sizeof(KEY)); 03793 03794 db_unlock_database(hDB); 03795 03796 } 03797 #endif /* LOCAL_ROUTINES */ 03798 03799 return DB_SUCCESS; 03800 }
Same as db_get_data, but do not follow a link to an array index
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer to the return data. | |
buf_size | Size of data buffer. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 4306 of file odb.c.
Referenced by cmd_dir(), db_copy(), db_save_xml_key(), print_key(), rpc_server_dispatch(), and show_odb_page().
04307 { 04308 if (rpc_is_remote()) 04309 return rpc_call(RPC_DB_GET_LINK_DATA, hDB, hKey, data, buf_size, type); 04310 04311 #ifdef LOCAL_ROUTINES 04312 { 04313 DATABASE_HEADER *pheader; 04314 KEY *pkey; 04315 04316 if (hDB > _database_entries || hDB <= 0) { 04317 cm_msg(MERROR, "db_get_data", "Invalid database handle"); 04318 return DB_INVALID_HANDLE; 04319 } 04320 04321 if (!_database[hDB - 1].attached) { 04322 cm_msg(MERROR, "db_get_data", "invalid database handle"); 04323 return DB_INVALID_HANDLE; 04324 } 04325 04326 if (hKey < (int) sizeof(DATABASE_HEADER)) { 04327 cm_msg(MERROR, "db_get_data", "invalid key handle"); 04328 return DB_INVALID_HANDLE; 04329 } 04330 04331 db_lock_database(hDB); 04332 04333 pheader = _database[hDB - 1].database_header; 04334 pkey = (KEY *) ((char *) pheader + hKey); 04335 04336 /* check if hKey argument is correct */ 04337 if (!db_validate_hkey(pheader, hKey)) { 04338 db_unlock_database(hDB); 04339 return DB_INVALID_HANDLE; 04340 } 04341 04342 /* check for read access */ 04343 if (!(pkey->access_mode & MODE_READ)) { 04344 db_unlock_database(hDB); 04345 return DB_NO_ACCESS; 04346 } 04347 04348 if (!pkey->type) { 04349 db_unlock_database(hDB); 04350 cm_msg(MERROR, "db_get_data", "invalid key type %d", pkey->type); 04351 return DB_INVALID_HANDLE; 04352 } 04353 04354 if (pkey->type != type) { 04355 db_unlock_database(hDB); 04356 cm_msg(MERROR, "db_get_data", "\"%s\" is of type %s, not %s", 04357 pkey->name, rpc_tid_name(pkey->type), rpc_tid_name(type)); 04358 return DB_TYPE_MISMATCH; 04359 } 04360 04361 /* keys cannot contain data */ 04362 if (pkey->type == TID_KEY) { 04363 db_unlock_database(hDB); 04364 cm_msg(MERROR, "db_get_data", "Key cannot contain data"); 04365 return DB_TYPE_MISMATCH; 04366 } 04367 04368 /* check if key has data */ 04369 if (pkey->data == 0) { 04370 memset(data, 0, *buf_size); 04371 *buf_size = 0; 04372 db_unlock_database(hDB); 04373 return DB_SUCCESS; 04374 } 04375 04376 /* check if buffer is too small */ 04377 if (pkey->num_values * pkey->item_size > *buf_size) { 04378 memcpy(data, (char *) pheader + pkey->data, *buf_size); 04379 db_unlock_database(hDB); 04380 cm_msg(MERROR, "db_get_data", "data for key \"%s\" truncated", pkey->name); 04381 return DB_TRUNCATED; 04382 } 04383 04384 /* copy key data */ 04385 memcpy(data, (char *) pheader + pkey->data, pkey->num_values * pkey->item_size); 04386 *buf_size = pkey->num_values * pkey->item_size; 04387 04388 db_unlock_database(hDB); 04389 04390 } 04391 #endif /* LOCAL_ROUTINES */ 04392 04393 return DB_SUCCESS; 04394 }
INT db_get_lock_cnt | ( | HNDLE | hDB | ) |
Definition at line 1497 of file odb.c.
01498 { 01499 #ifdef LOCAL_ROUTINES 01500 01501 /* return zero if no ODB is open or we run remotely */ 01502 if (_database_entries == 0) 01503 return 0; 01504 01505 if (hDB > _database_entries || hDB <= 0) { 01506 cm_msg(MERROR, "db_lock_database", "invalid database handle, aborting..."); 01507 abort(); 01508 return DB_INVALID_HANDLE; 01509 } 01510 01511 return _database[hDB - 1].lock_cnt; 01512 #else 01513 return 0; 01514 #endif 01515 }
Copy a set of keys to local memory.
An ODB sub-tree can be mapped to a C structure automatically via a hot-link using the function db_open_record() or manually with this function. Problems might occur if the ODB sub-tree contains values which don't match the C structure. Although the structure size is checked against the sub-tree size, no checking can be done if the type and order of the values in the structure are the same than those in the ODB sub-tree. Therefore it is recommended to use the function db_create_record() before db_get_record() is used which ensures that both are equivalent.
struct { INT level1; INT level2; } trigger_settings; char *trigger_settings_str = "[Settings]\n\ level1 = INT : 0\n\ level2 = INT : 0"; main() { HNDLE hDB, hkey; INT size; ... cm_get_experiment_database(&hDB, NULL); db_create_record(hDB, 0, "/Equipment/Trigger", trigger_settings_str); db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hkey); size = sizeof(trigger_settings); db_get_record(hDB, hkey, &trigger_settings, &size, 0); ... }
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer to the retrieved data. | |
buf_size | Size of data structure, must be obtained via sizeof(RECORD-NAME). | |
align | Byte alignment calculated by the stub and passed to the rpc side to align data according to local machine. Must be zero when called from user level. |
Definition at line 7486 of file odb.c.
Referenced by al_check(), al_reset_alarm(), al_trigger_alarm(), cm_transition1(), db_open_record(), db_update_record(), main(), register_equipment(), rpc_server_dispatch(), show_custom_gif(), show_status_page(), and tr_start().
07487 { 07488 if (rpc_is_remote()) { 07489 align = ss_get_struct_align(); 07490 return rpc_call(RPC_DB_GET_RECORD, hDB, hKey, data, buf_size, align); 07491 } 07492 #ifdef LOCAL_ROUTINES 07493 { 07494 KEY key; 07495 INT convert_flags, status; 07496 INT total_size; 07497 void *pdata; 07498 char str[256]; 07499 07500 convert_flags = 0; 07501 07502 if (!align) 07503 align = ss_get_struct_align(); 07504 else 07505 /* only convert data if called remotely, as indicated by align != 0 */ 07506 if (rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE) 07507 convert_flags = rpc_get_server_option(RPC_CONVERT_FLAGS); 07508 07509 /* check if key has subkeys */ 07510 status = db_get_key(hDB, hKey, &key); 07511 if (status != DB_SUCCESS) 07512 return status; 07513 07514 if (key.type != TID_KEY) { 07515 /* copy single key */ 07516 if (key.item_size * key.num_values != *buf_size) { 07517 cm_msg(MERROR, "db_get_record", "struct size mismatch for \"%s\"", key.name); 07518 return DB_STRUCT_SIZE_MISMATCH; 07519 } 07520 07521 db_get_data(hDB, hKey, data, buf_size, key.type); 07522 07523 if (convert_flags) { 07524 if (key.num_values > 1) 07525 rpc_convert_data(data, key.type, 07526 RPC_OUTGOING | RPC_FIXARRAY, key.item_size * key.num_values, convert_flags); 07527 else 07528 rpc_convert_single(data, key.type, RPC_OUTGOING, convert_flags); 07529 } 07530 07531 return DB_SUCCESS; 07532 } 07533 07534 /* check record size */ 07535 db_get_record_size(hDB, hKey, 0, &total_size); 07536 if (total_size != *buf_size) { 07537 db_get_path(hDB, hKey, str, sizeof(str)); 07538 cm_msg(MERROR, "db_get_record", 07539 "struct size mismatch for \"%s\" (expected size: %d, size in ODB: %d)", str, *buf_size, total_size); 07540 return DB_STRUCT_SIZE_MISMATCH; 07541 } 07542 07543 /* get subkey data */ 07544 pdata = data; 07545 total_size = 0; 07546 07547 db_lock_database(hDB); 07548 db_recurse_record_tree(hDB, hKey, &pdata, &total_size, align, NULL, FALSE, convert_flags); 07549 db_unlock_database(hDB); 07550 07551 } 07552 #endif /* LOCAL_ROUTINES */ 07553 07554 return DB_SUCCESS; 07555 }
Calculates the size of a record.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
align | Byte alignment calculated by the stub and passed to the rpc side to align data according to local machine. Must be zero when called from user level | |
buf_size | Size of record structure |
Definition at line 7400 of file odb.c.
Referenced by add_event(), command_loop(), db_get_record(), db_open_record(), db_set_record(), init_module_parameters(), log_history(), open_history(), rpc_server_dispatch(), and show_status_page().
07401 { 07402 if (rpc_is_remote()) { 07403 align = ss_get_struct_align(); 07404 return rpc_call(RPC_DB_GET_RECORD_SIZE, hDB, hKey, align, buf_size); 07405 } 07406 #ifdef LOCAL_ROUTINES 07407 { 07408 KEY key; 07409 INT status, max_align; 07410 07411 if (!align) 07412 align = ss_get_struct_align(); 07413 07414 /* check if key has subkeys */ 07415 status = db_get_key(hDB, hKey, &key); 07416 if (status != DB_SUCCESS) 07417 return status; 07418 07419 if (key.type != TID_KEY) { 07420 /* just a single key */ 07421 *buf_size = key.item_size * key.num_values; 07422 return DB_SUCCESS; 07423 } 07424 07425 db_lock_database(hDB); 07426 07427 /* determine record size */ 07428 *buf_size = max_align = 0; 07429 db_recurse_record_tree(hDB, hKey, NULL, buf_size, align, &max_align, 0, 0); 07430 07431 /* correct for byte padding */ 07432 *buf_size = VALIGN(*buf_size, max_align); 07433 07434 db_unlock_database(hDB); 07435 } 07436 #endif /* LOCAL_ROUTINES */ 07437 07438 return DB_SUCCESS; 07439 }
INT db_get_value | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
const char * | key_name, | |||
void * | data, | |||
INT * | buf_size, | |||
DWORD | type, | |||
BOOL | create | |||
) |
Get value of a single key.
The function returns single values or whole arrays which are contained in an ODB key. Since the data buffer is of type void, no type checking can be performed by the compiler. Therefore the type has to be explicitly supplied, which is checked against the type stored in the ODB. key_name can contain the full path of a key (like: "/Equipment/Trigger/Settings/Level1") while hkey is zero which refers to the root, or hkey can refer to a sub-directory (like: /Equipment/Trigger) and key_name is interpreted relative to that directory like "Settings/Level1".
INT level1, size; size = sizeof(level1); db_get_value(hDB, 0, "/Equipment/Trigger/Settings/Level1", &level1, &size, TID_INT, 0);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
key_name | Name of key to search, can contain directories. | |
data | Address of data. | |
buf_size | Maximum buffer size on input, number of written bytes on return. | |
type | Type of key, one of TID_xxx (see Midas Data Types) | |
create | If TRUE, create key if not existing |
Definition at line 3174 of file odb.c.
Referenced by add_event(), al_check(), al_trigger_alarm(), ana_end_of_run(), assemble_prompt(), bm_open_buffer(), book_ntuples(), bor(), cm_check_client(), cm_connect_experiment1(), cm_exist(), cm_msg_log(), cm_msg_log1(), cm_msg_retrieve(), cm_register_deferred_transition(), cm_set_client_info(), cm_shutdown(), cm_transition1(), command_loop(), create_experim_h(), db_get_event_definition(), do_jrpc_rev0(), el_submit(), evaluate_src(), export_hist(), gen_odb_attachment(), generate_hist_graph(), get_elog_url(), MidasHistory::GetEventsFromEquipment(), MidasHistory::hs_connect(), interprete(), lazy_main(), lazy_maintain_check(), lazy_select_purge(), lazy_settings_hotlink(), load_fragment(), log_callback(), log_generate_file_name(), log_write(), logger_init(), logger_root(), main(), odb_load(), odb_save(), open_history(), read_state(), register_equipment(), rpc_server_dispatch(), set_history_path(), show_alarm_page(), show_cnaf_page(), show_custom_gif(), show_custom_page(), show_elog_delete(), show_elog_new(), show_elog_page(), show_elog_query(), show_elog_submit_query(), show_form_query(), show_header(), show_hist_config_page(), show_hist_page(), show_messages_page(), show_programs_page(), show_rawfile(), show_start_page(), show_status_page(), start_the_run(), stop_the_run(), submit_elog(), tr_start(), tr_start_fal(), tr_stop(), and tr_stop_fal().
03175 { 03176 if (rpc_is_remote()) 03177 return rpc_call(RPC_DB_GET_VALUE, hDB, hKeyRoot, key_name, data, buf_size, type, create); 03178 03179 #ifdef LOCAL_ROUTINES 03180 { 03181 DATABASE_HEADER *pheader; 03182 HNDLE hkey; 03183 KEY *pkey; 03184 INT status, size, idx; 03185 char *p, path[256], keyname[256]; 03186 03187 if (hDB > _database_entries || hDB <= 0) { 03188 cm_msg(MERROR, "db_get_value", "invalid database handle"); 03189 return DB_INVALID_HANDLE; 03190 } 03191 03192 if (!_database[hDB - 1].attached) { 03193 cm_msg(MERROR, "db_get_value", "invalid database handle"); 03194 return DB_INVALID_HANDLE; 03195 } 03196 03197 /* check if key name contains index */ 03198 strlcpy(keyname, key_name, sizeof(keyname)); 03199 idx = -1; 03200 if (strchr(keyname, '[') && strchr(keyname, ']')) { 03201 for (p = strchr(keyname, '[') + 1; *p && *p != ']'; p++) 03202 if (!isdigit(*p)) 03203 break; 03204 03205 if (*p && *p == ']') { 03206 idx = atoi(strchr(keyname, '[') + 1); 03207 *strchr(keyname, '[') = 0; 03208 } 03209 } 03210 03211 status = db_find_key(hDB, hKeyRoot, keyname, &hkey); 03212 if (status == DB_NO_KEY) { 03213 if (create) { 03214 db_create_key(hDB, hKeyRoot, keyname, type); 03215 status = db_find_key(hDB, hKeyRoot, keyname, &hkey); 03216 if (status != DB_SUCCESS) 03217 return status; 03218 03219 /* get string size from data size */ 03220 if (type == TID_STRING || type == TID_LINK) 03221 size = *buf_size; 03222 else 03223 size = rpc_tid_size(type); 03224 03225 if (size == 0) 03226 return DB_TYPE_MISMATCH; 03227 03228 /* set default value if key was created */ 03229 status = db_set_value(hDB, hKeyRoot, keyname, data, *buf_size, *buf_size / size, type); 03230 } else 03231 return DB_NO_KEY; 03232 } 03233 03234 if (status != DB_SUCCESS) 03235 return status; 03236 03237 /* now lock database */ 03238 db_lock_database(hDB); 03239 pheader = _database[hDB - 1].database_header; 03240 03241 /* get address from handle */ 03242 pkey = (KEY *) ((char *) pheader + hkey); 03243 03244 /* check for correct type */ 03245 if (pkey->type != (type)) { 03246 db_unlock_database(hDB); 03247 cm_msg(MERROR, "db_get_value", "\"%s\" is of type %s, not %s", 03248 keyname, rpc_tid_name(pkey->type), rpc_tid_name(type)); 03249 return DB_TYPE_MISMATCH; 03250 } 03251 03252 /* check for read access */ 03253 if (!(pkey->access_mode & MODE_READ)) { 03254 db_unlock_database(hDB); 03255 cm_msg(MERROR, "db_get_value", "%s has no read access", keyname); 03256 return DB_NO_ACCESS; 03257 } 03258 03259 /* check if buffer is too small */ 03260 if ((idx == -1 && pkey->num_values * pkey->item_size > *buf_size) || (idx != -1 && pkey->item_size > *buf_size)) { 03261 memcpy(data, (char *) pheader + pkey->data, *buf_size); 03262 db_unlock_database(hDB); 03263 db_get_path(hDB, hkey, path, sizeof(path)); 03264 cm_msg(MERROR, "db_get_value", "buffer too small, data truncated for key \"%s\"", path); 03265 return DB_TRUNCATED; 03266 } 03267 03268 /* check if index in boundaries */ 03269 if (idx != -1 && idx >= pkey->num_values) { 03270 db_unlock_database(hDB); 03271 db_get_path(hDB, hkey, path, sizeof(path)); 03272 cm_msg(MERROR, "db_get_value", "invalid index \"%d\" for key \"%s\"", idx, path); 03273 return DB_INVALID_PARAM; 03274 } 03275 03276 /* copy key data */ 03277 if (idx == -1) { 03278 memcpy(data, (char *) pheader + pkey->data, pkey->num_values * pkey->item_size); 03279 *buf_size = pkey->num_values * pkey->item_size; 03280 } else { 03281 memcpy(data, (char *) pheader + pkey->data + idx * pkey->item_size, pkey->item_size); 03282 *buf_size = pkey->item_size; 03283 } 03284 03285 db_unlock_database(hDB); 03286 } 03287 #endif /* LOCAL_ROUTINES */ 03288 03289 return DB_SUCCESS; 03290 }
Load a branch of a database from an .ODB file.
This function is used by the ODBEdit command load. For a description of the ASCII format, see db_copy(). Data can be loaded relative to the root of the ODB (hkey equal zero) or relative to a certain key.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
filename | Filename of .ODB file. | |
bRemote | If TRUE, the file is loaded by the server process on the back-end, if FALSE, it is loaded from the current process |
Definition at line 5547 of file odb.c.
Referenced by command_loop(), load_parameters(), and rpc_server_dispatch().
05548 { 05549 struct stat stat_buf; 05550 INT hfile, size, n, i, status; 05551 char *buffer; 05552 05553 if (rpc_is_remote() && bRemote) 05554 return rpc_call(RPC_DB_LOAD, hDB, hKeyRoot, filename); 05555 05556 /* open file */ 05557 hfile = open(filename, O_RDONLY | O_TEXT, 0644); 05558 if (hfile == -1) { 05559 cm_msg(MERROR, "db_load", "file \"%s\" not found", filename); 05560 return DB_FILE_ERROR; 05561 } 05562 05563 /* allocate buffer with file size */ 05564 fstat(hfile, &stat_buf); 05565 size = stat_buf.st_size; 05566 buffer = (char *) malloc(size + 1); 05567 05568 if (buffer == NULL) { 05569 cm_msg(MERROR, "db_load", "cannot allocate ODB load buffer"); 05570 close(hfile); 05571 return DB_NO_MEMORY; 05572 } 05573 05574 n = 0; 05575 05576 do { 05577 i = read(hfile, buffer + n, size - n); 05578 if (i <= 0) 05579 break; 05580 n += i; 05581 } while (TRUE); 05582 05583 buffer[n] = 0; 05584 05585 if (strncmp(buffer, "<?xml version=\"1.0\"", 19) == 0) { 05586 status = db_paste_xml(hDB, hKeyRoot, buffer); 05587 if (status != DB_SUCCESS) 05588 printf("Error in file \"%s\"\n", filename); 05589 } else 05590 status = db_paste(hDB, hKeyRoot, buffer); 05591 05592 close(hfile); 05593 free(buffer); 05594 05595 return status; 05596 }
INT db_lock_database | ( | HNDLE | hDB | ) |
Lock a database for exclusive access via system semaphore calls.
hDB | Handle to the database to lock |
Definition at line 1389 of file odb.c.
Referenced by cm_check_client(), cm_delete_client_info(), cm_get_watchdog_info(), cm_set_client_info(), cm_set_watchdog_params(), db_close_database(), db_create_key(), db_create_record(), db_delete_key1(), db_enum_key(), db_find_key(), db_get_data(), db_get_data_index(), db_get_key(), db_get_key_info(), db_get_key_time(), db_get_link(), db_get_link_data(), db_get_record(), db_get_record_size(), db_get_value(), db_open_database(), db_set_data(), db_set_data_index(), db_set_link_data(), db_set_link_data_index(), db_set_record(), db_set_value(), and log_system_history().
01390 { 01391 #ifdef LOCAL_ROUTINES 01392 int status; 01393 void *p; 01394 01395 #ifdef CHECK_THREAD_ID 01396 if (_lock_tid == 0) 01397 _lock_tid = ss_gettid(); 01398 01399 assert(_lock_tid == ss_gettid()); 01400 #endif 01401 01402 if (hDB > _database_entries || hDB <= 0) { 01403 cm_msg(MERROR, "db_lock_database", "invalid database handle, aborting..."); 01404 abort(); 01405 return DB_INVALID_HANDLE; 01406 } 01407 01408 if (_database[hDB - 1].protect && _database[hDB - 1].database_header != NULL) { 01409 cm_msg(MERROR, "db_lock_database", "internal error: DB already locked, aborting..."); 01410 abort(); 01411 return DB_NO_SEMAPHORE; 01412 } 01413 01414 if (_database[hDB - 1].lock_cnt == 0) { 01415 /* wait max. 5 minutes for semaphore (required if locking process is being debugged) */ 01416 status = ss_semaphore_wait_for(_database[hDB - 1].semaphore, 5 * 60 * 1000); 01417 if (status == SS_TIMEOUT) { 01418 cm_msg(MERROR, "db_lock_database", "timeout obtaining lock for database, exiting..."); 01419 exit(1); 01420 return DB_TIMEOUT; 01421 } 01422 if (status != SS_SUCCESS) { 01423 cm_msg(MERROR, "db_lock_database", "cannot lock database, ss_semaphore_wait_for() status %d, aborting...", status); 01424 abort(); 01425 return DB_NO_SEMAPHORE; 01426 } 01427 } 01428 01429 _database[hDB - 1].lock_cnt++; 01430 01431 #ifdef CHECK_LOCK_COUNT 01432 { 01433 char str[256]; 01434 01435 sprintf(str, "db_lock_database, lock_cnt=%d", _database[hDB - 1].lock_cnt); 01436 ss_stack_history_entry(str); 01437 } 01438 #endif 01439 01440 if (_database[hDB - 1].protect) { 01441 if (_database[hDB - 1].database_header == NULL) { 01442 ss_shm_unprotect(_database[hDB - 1].shm_handle, &p); 01443 _database[hDB - 1].database_header = (DATABASE_HEADER *) p; 01444 } 01445 } 01446 #endif /* LOCAL_ROUTINES */ 01447 return DB_SUCCESS; 01448 }
INT db_open_database | ( | const char * | xdatabase_name, | |
INT | database_size, | |||
HNDLE * | hDB, | |||
const char * | client_name | |||
) |
Open an online database
database_name | Database name. | |
database_size | Initial size of database if not existing | |
client_name | Name of this application | |
hDB | ODB handle obtained via cm_get_experiment_database(). |
Definition at line 786 of file odb.c.
Referenced by cm_connect_experiment1(), and rpc_server_dispatch().
00787 { 00788 if (rpc_is_remote()) 00789 return rpc_call(RPC_DB_OPEN_DATABASE, xdatabase_name, database_size, hDB, client_name); 00790 00791 #ifdef LOCAL_ROUTINES 00792 { 00793 INT i, status; 00794 HNDLE handle; 00795 DATABASE_CLIENT *pclient; 00796 BOOL shm_created; 00797 HNDLE shm_handle; 00798 DATABASE_HEADER *pheader; 00799 KEY *pkey; 00800 KEYLIST *pkeylist; 00801 FREE_DESCRIP *pfree; 00802 BOOL call_watchdog; 00803 DWORD timeout; 00804 char database_name[NAME_LENGTH]; 00805 void *p; 00806 00807 /* restrict name length */ 00808 strlcpy(database_name, xdatabase_name, NAME_LENGTH); 00809 00810 if (database_size < 0 || database_size > 10E7) { 00811 cm_msg(MERROR, "db_open_database", "invalid database size"); 00812 return DB_INVALID_PARAM; 00813 } 00814 00815 if (strlen(client_name) >= NAME_LENGTH) { 00816 cm_msg(MERROR, "db_open_database", "client name \'%s\' is longer than %d characters", client_name, NAME_LENGTH-1); 00817 return DB_INVALID_PARAM; 00818 } 00819 00820 if (strchr(client_name, '/') != NULL) { 00821 cm_msg(MERROR, "db_open_database", "client name \'%s\' should not contain the slash \'/\' character", client_name); 00822 return DB_INVALID_PARAM; 00823 } 00824 00825 /* allocate new space for the new database descriptor */ 00826 if (_database_entries == 0) { 00827 _database = (DATABASE *) malloc(sizeof(DATABASE)); 00828 memset(_database, 0, sizeof(DATABASE)); 00829 if (_database == NULL) { 00830 *hDB = 0; 00831 return DB_NO_MEMORY; 00832 } 00833 00834 _database_entries = 1; 00835 i = 0; 00836 } else { 00837 /* check if database already open */ 00838 for (i = 0; i < _database_entries; i++) 00839 if (_database[i].attached && equal_ustring(_database[i].name, database_name)) { 00840 /* check if database belongs to this thread */ 00841 if (rpc_get_server_option(RPC_OSERVER_TYPE) == ST_MTHREAD) { 00842 if (_database[i].index == ss_gettid()) { 00843 *hDB = i + 1; 00844 return DB_SUCCESS; 00845 } 00846 } else { 00847 *hDB = i + 1; 00848 return DB_SUCCESS; 00849 } 00850 } 00851 00852 /* check for a deleted entry */ 00853 for (i = 0; i < _database_entries; i++) 00854 if (!_database[i].attached) 00855 break; 00856 00857 /* if not found, create new one */ 00858 if (i == _database_entries) { 00859 _database = (DATABASE *) realloc(_database, sizeof(DATABASE) * (_database_entries + 1)); 00860 memset(&_database[_database_entries], 0, sizeof(DATABASE)); 00861 00862 _database_entries++; 00863 if (_database == NULL) { 00864 _database_entries--; 00865 *hDB = 0; 00866 return DB_NO_MEMORY; 00867 } 00868 } 00869 } 00870 00871 handle = (HNDLE) i; 00872 00873 /* open shared memory region */ 00874 status = ss_shm_open(database_name, 00875 sizeof(DATABASE_HEADER) + 2 * ALIGN8(database_size / 2), &p, &shm_handle, TRUE); 00876 00877 _database[(INT) handle].database_header = (DATABASE_HEADER *) p; 00878 if (status == SS_NO_MEMORY || status == SS_FILE_ERROR) { 00879 *hDB = 0; 00880 return DB_INVALID_NAME; 00881 } 00882 00883 /* shortcut to header */ 00884 pheader = _database[handle].database_header; 00885 00886 /* save name */ 00887 strcpy(_database[handle].name, database_name); 00888 00889 shm_created = (status == SS_CREATED); 00890 00891 /* clear memeory for debugging */ 00892 /* memset(pheader, 0, sizeof(DATABASE_HEADER) + 2*ALIGN8(database_size/2)); */ 00893 00894 if (shm_created && pheader->name[0] == 0) { 00895 /* setup header info if database was created */ 00896 memset(pheader, 0, sizeof(DATABASE_HEADER) + 2 * ALIGN8(database_size / 2)); 00897 00898 strcpy(pheader->name, database_name); 00899 pheader->version = DATABASE_VERSION; 00900 pheader->key_size = ALIGN8(database_size / 2); 00901 pheader->data_size = ALIGN8(database_size / 2); 00902 pheader->root_key = sizeof(DATABASE_HEADER); 00903 pheader->first_free_key = sizeof(DATABASE_HEADER); 00904 pheader->first_free_data = sizeof(DATABASE_HEADER) + pheader->key_size; 00905 00906 /* set up free list */ 00907 pfree = (FREE_DESCRIP *) ((char *) pheader + pheader->first_free_key); 00908 pfree->size = pheader->key_size; 00909 pfree->next_free = 0; 00910 00911 pfree = (FREE_DESCRIP *) ((char *) pheader + pheader->first_free_data); 00912 pfree->size = pheader->data_size; 00913 pfree->next_free = 0; 00914 00915 /* create root key */ 00916 pkey = (KEY *) malloc_key(pheader, sizeof(KEY)); 00917 00918 /* set key properties */ 00919 pkey->type = TID_KEY; 00920 pkey->num_values = 1; 00921 pkey->access_mode = MODE_READ | MODE_WRITE | MODE_DELETE; 00922 strcpy(pkey->name, "root"); 00923 pkey->parent_keylist = 0; 00924 00925 /* create keylist */ 00926 pkeylist = (KEYLIST *) malloc_key(pheader, sizeof(KEYLIST)); 00927 00928 /* store keylist in data field */ 00929 pkey->data = (POINTER_T) pkeylist - (POINTER_T) pheader; 00930 pkey->item_size = sizeof(KEYLIST); 00931 pkey->total_size = sizeof(KEYLIST); 00932 00933 pkeylist->parent = (POINTER_T) pkey - (POINTER_T) pheader; 00934 pkeylist->num_keys = 0; 00935 pkeylist->first_key = 0; 00936 } 00937 00938 /* check database version */ 00939 if (pheader->version != DATABASE_VERSION) { 00940 cm_msg(MERROR, "db_open_database", 00941 "Different database format: Shared memory is %d, program is %d", pheader->version, DATABASE_VERSION); 00942 return DB_VERSION_MISMATCH; 00943 } 00944 00945 /* create semaphore for the database */ 00946 status = ss_semaphore_create(database_name, &(_database[handle].semaphore)); 00947 if (status != SS_SUCCESS && status != SS_CREATED) { 00948 *hDB = 0; 00949 return DB_NO_SEMAPHORE; 00950 } 00951 _database[handle].lock_cnt = 0; 00952 00953 /* first lock database */ 00954 status = db_lock_database(handle + 1); 00955 if (status != DB_SUCCESS) 00956 return status; 00957 00958 /* 00959 Now we have a DATABASE_HEADER, so let's setup a CLIENT 00960 structure in that database. The information there can also 00961 be seen by other processes. 00962 */ 00963 00964 /* 00965 update the client count 00966 */ 00967 pheader->num_clients = 0; 00968 pheader->max_client_index = 0; 00969 for (i = 0; i < MAX_CLIENTS; i++) { 00970 if (pheader->client[i].pid == 0) 00971 continue; 00972 pheader->num_clients++; 00973 pheader->max_client_index = i + 1; 00974 } 00975 00976 /*fprintf(stderr,"num_clients: %d, max_client: %d\n",pheader->num_clients,pheader->max_client_index); */ 00977 00978 /* 00979 Look for empty client slot 00980 */ 00981 for (i = 0; i < MAX_CLIENTS; i++) 00982 if (pheader->client[i].pid == 0) 00983 break; 00984 00985 if (i == MAX_CLIENTS) { 00986 db_unlock_database(handle + 1); 00987 *hDB = 0; 00988 cm_msg(MERROR, "db_open_database", "maximum number of clients exceeded"); 00989 return DB_NO_SLOT; 00990 } 00991 00992 /* store slot index in _database structure */ 00993 _database[handle].client_index = i; 00994 00995 /* 00996 Save the index of the last client of that database so that later only 00997 the clients 0..max_client_index-1 have to be searched through. 00998 */ 00999 pheader->num_clients++; 01000 if (i + 1 > pheader->max_client_index) 01001 pheader->max_client_index = i + 1; 01002 01003 /* setup database header and client structure */ 01004 pclient = &pheader->client[i]; 01005 01006 memset(pclient, 0, sizeof(DATABASE_CLIENT)); 01007 /* use client name previously set by bm_set_name */ 01008 strlcpy(pclient->name, client_name, sizeof(pclient->name)); 01009 pclient->pid = ss_getpid(); 01010 pclient->num_open_records = 0; 01011 01012 ss_suspend_get_port(&pclient->port); 01013 01014 pclient->last_activity = ss_millitime(); 01015 01016 cm_get_watchdog_params(&call_watchdog, &timeout); 01017 pclient->watchdog_timeout = timeout; 01018 01019 /* check ODB for corruption */ 01020 if (!db_validate_db(pheader)) { 01021 /* do not treat corrupted odb as a fatal error- allow the user 01022 to preceed at own risk- the database is already corrupted, 01023 so no further harm can possibly be made. */ 01024 /* 01025 db_unlock_database(handle + 1); 01026 *hDB = 0; 01027 return DB_CORRUPTED; 01028 */ 01029 } 01030 01031 /* setup _database entry */ 01032 _database[handle].database_data = _database[handle].database_header + 1; 01033 _database[handle].attached = TRUE; 01034 _database[handle].shm_handle = shm_handle; 01035 _database[handle].protect = FALSE; 01036 01037 /* remember to which connection acutal buffer belongs */ 01038 if (rpc_get_server_option(RPC_OSERVER_TYPE) == ST_SINGLE) 01039 _database[handle].index = rpc_get_server_acception(); 01040 else 01041 _database[handle].index = ss_gettid(); 01042 01043 *hDB = (handle + 1); 01044 01045 /* setup dispatcher for updated records */ 01046 ss_suspend_set_dispatch(CH_IPC, 0, (int (*)(void)) cm_dispatch_ipc); 01047 01048 01049 /* remove dead clients */ 01050 01051 #ifdef OS_UNIX 01052 #ifdef ESRCH 01053 /* Only enable this for systems that define ESRCH and hope that 01054 they also support kill(pid,0) */ 01055 for (i = 0; i < MAX_CLIENTS; i++) { 01056 int k; 01057 01058 errno = 0; 01059 kill(pheader->client[i].pid, 0); 01060 if (errno == ESRCH) { 01061 cm_msg(MERROR, "db_open_database", 01062 "Removing client \'%s\', pid %d, index %d because the pid no longer exists", 01063 pheader->client[i].name, pheader->client[i].pid, i); 01064 01065 /* decrement notify_count for open records and clear exclusive mode */ 01066 for (k = 0; k < pheader->client[i].max_index; k++) 01067 if (pheader->client[i].open_record[k].handle) { 01068 pkey = (KEY *) ((char *) pheader + pheader->client[i].open_record[k].handle); 01069 if (pkey->notify_count > 0) 01070 pkey->notify_count--; 01071 01072 if (pheader->client[i].open_record[k].access_mode & MODE_WRITE) 01073 db_set_mode(handle + 1, pheader->client[i].open_record[k].handle, 01074 (WORD) (pkey->access_mode & ~MODE_EXCLUSIVE), 2); 01075 } 01076 01077 /* clear entry from client structure in database header */ 01078 memset(&(pheader->client[i]), 0, sizeof(DATABASE_CLIENT)); 01079 } 01080 } 01081 #endif 01082 #endif 01083 01084 db_unlock_database(handle + 1); 01085 01086 if (shm_created) 01087 return DB_CREATED; 01088 } 01089 #endif /* LOCAL_ROUTINES */ 01090 01091 return DB_SUCCESS; 01092 }
INT db_open_record | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
void * | ptr, | |||
INT | rec_size, | |||
WORD | access_mode, | |||
void(*)(INT, INT, void *) | dispatcher, | |||
void * | info | |||
) |
Open a record. Create a local copy and maintain an automatic update.
This function opens a hot-link between an ODB sub-tree and a local structure. The sub-tree is copied to the structure automatically every time it is modified by someone else. Additionally, a callback function can be declared which is called after the structure has been updated. The callback function receives the database handle and the key handle as parameters.
Problems might occur if the ODB sub-tree contains values which don't match the C structure. Although the structure size is checked against the sub-tree size, no checking can be done if the type and order of the values in the structure are the same than those in the ODB sub-tree. Therefore it is recommended to use the function db_create_record() before db_open_record() is used which ensures that both are equivalent.
The access mode might either be MODE_READ or MODE_WRITE. In read mode, the ODB sub-tree is automatically copied to the local structure when modified by other clients. In write mode, the local structure is copied to the ODB sub-tree if it has been modified locally. This update has to be manually scheduled by calling db_send_changed_records() periodically in the main loop. The system keeps a copy of the local structure to determine if its contents has been changed.
If MODE_ALLOC is or'ed with the access mode, the memory for the structure is allocated internally. The structure pointer must contain a pointer to a pointer to the structure. The internal memory is released when db_close_record() is called.
struct { INT level1; INT level2; } trigger_settings; char *trigger_settings_str = "[Settings]\n\ level1 = INT : 0\n\ level2 = INT : 0"; main() { HNDLE hDB, hkey, i=0; ... cm_get_experiment_database(&hDB, NULL); db_create_record(hDB, 0, "/Equipment/Trigger", trigger_settings_str); db_find_key(hDB, 0,"/Equipment/Trigger/Settings", &hkey); db_open_record(hDB, hkey, &trigger_settings, sizeof(trigger_settings) , MODE_WRITE, NULL); do { trigger_settings.level1 = i++; db_send_changed_records() status = cm_yield(1000); } while (status != RPC_SHUTDOWN && status != SS_ABORT); ... }
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
ptr | If access_mode includes MODE_ALLOC: Address of pointer which points to the record data after the call if access_mode includes not MODE_ALLOC: Address of record if ptr==NULL, only the dispatcher is called. | |
rec_size | Record size in bytes | |
access_mode | Mode for opening record, either MODE_READ or MODE_WRITE. May be or'ed with MODE_ALLOC to let db_open_record allocate the memory for the record. | |
(*dispatcher) | Function which gets called when record is updated.The argument list composed of: HNDLE hDB, HNDLE hKey, void *info | |
info | Additional info passed to the dispatcher. |
Definition at line 8463 of file odb.c.
Referenced by add_event(), analyzer_init(), book_ntuples(), cm_register_deferred_transition(), command_loop(), frontend_init(), init_module_parameters(), main(), mana_init(), open_history(), register_equipment(), register_requests(), and tr_start().
08465 { 08466 INT idx, status, size; 08467 KEY key; 08468 void *data; 08469 char str[256]; 08470 08471 /* allocate new space for the local record list */ 08472 if (_record_list_entries == 0) { 08473 _record_list = (RECORD_LIST *) malloc(sizeof(RECORD_LIST)); 08474 memset(_record_list, 0, sizeof(RECORD_LIST)); 08475 if (_record_list == NULL) { 08476 cm_msg(MERROR, "db_open_record", "not enough memory"); 08477 return DB_NO_MEMORY; 08478 } 08479 08480 _record_list_entries = 1; 08481 idx = 0; 08482 } else { 08483 /* check for a deleted entry */ 08484 for (idx = 0; idx < _record_list_entries; idx++) 08485 if (!_record_list[idx].handle) 08486 break; 08487 08488 /* if not found, create new one */ 08489 if (idx == _record_list_entries) { 08490 _record_list = (RECORD_LIST *) realloc(_record_list, sizeof(RECORD_LIST) * (_record_list_entries + 1)); 08491 if (_record_list == NULL) { 08492 cm_msg(MERROR, "db_open_record", "not enough memory"); 08493 return DB_NO_MEMORY; 08494 } 08495 08496 memset(&_record_list[_record_list_entries], 0, sizeof(RECORD_LIST)); 08497 08498 _record_list_entries++; 08499 } 08500 } 08501 08502 db_get_key(hDB, hKey, &key); 08503 08504 /* check record size */ 08505 status = db_get_record_size(hDB, hKey, 0, &size); 08506 if (status != DB_SUCCESS) { 08507 _record_list_entries--; 08508 cm_msg(MERROR, "db_open_record", "cannot get record size"); 08509 return DB_NO_MEMORY; 08510 } 08511 if (size != rec_size && ptr != NULL) { 08512 _record_list_entries--; 08513 db_get_path(hDB, hKey, str, sizeof(str)); 08514 cm_msg(MERROR, "db_open_record", "struct size mismatch for \"%s\" (%d instead of %d)", str, rec_size, size); 08515 return DB_STRUCT_SIZE_MISMATCH; 08516 } 08517 08518 /* check for read access */ 08519 if (((key.access_mode & MODE_EXCLUSIVE) && (access_mode & MODE_WRITE)) 08520 || (!(key.access_mode & MODE_WRITE) && (access_mode & MODE_WRITE)) 08521 || (!(key.access_mode & MODE_READ) && (access_mode & MODE_READ))) { 08522 _record_list_entries--; 08523 return DB_NO_ACCESS; 08524 } 08525 08526 if (access_mode & MODE_ALLOC) { 08527 data = malloc(size); 08528 memset(data, 0, size); 08529 08530 if (data == NULL) { 08531 _record_list_entries--; 08532 cm_msg(MERROR, "db_open_record", "not enough memory"); 08533 return DB_NO_MEMORY; 08534 } 08535 08536 *((void **) ptr) = data; 08537 } else 08538 data = ptr; 08539 08540 /* copy record to local memory */ 08541 if (access_mode & MODE_READ && data != NULL) { 08542 status = db_get_record(hDB, hKey, data, &size, 0); 08543 if (status != DB_SUCCESS) { 08544 _record_list_entries--; 08545 cm_msg(MERROR, "db_open_record", "cannot get record"); 08546 return DB_NO_MEMORY; 08547 } 08548 } 08549 08550 /* copy local record to ODB */ 08551 if (access_mode & MODE_WRITE) { 08552 /* only write to ODB if not in MODE_ALLOC */ 08553 if ((access_mode & MODE_ALLOC) == 0) { 08554 status = db_set_record(hDB, hKey, data, size, 0); 08555 if (status != DB_SUCCESS) { 08556 _record_list_entries--; 08557 cm_msg(MERROR, "db_open_record", "cannot set record"); 08558 return DB_NO_MEMORY; 08559 } 08560 } 08561 08562 /* init a local copy of the record */ 08563 _record_list[idx].copy = malloc(size); 08564 if (_record_list[idx].copy == NULL) { 08565 cm_msg(MERROR, "db_open_record", "not enough memory"); 08566 return DB_NO_MEMORY; 08567 } 08568 08569 memcpy(_record_list[idx].copy, data, size); 08570 } 08571 08572 /* initialize record list */ 08573 _record_list[idx].handle = hKey; 08574 _record_list[idx].hDB = hDB; 08575 _record_list[idx].access_mode = access_mode; 08576 _record_list[idx].data = data; 08577 _record_list[idx].buf_size = size; 08578 _record_list[idx].dispatcher = dispatcher; 08579 _record_list[idx].info = info; 08580 08581 /* add record entry in database structure */ 08582 return db_add_open_record(hDB, hKey, (WORD) (access_mode & ~MODE_ALLOC)); 08583 }
INT db_paste | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
const char * | buffer | |||
) |
Copy an ODB subtree in ASCII format from a buffer
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
buffer | NULL-terminated buffer |
Definition at line 5897 of file odb.c.
Referenced by command_loop(), db_create_record(), db_load(), and odb_load().
05898 { 05899 char line[MAX_STRING_LENGTH]; 05900 char title[MAX_STRING_LENGTH]; 05901 char key_name[MAX_STRING_LENGTH]; 05902 char data_str[MAX_STRING_LENGTH + 50]; 05903 char test_str[MAX_STRING_LENGTH]; 05904 char *pc, *data; 05905 const char *pold; 05906 INT data_size; 05907 INT tid, i, j, n_data, string_length, status, size; 05908 HNDLE hKey; 05909 KEY root_key; 05910 BOOL multi_line; 05911 05912 title[0] = 0; 05913 multi_line = FALSE; 05914 05915 if (hKeyRoot == 0) 05916 db_find_key(hDB, hKeyRoot, "", &hKeyRoot); 05917 05918 db_get_key(hDB, hKeyRoot, &root_key); 05919 05920 /* initial data size */ 05921 data_size = 1000; 05922 data = (char *) malloc(data_size); 05923 if (data == NULL) { 05924 cm_msg(MERROR, "db_paste", "cannot allocate data buffer"); 05925 return DB_NO_MEMORY; 05926 } 05927 05928 do { 05929 if (*buffer == 0) 05930 break; 05931 05932 for (i = 0; *buffer != '\n' && *buffer && i < MAX_STRING_LENGTH; i++) 05933 line[i] = *buffer++; 05934 05935 if (i == MAX_STRING_LENGTH) { 05936 cm_msg(MERROR, "db_paste", "line too long"); 05937 free(data); 05938 return DB_TRUNCATED; 05939 } 05940 05941 line[i] = 0; 05942 if (*buffer == '\n') 05943 buffer++; 05944 05945 /* check if it is a section title */ 05946 if (line[0] == '[') { 05947 /* extract title and append '/' */ 05948 strlcpy(title, line + 1, sizeof(title)); 05949 if (strchr(title, ']')) 05950 *strchr(title, ']') = 0; 05951 if (title[0] && title[strlen(title) - 1] != '/') 05952 strlcat(title, "/", sizeof(title)); 05953 } else { 05954 /* valid data line if it includes '=' and no ';' */ 05955 if (strchr(line, '=') && line[0] != ';') { 05956 /* copy type info and data */ 05957 pc = strrchr(line, '=') + 1; 05958 while (strstr(line, ": [") != NULL && strstr(line, ": [") < pc) { 05959 pc -= 2; 05960 while (*pc != '=' && pc > line) 05961 pc--; 05962 pc++; 05963 } 05964 while (*pc == ' ') 05965 pc++; 05966 strlcpy(data_str, pc, sizeof(data_str)); 05967 05968 /* extract key name */ 05969 *strrchr(line, '=') = 0; 05970 while (strstr(line, ": [") && strchr(line, '=')) 05971 *strrchr(line, '=') = 0; 05972 05973 pc = &line[strlen(line) - 1]; 05974 while (*pc == ' ') 05975 *pc-- = 0; 05976 05977 key_name[0] = 0; 05978 if (title[0] != '.') 05979 strlcpy(key_name, title, sizeof(key_name)); 05980 05981 strlcat(key_name, line, sizeof(key_name)); 05982 05983 /* evaluate type info */ 05984 strlcpy(line, data_str, sizeof(line)); 05985 if (strchr(line, ' ')) 05986 *strchr(line, ' ') = 0; 05987 05988 n_data = 1; 05989 if (strchr(line, '[')) { 05990 n_data = atol(strchr(line, '[') + 1); 05991 *strchr(line, '[') = 0; 05992 } 05993 05994 for (tid = 0; tid < TID_LAST; tid++) 05995 if (strcmp(tid_name[tid], line) == 0) 05996 break; 05997 05998 string_length = 0; 05999 06000 if (tid == TID_LAST) 06001 cm_msg(MERROR, "db_paste", "found unknown data type \"%s\" in ODB file", line); 06002 else { 06003 /* skip type info */ 06004 pc = data_str; 06005 while (*pc != ' ' && *pc) 06006 pc++; 06007 while ((*pc == ' ' || *pc == ':') && *pc) 06008 pc++; 06009 strlcpy(data_str, pc, sizeof(data_str)); 06010 06011 if (n_data > 1) { 06012 data_str[0] = 0; 06013 if (!*buffer) 06014 break; 06015 06016 for (j = 0; *buffer != '\n' && *buffer; j++) 06017 data_str[j] = *buffer++; 06018 data_str[j] = 0; 06019 if (*buffer == '\n') 06020 buffer++; 06021 } 06022 06023 for (i = 0; i < n_data; i++) { 06024 /* strip trailing \n */ 06025 pc = &data_str[strlen(data_str) - 1]; 06026 while (*pc == '\n' || *pc == '\r') 06027 *pc-- = 0; 06028 06029 if (tid == TID_STRING || tid == TID_LINK) { 06030 if (!string_length) { 06031 if (data_str[1] == '=') 06032 string_length = -1; 06033 else 06034 string_length = atoi(data_str + 1); 06035 if (string_length > MAX_STRING_LENGTH) { 06036 string_length = MAX_STRING_LENGTH; 06037 cm_msg(MERROR, "db_paste", "found string exceeding MAX_STRING_LENGTH"); 06038 } 06039 } 06040 06041 if (string_length == -1) { 06042 /* multi-line string */ 06043 if (strstr(buffer, "\n====#$@$#====\n") != NULL) { 06044 string_length = (POINTER_T) strstr(buffer, "\n====#$@$#====\n") - (POINTER_T) buffer + 1; 06045 06046 if (string_length >= data_size) { 06047 data_size += string_length + 100; 06048 data = (char *) realloc(data, data_size); 06049 if (data == NULL) { 06050 cm_msg(MERROR, "db_paste", "cannot allocate data buffer"); 06051 return DB_NO_MEMORY; 06052 } 06053 } 06054 06055 memset(data, 0, data_size); 06056 strncpy(data, buffer, string_length); 06057 data[string_length - 1] = 0; 06058 buffer = strstr(buffer, "\n====#$@$#====\n") + strlen("\n====#$@$#====\n"); 06059 } else 06060 cm_msg(MERROR, "db_paste", "found multi-line string without termination sequence"); 06061 } else { 06062 pc = data_str + 2; 06063 while (*pc && *pc != ' ') 06064 pc++; 06065 while (*pc && *pc == ' ') 06066 pc++; 06067 06068 /* limit string size */ 06069 *(pc + string_length - 1) = 0; 06070 06071 /* increase data buffer if necessary */ 06072 if (string_length * (i + 1) >= data_size) { 06073 data_size += 1000; 06074 data = (char *) realloc(data, data_size); 06075 if (data == NULL) { 06076 cm_msg(MERROR, "db_paste", "cannot allocate data buffer"); 06077 return DB_NO_MEMORY; 06078 } 06079 } 06080 06081 strlcpy(data + string_length * i, pc, string_length); 06082 } 06083 } else { 06084 pc = data_str; 06085 06086 if (n_data > 1 && data_str[0] == '[') { 06087 pc = strchr(data_str, ']') + 1; 06088 while (*pc && *pc == ' ') 06089 pc++; 06090 } 06091 06092 db_sscanf(pc, data, &size, i, tid); 06093 06094 /* increase data buffer if necessary */ 06095 if (size * (i + 1) >= data_size) { 06096 data_size += 1000; 06097 data = (char *) realloc(data, data_size); 06098 if (data == NULL) { 06099 cm_msg(MERROR, "db_paste", "cannot allocate data buffer"); 06100 return DB_NO_MEMORY; 06101 } 06102 } 06103 06104 } 06105 06106 if (i < n_data - 1) { 06107 data_str[0] = 0; 06108 if (!*buffer) 06109 break; 06110 06111 pold = buffer; 06112 06113 for (j = 0; *buffer != '\n' && *buffer; j++) 06114 data_str[j] = *buffer++; 06115 data_str[j] = 0; 06116 if (*buffer == '\n') 06117 buffer++; 06118 06119 /* test if valid data */ 06120 if (tid != TID_STRING && tid != TID_LINK) { 06121 if (data_str[0] == 0 || (strchr(data_str, '=') 06122 && strchr(data_str, ':'))) 06123 buffer = pold; 06124 } 06125 } 06126 } 06127 06128 /* skip system client entries */ 06129 strcpy(test_str, key_name); 06130 test_str[15] = 0; 06131 06132 if (!equal_ustring(test_str, "/System/Clients")) { 06133 if (root_key.type != TID_KEY) { 06134 /* root key is destination key */ 06135 hKey = hKeyRoot; 06136 } else { 06137 /* create key and set value */ 06138 if (key_name[0] == '/') { 06139 status = db_find_link(hDB, 0, key_name, &hKey); 06140 if (status == DB_NO_KEY) { 06141 db_create_key(hDB, 0, key_name, tid); 06142 status = db_find_link(hDB, 0, key_name, &hKey); 06143 } 06144 } else { 06145 status = db_find_link(hDB, hKeyRoot, key_name, &hKey); 06146 if (status == DB_NO_KEY) { 06147 db_create_key(hDB, hKeyRoot, key_name, tid); 06148 status = db_find_link(hDB, hKeyRoot, key_name, &hKey); 06149 } 06150 } 06151 } 06152 06153 /* set key data if created sucessfully */ 06154 if (hKey) { 06155 if (tid == TID_STRING || tid == TID_LINK) 06156 db_set_link_data(hDB, hKey, data, string_length * n_data, n_data, tid); 06157 else 06158 db_set_link_data(hDB, hKey, data, rpc_tid_size(tid) * n_data, n_data, tid); 06159 } 06160 } 06161 } 06162 } 06163 } 06164 } while (TRUE); 06165 06166 free(data); 06167 return DB_SUCCESS; 06168 }
int db_paste_node | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
PMXML_NODE | node | |||
) |
Definition at line 6174 of file odb.c.
Referenced by db_paste_xml().
06175 { 06176 char type[256], data[256], test_str[256], buf[10000]; 06177 int i, status, size, tid, num_values; 06178 HNDLE hKey; 06179 PMXML_NODE child; 06180 06181 if (strcmp(mxml_get_name(node), "odb") == 0) { 06182 for (i = 0; i < mxml_get_number_of_children(node); i++) { 06183 status = db_paste_node(hDB, hKeyRoot, mxml_subnode(node, i)); 06184 if (status != DB_SUCCESS) 06185 return status; 06186 } 06187 } else if (strcmp(mxml_get_name(node), "dir") == 0) { 06188 status = db_find_link(hDB, hKeyRoot, mxml_get_attribute(node, "name"), &hKey); 06189 06190 /* skip system client entries */ 06191 strlcpy(test_str, mxml_get_attribute(node, "name"), sizeof(test_str)); 06192 test_str[15] = 0; 06193 if (equal_ustring(test_str, "/System/Clients")) 06194 return DB_SUCCESS; 06195 06196 if (status == DB_NO_KEY) { 06197 status = db_create_key(hDB, hKeyRoot, mxml_get_attribute(node, "name"), TID_KEY); 06198 if (status == DB_NO_ACCESS) 06199 return DB_SUCCESS; /* key or tree is locked, just skip it */ 06200 06201 if (status != DB_SUCCESS && status != DB_KEY_EXIST) { 06202 cm_msg(MERROR, "db_paste_node", 06203 "cannot create key \"%s\" in ODB, status = %d", mxml_get_attribute(node, "name"), status); 06204 return status; 06205 } 06206 status = db_find_link(hDB, hKeyRoot, mxml_get_attribute(node, "name"), &hKey); 06207 if (status != DB_SUCCESS) { 06208 cm_msg(MERROR, "db_paste_node", "cannot find key \"%s\" in ODB", mxml_get_attribute(node, "name")); 06209 return status; 06210 } 06211 } 06212 06213 db_get_path(hDB, hKey, data, sizeof(data)); 06214 if (strncmp(data, "/System/Clients", 15) != 0) { 06215 for (i = 0; i < mxml_get_number_of_children(node); i++) { 06216 status = db_paste_node(hDB, hKey, mxml_subnode(node, i)); 06217 if (status != DB_SUCCESS) 06218 return status; 06219 } 06220 } 06221 } else if (strcmp(mxml_get_name(node), "key") == 0 || strcmp(mxml_get_name(node), "keyarray") == 0) { 06222 06223 if (strcmp(mxml_get_name(node), "keyarray") == 0) 06224 num_values = atoi(mxml_get_attribute(node, "num_values")); 06225 else 06226 num_values = 0; 06227 06228 if (mxml_get_attribute(node, "type") == NULL) { 06229 cm_msg(MERROR, "db_paste_node", "found key \"%s\" with no type in XML data", mxml_get_name(node)); 06230 return DB_TYPE_MISMATCH; 06231 } 06232 06233 strlcpy(type, mxml_get_attribute(node, "type"), sizeof(type)); 06234 for (tid = 0; tid < TID_LAST; tid++) 06235 if (strcmp(tid_name[tid], type) == 0) 06236 break; 06237 if (tid == TID_LAST) { 06238 cm_msg(MERROR, "db_paste_node", "found unknown data type \"%s\" in XML data", type); 06239 return DB_TYPE_MISMATCH; 06240 } 06241 06242 status = db_find_link(hDB, hKeyRoot, mxml_get_attribute(node, "name"), &hKey); 06243 if (status == DB_NO_KEY) { 06244 status = db_create_key(hDB, hKeyRoot, mxml_get_attribute(node, "name"), tid); 06245 if (status == DB_NO_ACCESS) 06246 return DB_SUCCESS; /* key or tree is locked, just skip it */ 06247 06248 if (status != DB_SUCCESS) { 06249 cm_msg(MERROR, "db_paste_node", 06250 "cannot create key \"%s\" in ODB, status = %d", mxml_get_attribute(node, "name"), status); 06251 return status; 06252 } 06253 status = db_find_link(hDB, hKeyRoot, mxml_get_attribute(node, "name"), &hKey); 06254 if (status != DB_SUCCESS) { 06255 cm_msg(MERROR, "db_paste_node", 06256 "cannot find key \"%s\" in ODB, status = %d", mxml_get_attribute(node, "name")); 06257 return status; 06258 } 06259 } 06260 06261 if (num_values) { 06262 /* evaluate array */ 06263 for (i = 0; i < mxml_get_number_of_children(node); i++) { 06264 child = mxml_subnode(node, i); 06265 if (tid == TID_STRING || tid == TID_LINK) { 06266 size = atoi(mxml_get_attribute(node, "size")); 06267 if (mxml_get_value(child) == NULL) 06268 db_set_data_index(hDB, hKey, "", size, i, tid); 06269 else { 06270 strlcpy(buf, mxml_get_value(child), sizeof(buf)); 06271 db_set_data_index(hDB, hKey, buf, size, i, tid); 06272 } 06273 } else { 06274 db_sscanf(mxml_get_value(child), data, &size, 0, tid); 06275 db_set_data_index(hDB, hKey, data, rpc_tid_size(tid), i, tid); 06276 } 06277 } 06278 06279 } else { /* single value */ 06280 if (tid == TID_STRING || tid == TID_LINK) { 06281 size = atoi(mxml_get_attribute(node, "size")); 06282 if (mxml_get_value(node) == NULL) 06283 db_set_data(hDB, hKey, "", size, 1, tid); 06284 else 06285 db_set_data(hDB, hKey, mxml_get_value(node), size, 1, tid); 06286 } else { 06287 db_sscanf(mxml_get_value(node), data, &size, 0, tid); 06288 db_set_data(hDB, hKey, data, rpc_tid_size(tid), 1, tid); 06289 } 06290 } 06291 } 06292 06293 return DB_SUCCESS; 06294 }
INT db_paste_xml | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
const char * | buffer | |||
) |
Paste an ODB subtree in XML format from a buffer
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
buffer | NULL-terminated buffer |
Definition at line 6304 of file odb.c.
Referenced by db_load(), and odb_load().
06305 { 06306 char error[256]; 06307 INT status; 06308 PMXML_NODE tree, node; 06309 06310 if (hKeyRoot == 0) 06311 db_find_key(hDB, hKeyRoot, "", &hKeyRoot); 06312 06313 /* parse XML buffer */ 06314 tree = mxml_parse_buffer(buffer, error, sizeof(error)); 06315 if (tree == NULL) { 06316 puts(error); 06317 return DB_TYPE_MISMATCH; 06318 } 06319 06320 node = mxml_find_node(tree, "odb"); 06321 if (node == NULL) { 06322 puts("Cannot find element \"odb\" in XML data"); 06323 return DB_TYPE_MISMATCH; 06324 } 06325 06326 status = db_paste_node(hDB, hKeyRoot, node); 06327 06328 mxml_free_tree(tree); 06329 06330 return status; 06331 }
INT db_protect_database | ( | HNDLE | hDB | ) |
Protect a database for read/write access outside of the db_xxx functions
hDB | ODB handle obtained via cm_get_experiment_database(). |
Definition at line 1523 of file odb.c.
Referenced by main().
01524 { 01525 #ifdef LOCAL_ROUTINES 01526 if (hDB > _database_entries || hDB <= 0) { 01527 cm_msg(MERROR, "db_unlock_database", "invalid database handle"); 01528 return DB_INVALID_HANDLE; 01529 } 01530 01531 _database[hDB - 1].protect = TRUE; 01532 ss_shm_protect(_database[hDB - 1].shm_handle, _database[hDB - 1].database_header); 01533 _database[hDB - 1].database_header = NULL; 01534 #endif /* LOCAL_ROUTINES */ 01535 return DB_SUCCESS; 01536 }
Save a branch of a database to an .ODB file
This function is used by the ODBEdit command save. For a description of the ASCII format, see db_copy(). Data of the whole ODB can be saved (hkey equal zero) or only a sub-tree.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
filename | Filename of .ODB file. | |
bRemote | Flag for saving database on remote server. |
Definition at line 6517 of file odb.c.
Referenced by command_loop(), lazy_main(), odb_save(), and rpc_server_dispatch().
06518 { 06519 if (rpc_is_remote() && bRemote) 06520 return rpc_call(RPC_DB_SAVE, hDB, hKey, filename, bRemote); 06521 06522 #ifdef LOCAL_ROUTINES 06523 { 06524 INT hfile, size, buffer_size, n, status; 06525 char *buffer, path[256]; 06526 06527 /* open file */ 06528 hfile = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, 0644); 06529 if (hfile == -1) { 06530 cm_msg(MERROR, "db_save", "Cannot open file \"%s\"", filename); 06531 return DB_FILE_ERROR; 06532 } 06533 06534 db_get_path(hDB, hKey, path, sizeof(path)); 06535 06536 buffer_size = 10000; 06537 do { 06538 buffer = (char *) malloc(buffer_size); 06539 if (buffer == NULL) { 06540 cm_msg(MERROR, "db_save", "cannot allocate ODB dump buffer"); 06541 break; 06542 } 06543 06544 size = buffer_size; 06545 status = db_copy(hDB, hKey, buffer, &size, path); 06546 if (status != DB_TRUNCATED) { 06547 n = write(hfile, buffer, buffer_size - size); 06548 free(buffer); 06549 06550 if (n != buffer_size - size) { 06551 cm_msg(MERROR, "db_save", "cannot save .ODB file"); 06552 close(hfile); 06553 return DB_FILE_ERROR; 06554 } 06555 break; 06556 } 06557 06558 /* increase buffer size if truncated */ 06559 free(buffer); 06560 buffer_size *= 2; 06561 } while (1); 06562 06563 close(hfile); 06564 06565 } 06566 #endif /* LOCAL_ROUTINES */ 06567 06568 return DB_SUCCESS; 06569 }
INT db_save_struct | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | file_name, | |||
const char * | struct_name, | |||
BOOL | append | |||
) |
Save a branch of a database to a C structure .H file
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
file_name | Filename of .ODB file. | |
struct_name | Name of structure. If struct_name == NULL, the name of the key is used. | |
append | If TRUE, append to end of existing file |
Definition at line 6771 of file odb.c.
Referenced by command_loop(), and create_experim_h().
06772 { 06773 KEY key; 06774 char str[100], line[100]; 06775 INT status, i, fh; 06776 06777 /* open file */ 06778 fh = open(file_name, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0644); 06779 06780 if (fh == -1) { 06781 cm_msg(MERROR, "db_save_struct", "Cannot open file\"%s\"", file_name); 06782 return DB_FILE_ERROR; 06783 } 06784 06785 status = db_get_key(hDB, hKey, &key); 06786 if (status != DB_SUCCESS) { 06787 cm_msg(MERROR, "db_save_struct", "cannot find key"); 06788 return DB_INVALID_HANDLE; 06789 } 06790 06791 sprintf(line, "typedef struct {\n"); 06792 write(fh, line, strlen(line)); 06793 db_save_tree_struct(hDB, hKey, fh, 0); 06794 06795 if (struct_name && struct_name[0]) 06796 strcpy(str, struct_name); 06797 else 06798 strcpy(str, key.name); 06799 06800 name2c(str); 06801 for (i = 0; i < (int) strlen(str); i++) 06802 str[i] = (char) toupper(str[i]); 06803 06804 sprintf(line, "} %s;\n\n", str); 06805 write(fh, line, strlen(line)); 06806 06807 close(fh); 06808 06809 return DB_SUCCESS; 06810 }
INT db_save_xml | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const char * | filename | |||
) |
Save a branch of a database to an .xml file
This function is used by the ODBEdit command save to write the contents of the ODB into a XML file. Data of the whole ODB can be saved (hkey equal zero) or only a sub-tree.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
filename | Filename of .XML file. |
Definition at line 6719 of file odb.c.
Referenced by command_loop(), and odb_save().
06720 { 06721 #ifdef LOCAL_ROUTINES 06722 { 06723 INT status; 06724 char str[256]; 06725 MXML_WRITER *writer; 06726 06727 /* open file */ 06728 writer = mxml_open_file(filename); 06729 if (writer == NULL) { 06730 cm_msg(MERROR, "db_save_xml", "Cannot open file \"%s\"", filename); 06731 return DB_FILE_ERROR; 06732 } 06733 06734 db_get_path(hDB, hKey, str, sizeof(str)); 06735 06736 /* write XML header */ 06737 mxml_start_element(writer, "odb"); 06738 mxml_write_attribute(writer, "root", str); 06739 mxml_write_attribute(writer, "filename", filename); 06740 mxml_write_attribute(writer, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 06741 06742 if (getenv("MIDASSYS")) 06743 strcpy(str, getenv("MIDASSYS")); 06744 else 06745 strcpy(str, ""); 06746 strcat(str, DIR_SEPARATOR_STR); 06747 strcat(str, "odb.xsd"); 06748 mxml_write_attribute(writer, "xsi:noNamespaceSchemaLocation", str); 06749 06750 status = db_save_xml_key(hDB, hKey, 0, writer); 06751 06752 mxml_end_element(writer); // "odb" 06753 mxml_close_file(writer); 06754 } 06755 #endif /* LOCAL_ROUTINES */ 06756 06757 return DB_SUCCESS; 06758 }
Definition at line 6616 of file odb.c.
Referenced by db_copy_xml(), and db_save_xml().
06617 { 06618 INT i, idx, size, status; 06619 char str[MAX_STRING_LENGTH * 2], *data; 06620 HNDLE hSubkey; 06621 KEY key; 06622 06623 status = db_get_link(hDB, hKey, &key); 06624 if (status != DB_SUCCESS) 06625 return status; 06626 06627 if (key.type == TID_KEY) { 06628 06629 /* save opening tag for subtree */ 06630 06631 if (level > 0) { 06632 mxml_start_element(writer, "dir"); 06633 mxml_write_attribute(writer, "name", key.name); 06634 } 06635 06636 for (idx = 0;; idx++) { 06637 db_enum_link(hDB, hKey, idx, &hSubkey); 06638 06639 if (!hSubkey) 06640 break; 06641 06642 /* save subtree */ 06643 status = db_save_xml_key(hDB, hSubkey, level + 1, writer); 06644 if (status != DB_SUCCESS) 06645 return status; 06646 } 06647 06648 /* save closing tag for subtree */ 06649 if (level > 0) 06650 mxml_end_element(writer); 06651 06652 } else { 06653 06654 /* save key value */ 06655 06656 if (key.num_values > 1) 06657 mxml_start_element(writer, "keyarray"); 06658 else 06659 mxml_start_element(writer, "key"); 06660 mxml_write_attribute(writer, "name", key.name); 06661 mxml_write_attribute(writer, "type", rpc_tid_name(key.type)); 06662 06663 if (key.type == TID_STRING || key.type == TID_LINK) { 06664 sprintf(str, "%d", key.item_size); 06665 mxml_write_attribute(writer, "size", str); 06666 } 06667 06668 if (key.num_values > 1) { 06669 sprintf(str, "%d", key.num_values); 06670 mxml_write_attribute(writer, "num_values", str); 06671 } 06672 06673 size = key.total_size; 06674 data = (char *) malloc(size); 06675 if (data == NULL) { 06676 cm_msg(MERROR, "db_save_xml_key", "cannot allocate data buffer"); 06677 return DB_NO_MEMORY; 06678 } 06679 06680 db_get_link_data(hDB, hKey, data, &size, key.type); 06681 06682 if (key.num_values == 1) { 06683 06684 db_sprintf(str, data, key.item_size, 0, key.type); 06685 mxml_write_value(writer, str); 06686 mxml_end_element(writer); 06687 06688 } else { /* array of values */ 06689 06690 for (i = 0; i < key.num_values; i++) { 06691 06692 mxml_start_element(writer, "value"); 06693 db_sprintf(str, data, key.item_size, i, key.type); 06694 mxml_write_value(writer, str); 06695 mxml_end_element(writer); 06696 } 06697 06698 mxml_end_element(writer); /* keyarray */ 06699 } 06700 06701 free(data); 06702 } 06703 06704 return DB_SUCCESS; 06705 }
INT db_send_changed_records | ( | ) |
Send all records to the ODB which were changed locally since the last call to this function.
This function is valid if used in conjunction with db_open_record() under the condition the record is open as MODE_WRITE access code.
//-------- BOF dbchange.c typedef struct { INT my_number; float my_rate; } MY_STATISTICS; MY_STATISTICS myrec; #define MY_STATISTICS(_name) char *_name[] = {\ "My Number = INT : 0",\ "My Rate = FLOAT : 0",\ "",\ NULL } HNDLE hDB, hKey; // Main int main(unsigned int argc,char **argv) { char host_name[HOST_NAME_LENGTH]; char expt_name[HOST_NAME_LENGTH]; INT lastnumber, status, msg; BOOL debug=FALSE; char i, ch; DWORD update_time, mainlast_time; MY_STATISTICS (my_stat); // set default host_name[0] = 0; expt_name[0] = 0; // get default cm_get_environment(host_name, sizeof(host_name), expt_name, sizeof(expt_name)); // get parameters for (i=1 ; i<argc ; i++) { if (argv[i][0] == '-' && argv[i][1] == 'd') debug = TRUE; else if (argv[i][0] == '-') { if (i+1 >= argc || argv[i+1][0] == '-') goto usage; if (strncmp(argv[i],"-e",2) == 0) strcpy(expt_name, argv[++i]); else if (strncmp(argv[i],"-h",2)==0) strcpy(host_name, argv[++i]); } else { usage: printf("usage: dbchange [-h <Hostname>] [-e <Experiment>]\n"); return 0; } } // connect to experiment status = cm_connect_experiment(host_name, expt_name, "dbchange", 0); if (status != CM_SUCCESS) return 1; // Connect to DB cm_get_experiment_database(&hDB, &hKey); // Create a default structure in ODB db_create_record(hDB, 0, "My statistics", strcomb(my_stat)); // Retrieve key for that strucutre in ODB if (db_find_key(hDB, 0, "My statistics", &hKey) != DB_SUCCESS) { cm_msg(MERROR, "mychange", "cannot find My statistics"); goto error; } // Hot link this structure in Write mode status = db_open_record(hDB, hKey, &myrec , sizeof(MY_STATISTICS), MODE_WRITE, NULL, NULL); if (status != DB_SUCCESS) { cm_msg(MERROR, "mychange", "cannot open My statistics record"); goto error; } // initialize ss_getchar() ss_getchar(0); // Main loop do { // Update local structure if ((ss_millitime() - update_time) > 100) { myrec.my_number += 1; if (myrec.my_number - lastnumber) { myrec.my_rate = 1000.f * (float) (myrec.my_number - lastnumber) / (float) (ss_millitime() - update_time); } update_time = ss_millitime(); lastnumber = myrec.my_number; } // Publish local structure to ODB (db_send_changed_record) if ((ss_millitime() - mainlast_time) > 5000) { db_send_changed_records(); // <------- Call mainlast_time = ss_millitime(); } // Check for keyboard interaction ch = 0; while (ss_kbhit()) { ch = ss_getchar(0); if (ch == -1) ch = getchar(); if ((char) ch == '!') break; } msg = cm_yield(20); } while (msg != RPC_SHUTDOWN && msg != SS_ABORT && ch != '!'); error: cm_disconnect_experiment(); return 1; } //-------- EOF dbchange.c
Definition at line 8870 of file odb.c.
Referenced by lazy_statistics_update(), main(), scan_fragment(), and update_stats().
08871 { 08872 INT i; 08873 08874 for (i = 0; i < _record_list_entries; i++) 08875 if (_record_list[i].access_mode & MODE_WRITE) { 08876 if (memcmp(_record_list[i].copy, _record_list[i].data, _record_list[i].buf_size) != 0) { 08877 /* switch to fast TCP mode temporarily */ 08878 if (rpc_is_remote()) 08879 rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); 08880 db_set_record(_record_list[i].hDB, 08881 _record_list[i].handle, _record_list[i].data, _record_list[i].buf_size, 0); 08882 if (rpc_is_remote()) 08883 rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP); 08884 memcpy(_record_list[i].copy, _record_list[i].data, _record_list[i].buf_size); 08885 } 08886 } 08887 08888 return DB_SUCCESS; 08889 }
INT db_set_data | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const void * | data, | |||
INT | buf_size, | |||
INT | num_values, | |||
DWORD | type | |||
) |
Set key data from a handle. Adjust number of values if previous data has different size.
HNLDE hkey; INT run_number; // get key handle for run number db_find_key(hDB, 0, "/Runinfo/Run number", &hkey); // set run number db_set_data(hDB, hkey, &run_number, sizeof(run_number),TID_INT);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Buffer from which data gets copied to. | |
buf_size | Size of data buffer. | |
num_values | Number of data values (for arrays). | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 4654 of file odb.c.
Referenced by add_event(), command_loop(), db_paste_node(), db_set_record(), rpc_server_dispatch(), show_create_page(), show_custom_page(), show_elog_page(), show_hist_page(), update_odb(), and write_event_odb().
04655 { 04656 if (rpc_is_remote()) 04657 return rpc_call(RPC_DB_SET_DATA, hDB, hKey, data, buf_size, num_values, type); 04658 04659 #ifdef LOCAL_ROUTINES 04660 { 04661 DATABASE_HEADER *pheader; 04662 KEY *pkey; 04663 HNDLE hkeylink; 04664 int link_idx; 04665 char link_name[256]; 04666 04667 if (hDB > _database_entries || hDB <= 0) { 04668 cm_msg(MERROR, "db_set_data", "invalid database handle"); 04669 return DB_INVALID_HANDLE; 04670 } 04671 04672 if (!_database[hDB - 1].attached) { 04673 cm_msg(MERROR, "db_set_data", "invalid database handle"); 04674 return DB_INVALID_HANDLE; 04675 } 04676 04677 if (hKey < (int) sizeof(DATABASE_HEADER)) { 04678 cm_msg(MERROR, "db_set_data", "invalid key handle"); 04679 return DB_INVALID_HANDLE; 04680 } 04681 04682 if (num_values == 0) 04683 return DB_INVALID_PARAM; 04684 04685 db_lock_database(hDB); 04686 04687 pheader = _database[hDB - 1].database_header; 04688 pkey = (KEY *) ((char *) pheader + hKey); 04689 04690 /* check if hKey argument is correct */ 04691 if (!db_validate_hkey(pheader, hKey)) { 04692 db_unlock_database(hDB); 04693 return DB_INVALID_HANDLE; 04694 } 04695 04696 /* check for write access */ 04697 if (!(pkey->access_mode & MODE_WRITE) || (pkey->access_mode & MODE_EXCLUSIVE)) { 04698 db_unlock_database(hDB); 04699 return DB_NO_ACCESS; 04700 } 04701 04702 /* check for link to array index */ 04703 if (pkey->type == TID_LINK) { 04704 strlcpy(link_name, (char *) pheader + pkey->data, sizeof(link_name)); 04705 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] == ']') { 04706 db_unlock_database(hDB); 04707 if (strchr(link_name, '[') == NULL) 04708 return DB_INVALID_LINK; 04709 link_idx = atoi(strchr(link_name, '[') + 1); 04710 *strchr(link_name, '[') = 0; 04711 if (db_find_key(hDB, 0, link_name, &hkeylink) != DB_SUCCESS) 04712 return DB_INVALID_LINK; 04713 return db_set_data_index(hDB, hkeylink, data, buf_size, link_idx, type); 04714 } 04715 } 04716 04717 if (pkey->type != type) { 04718 db_unlock_database(hDB); 04719 cm_msg(MERROR, "db_set_data", "\"%s\" is of type %s, not %s", 04720 pkey->name, rpc_tid_name(pkey->type), rpc_tid_name(type)); 04721 return DB_TYPE_MISMATCH; 04722 } 04723 04724 /* keys cannot contain data */ 04725 if (pkey->type == TID_KEY) { 04726 db_unlock_database(hDB); 04727 cm_msg(MERROR, "db_set_data", "Key cannot contain data"); 04728 return DB_TYPE_MISMATCH; 04729 } 04730 04731 /* if no buf_size given (Java!), calculate it */ 04732 if (buf_size == 0) 04733 buf_size = pkey->item_size * num_values; 04734 04735 /* resize data size if necessary */ 04736 if (pkey->total_size != buf_size) { 04737 pkey->data = (POINTER_T) realloc_data(pheader, (char *) pheader + pkey->data, pkey->total_size, buf_size); 04738 04739 if (pkey->data == 0) { 04740 db_unlock_database(hDB); 04741 cm_msg(MERROR, "db_set_data", "online database full"); 04742 return DB_FULL; 04743 } 04744 04745 pkey->data -= (POINTER_T) pheader; 04746 pkey->total_size = buf_size; 04747 } 04748 04749 /* set number of values */ 04750 pkey->num_values = num_values; 04751 if (num_values) 04752 pkey->item_size = buf_size / num_values; 04753 04754 /* copy data */ 04755 memcpy((char *) pheader + pkey->data, data, buf_size); 04756 04757 /* update time */ 04758 pkey->last_written = ss_time(); 04759 04760 db_notify_clients(hDB, hKey, TRUE); 04761 db_unlock_database(hDB); 04762 04763 } 04764 #endif /* LOCAL_ROUTINES */ 04765 04766 return DB_SUCCESS; 04767 }
INT db_set_data_index | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const void * | data, | |||
INT | data_size, | |||
INT | idx, | |||
DWORD | type | |||
) |
Set key data for a key which contains an array of values.
This function sets individual values of a key containing an array. If the index is larger than the array size, the array is extended and the intermediate values are set to zero.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer to single value of data. | |
data_size | ||
idx | Size of single data element. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 5006 of file odb.c.
Referenced by add_event(), cm_register_transition(), command_loop(), db_paste_node(), db_set_data(), db_set_value_index(), interprete(), load_parameters(), resize_vars_odb(), rpc_server_dispatch(), save_vars_odb(), show_create_page(), show_custom_page(), show_odb_tag(), and show_sc_page().
05007 { 05008 if (rpc_is_remote()) 05009 return rpc_call(RPC_DB_SET_DATA_INDEX, hDB, hKey, data, data_size, idx, type); 05010 05011 #ifdef LOCAL_ROUTINES 05012 { 05013 DATABASE_HEADER *pheader; 05014 KEY *pkey; 05015 char link_name[256], str[256]; 05016 int link_idx; 05017 HNDLE hkeylink; 05018 05019 if (hDB > _database_entries || hDB <= 0) { 05020 cm_msg(MERROR, "db_set_data_index", "invalid database handle"); 05021 return DB_INVALID_HANDLE; 05022 } 05023 05024 if (!_database[hDB - 1].attached) { 05025 cm_msg(MERROR, "db_set_data_index", "invalid database handle"); 05026 return DB_INVALID_HANDLE; 05027 } 05028 05029 if (hKey < (int) sizeof(DATABASE_HEADER)) { 05030 cm_msg(MERROR, "db_set_data_index", "invalid key handle"); 05031 return DB_INVALID_HANDLE; 05032 } 05033 05034 db_lock_database(hDB); 05035 05036 pheader = _database[hDB - 1].database_header; 05037 pkey = (KEY *) ((char *) pheader + hKey); 05038 05039 /* check if hKey argument is correct */ 05040 if (!db_validate_hkey(pheader, hKey)) { 05041 db_unlock_database(hDB); 05042 return DB_INVALID_HANDLE; 05043 } 05044 05045 /* check for write access */ 05046 if (!(pkey->access_mode & MODE_WRITE) || (pkey->access_mode & MODE_EXCLUSIVE)) { 05047 db_unlock_database(hDB); 05048 return DB_NO_ACCESS; 05049 } 05050 05051 /* check for link to array index */ 05052 if (pkey->type == TID_LINK) { 05053 strlcpy(link_name, (char *) pheader + pkey->data, sizeof(link_name)); 05054 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] == ']') { 05055 db_unlock_database(hDB); 05056 if (strchr(link_name, '[') == NULL) 05057 return DB_INVALID_LINK; 05058 link_idx = atoi(strchr(link_name, '[') + 1); 05059 *strchr(link_name, '[') = 0; 05060 if (db_find_key(hDB, 0, link_name, &hkeylink) != DB_SUCCESS) 05061 return DB_INVALID_LINK; 05062 return db_set_data_index(hDB, hkeylink, data, data_size, link_idx, type); 05063 } 05064 } 05065 05066 if (pkey->type != type) { 05067 db_unlock_database(hDB); 05068 db_get_path(hDB, hKey, str, sizeof(str)); 05069 cm_msg(MERROR, "db_set_data_index", 05070 "\"%s\" is of type %s, not %s", str, rpc_tid_name(pkey->type), rpc_tid_name(type)); 05071 return DB_TYPE_MISMATCH; 05072 } 05073 05074 /* keys cannot contain data */ 05075 if (pkey->type == TID_KEY) { 05076 db_unlock_database(hDB); 05077 cm_msg(MERROR, "db_set_data_index", "key cannot contain data"); 05078 return DB_TYPE_MISMATCH; 05079 } 05080 05081 /* check for valid idx */ 05082 if (idx < 0) { 05083 db_unlock_database(hDB); 05084 cm_msg(MERROR, "db_set_data_index", "invalid index %d", idx); 05085 return DB_FULL; 05086 } 05087 05088 /* check for valid array element size: if new element size 05089 is different from existing size, ODB becomes corrupted */ 05090 if (pkey->item_size != 0 && data_size != pkey->item_size) { 05091 db_unlock_database(hDB); 05092 cm_msg(MERROR, "db_set_data_index", "invalid element data size %d, expected %d", data_size, pkey->item_size); 05093 return DB_TYPE_MISMATCH; 05094 } 05095 05096 /* increase data size if necessary */ 05097 if (idx >= pkey->num_values || pkey->item_size == 0) { 05098 pkey->data = 05099 (POINTER_T) realloc_data(pheader, (char *) pheader + pkey->data, pkey->total_size, data_size * (idx + 1)); 05100 05101 if (pkey->data == 0) { 05102 db_unlock_database(hDB); 05103 cm_msg(MERROR, "db_set_data_index", "online database full"); 05104 return DB_FULL; 05105 } 05106 05107 pkey->data -= (POINTER_T) pheader; 05108 if (!pkey->item_size) 05109 pkey->item_size = data_size; 05110 pkey->total_size = data_size * (idx + 1); 05111 pkey->num_values = idx + 1; 05112 } 05113 05114 /* cut strings which are too long */ 05115 if ((type == TID_STRING || type == TID_LINK) && (int) strlen((char *) data) + 1 > pkey->item_size) 05116 *((char *) data + pkey->item_size - 1) = 0; 05117 05118 /* copy data */ 05119 memcpy((char *) pheader + pkey->data + idx * pkey->item_size, data, pkey->item_size); 05120 05121 /* update time */ 05122 pkey->last_written = ss_time(); 05123 05124 db_notify_clients(hDB, hKey, TRUE); 05125 db_unlock_database(hDB); 05126 05127 } 05128 #endif /* LOCAL_ROUTINES */ 05129 05130 return DB_SUCCESS; 05131 }
INT db_set_link_data | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const void * | data, | |||
INT | buf_size, | |||
INT | num_values, | |||
DWORD | type | |||
) |
Same as db_set_data, but it does not follow a link to an array index
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Buffer from which data gets copied to. | |
buf_size | Size of data buffer. | |
num_values | Number of data values (for arrays). | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 4780 of file odb.c.
Referenced by command_loop(), db_paste(), rpc_server_dispatch(), and show_set_page().
04781 { 04782 if (rpc_is_remote()) 04783 return rpc_call(RPC_DB_SET_LINK_DATA, hDB, hKey, data, buf_size, num_values, type); 04784 04785 #ifdef LOCAL_ROUTINES 04786 { 04787 DATABASE_HEADER *pheader; 04788 KEY *pkey; 04789 04790 if (hDB > _database_entries || hDB <= 0) { 04791 cm_msg(MERROR, "db_set_data", "invalid database handle"); 04792 return DB_INVALID_HANDLE; 04793 } 04794 04795 if (!_database[hDB - 1].attached) { 04796 cm_msg(MERROR, "db_set_data", "invalid database handle"); 04797 return DB_INVALID_HANDLE; 04798 } 04799 04800 if (hKey < (int) sizeof(DATABASE_HEADER)) { 04801 cm_msg(MERROR, "db_set_data", "invalid key handle"); 04802 return DB_INVALID_HANDLE; 04803 } 04804 04805 if (num_values == 0) 04806 return DB_INVALID_PARAM; 04807 04808 db_lock_database(hDB); 04809 04810 pheader = _database[hDB - 1].database_header; 04811 pkey = (KEY *) ((char *) pheader + hKey); 04812 04813 /* check if hKey argument is correct */ 04814 if (!db_validate_hkey(pheader, hKey)) { 04815 db_unlock_database(hDB); 04816 return DB_INVALID_HANDLE; 04817 } 04818 04819 /* check for write access */ 04820 if (!(pkey->access_mode & MODE_WRITE) || (pkey->access_mode & MODE_EXCLUSIVE)) { 04821 db_unlock_database(hDB); 04822 return DB_NO_ACCESS; 04823 } 04824 04825 if (pkey->type != type) { 04826 db_unlock_database(hDB); 04827 cm_msg(MERROR, "db_set_link_data", "\"%s\" is of type %s, not %s", 04828 pkey->name, rpc_tid_name(pkey->type), rpc_tid_name(type)); 04829 return DB_TYPE_MISMATCH; 04830 } 04831 04832 /* keys cannot contain data */ 04833 if (pkey->type == TID_KEY) { 04834 db_unlock_database(hDB); 04835 cm_msg(MERROR, "db_set_link_data", "Key cannot contain data"); 04836 return DB_TYPE_MISMATCH; 04837 } 04838 04839 /* if no buf_size given (Java!), calculate it */ 04840 if (buf_size == 0) 04841 buf_size = pkey->item_size * num_values; 04842 04843 /* resize data size if necessary */ 04844 if (pkey->total_size != buf_size) { 04845 pkey->data = (POINTER_T) realloc_data(pheader, (char *) pheader + pkey->data, pkey->total_size, buf_size); 04846 04847 if (pkey->data == 0) { 04848 db_unlock_database(hDB); 04849 cm_msg(MERROR, "db_set_link_data", "online database full"); 04850 return DB_FULL; 04851 } 04852 04853 pkey->data -= (POINTER_T) pheader; 04854 pkey->total_size = buf_size; 04855 } 04856 04857 /* set number of values */ 04858 pkey->num_values = num_values; 04859 if (num_values) 04860 pkey->item_size = buf_size / num_values; 04861 04862 /* copy data */ 04863 memcpy((char *) pheader + pkey->data, data, buf_size); 04864 04865 /* update time */ 04866 pkey->last_written = ss_time(); 04867 04868 db_notify_clients(hDB, hKey, TRUE); 04869 db_unlock_database(hDB); 04870 04871 } 04872 #endif /* LOCAL_ROUTINES */ 04873 04874 return DB_SUCCESS; 04875 }
INT db_set_link_data_index | ( | HNDLE | hDB, | |
HNDLE | hKey, | |||
const void * | data, | |||
INT | data_size, | |||
INT | idx, | |||
DWORD | type | |||
) |
Same as db_set_data_index, but does not follow links.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer to single value of data. | |
data_size | ||
idx | Size of single data element. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 5145 of file odb.c.
Referenced by command_loop(), rpc_server_dispatch(), set_key(), and show_set_page().
05146 { 05147 if (rpc_is_remote()) 05148 return rpc_call(RPC_DB_SET_LINK_DATA_INDEX, hDB, hKey, data, data_size, idx, type); 05149 05150 #ifdef LOCAL_ROUTINES 05151 { 05152 DATABASE_HEADER *pheader; 05153 KEY *pkey; 05154 char str[256]; 05155 05156 if (hDB > _database_entries || hDB <= 0) { 05157 cm_msg(MERROR, "db_set_data_index", "invalid database handle"); 05158 return DB_INVALID_HANDLE; 05159 } 05160 05161 if (!_database[hDB - 1].attached) { 05162 cm_msg(MERROR, "db_set_data_index", "invalid database handle"); 05163 return DB_INVALID_HANDLE; 05164 } 05165 05166 if (hKey < (int) sizeof(DATABASE_HEADER)) { 05167 cm_msg(MERROR, "db_set_data_index", "invalid key handle"); 05168 return DB_INVALID_HANDLE; 05169 } 05170 05171 db_lock_database(hDB); 05172 05173 pheader = _database[hDB - 1].database_header; 05174 pkey = (KEY *) ((char *) pheader + hKey); 05175 05176 /* check if hKey argument is correct */ 05177 if (!db_validate_hkey(pheader, hKey)) { 05178 db_unlock_database(hDB); 05179 return DB_INVALID_HANDLE; 05180 } 05181 05182 /* check for write access */ 05183 if (!(pkey->access_mode & MODE_WRITE) || (pkey->access_mode & MODE_EXCLUSIVE)) { 05184 db_unlock_database(hDB); 05185 return DB_NO_ACCESS; 05186 } 05187 05188 if (pkey->type != type) { 05189 db_unlock_database(hDB); 05190 db_get_path(hDB, hKey, str, sizeof(str)); 05191 cm_msg(MERROR, "db_set_data_index", 05192 "\"%s\" is of type %s, not %s", str, rpc_tid_name(pkey->type), rpc_tid_name(type)); 05193 return DB_TYPE_MISMATCH; 05194 } 05195 05196 /* keys cannot contain data */ 05197 if (pkey->type == TID_KEY) { 05198 db_unlock_database(hDB); 05199 cm_msg(MERROR, "db_set_data_index", "key cannot contain data"); 05200 return DB_TYPE_MISMATCH; 05201 } 05202 05203 /* check for valid array element size: if new element size 05204 is different from existing size, ODB becomes corrupted */ 05205 if (pkey->item_size != 0 && data_size != pkey->item_size) { 05206 db_unlock_database(hDB); 05207 cm_msg(MERROR, "db_set_data_index", "invalid element data size %d, expected %d", data_size, pkey->item_size); 05208 return DB_TYPE_MISMATCH; 05209 } 05210 05211 /* increase data size if necessary */ 05212 if (idx >= pkey->num_values || pkey->item_size == 0) { 05213 pkey->data = 05214 (POINTER_T) realloc_data(pheader, (char *) pheader + pkey->data, pkey->total_size, data_size * (idx + 1)); 05215 05216 if (pkey->data == 0) { 05217 db_unlock_database(hDB); 05218 cm_msg(MERROR, "db_set_data_index", "online database full"); 05219 return DB_FULL; 05220 } 05221 05222 pkey->data -= (POINTER_T) pheader; 05223 if (!pkey->item_size) 05224 pkey->item_size = data_size; 05225 pkey->total_size = data_size * (idx + 1); 05226 pkey->num_values = idx + 1; 05227 } 05228 05229 /* cut strings which are too long */ 05230 if ((type == TID_STRING || type == TID_LINK) && (int) strlen((char *) data) + 1 > pkey->item_size) 05231 *((char *) data + pkey->item_size - 1) = 0; 05232 05233 /* copy data */ 05234 memcpy((char *) pheader + pkey->data + idx * pkey->item_size, data, pkey->item_size); 05235 05236 /* update time */ 05237 pkey->last_written = ss_time(); 05238 05239 db_notify_clients(hDB, hKey, TRUE); 05240 db_unlock_database(hDB); 05241 05242 } 05243 #endif /* LOCAL_ROUTINES */ 05244 05245 return DB_SUCCESS; 05246 }
Copy a set of keys from local memory to the database.
An ODB sub-tree can be mapped to a C structure automatically via a hot-link using the function db_open_record() or manually with this function. Problems might occur if the ODB sub-tree contains values which don't match the C structure. Although the structure size is checked against the sub-tree size, no checking can be done if the type and order of the values in the structure are the same than those in the ODB sub-tree. Therefore it is recommended to use the function db_create_record() before using this function.
... memset(&lazyst,0,size); if (db_find_key(hDB, pLch->hKey, "Statistics",&hKeyst) == DB_SUCCESS) status = db_set_record(hDB, hKeyst, &lazyst, size, 0); else cm_msg(MERROR,"task","record %s/statistics not found", pLch->name) ...
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
data | Pointer where data is stored. | |
buf_size | Size of data structure, must be obtained via sizeof(RECORD-NAME). | |
align | Byte alignment calculated by the stub and passed to the rpc side to align data according to local machine. Must be zero when called from user level. |
Definition at line 7587 of file odb.c.
Referenced by al_check(), al_reset_alarm(), al_trigger_alarm(), close_channels(), db_open_record(), db_send_changed_records(), lazy_main(), main(), register_equipment(), register_requests(), rpc_server_dispatch(), tr_start(), tr_stop(), update_odb(), and write_event_odb().
07588 { 07589 if (rpc_is_remote()) { 07590 align = ss_get_struct_align(); 07591 return rpc_call(RPC_DB_SET_RECORD, hDB, hKey, data, buf_size, align); 07592 } 07593 #ifdef LOCAL_ROUTINES 07594 { 07595 KEY key; 07596 INT convert_flags; 07597 INT total_size; 07598 void *pdata; 07599 07600 convert_flags = 0; 07601 07602 if (!align) 07603 align = ss_get_struct_align(); 07604 else 07605 /* only convert data if called remotely, as indicated by align != 0 */ 07606 if (rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE) 07607 convert_flags = rpc_get_server_option(RPC_CONVERT_FLAGS); 07608 07609 /* check if key has subkeys */ 07610 db_get_key(hDB, hKey, &key); 07611 if (key.type != TID_KEY) { 07612 /* copy single key */ 07613 if (key.item_size * key.num_values != buf_size) { 07614 cm_msg(MERROR, "db_set_record", "struct size mismatch for \"%s\"", key.name); 07615 return DB_STRUCT_SIZE_MISMATCH; 07616 } 07617 07618 if (convert_flags) { 07619 if (key.num_values > 1) 07620 rpc_convert_data(data, key.type, RPC_FIXARRAY, key.item_size * key.num_values, convert_flags); 07621 else 07622 rpc_convert_single(data, key.type, 0, convert_flags); 07623 } 07624 07625 db_set_data(hDB, hKey, data, key.total_size, key.num_values, key.type); 07626 return DB_SUCCESS; 07627 } 07628 07629 /* check record size */ 07630 db_get_record_size(hDB, hKey, 0, &total_size); 07631 if (total_size != buf_size) { 07632 cm_msg(MERROR, "db_set_record", "struct size mismatch for \"%s\"", key.name); 07633 return DB_STRUCT_SIZE_MISMATCH; 07634 } 07635 07636 /* set subkey data */ 07637 pdata = data; 07638 total_size = 0; 07639 07640 db_lock_database(hDB); 07641 db_recurse_record_tree(hDB, hKey, &pdata, &total_size, align, NULL, TRUE, convert_flags); 07642 db_notify_clients(hDB, hKey, TRUE); 07643 db_unlock_database(hDB); 07644 } 07645 #endif /* LOCAL_ROUTINES */ 07646 07647 return DB_SUCCESS; 07648 }
INT db_set_value | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
const char * | key_name, | |||
const void * | data, | |||
INT | data_size, | |||
INT | num_values, | |||
DWORD | type | |||
) |
Set value of a single key.
The function sets a single value or a whole array to a ODB key. Since the data buffer is of type void, no type checking can be performed by the compiler. Therefore the type has to be explicitly supplied, which is checked against the type stored in the ODB. key_name can contain the full path of a key (like: "/Equipment/Trigger/Settings/Level1") while hkey is zero which refers to the root, or hkey can refer to a sub-directory (like /Equipment/Trigger) and key_name is interpreted relative to that directory like "Settings/Level1".
INT level1; db_set_value(hDB, 0, "/Equipment/Trigger/Settings/Level1", &level1, sizeof(level1), 1, TID_INT);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
key_name | Name of key to search, can contain directories. | |
data | Address of data. | |
data_size | Size of data (in bytes). | |
num_values | Number of data elements. | |
type | Type of key, one of TID_xxx (see Midas Data Types) |
Definition at line 3005 of file odb.c.
Referenced by add_event(), al_trigger_alarm(), analyze_run(), cm_connect_experiment1(), cm_delete_client_info(), cm_register_deferred_transition(), cm_register_transition(), cm_set_client_info(), cm_set_transition_sequence(), cm_set_watchdog_params(), cm_transition1(), command_loop(), db_create_link(), db_get_value(), get_event_id(), lazy_main(), lazy_maintain_check(), log_callback(), log_generate_file_name(), log_write(), main(), mana_init(), process_event(), register_equipment(), rpc_server_dispatch(), set_equipment_status(), show_alarm_page(), show_elog_new(), show_elog_query(), show_hist_config_page(), show_hist_page(), test_write(), tr_start(), and update_odb().
03007 { 03008 if (rpc_is_remote()) 03009 return rpc_call(RPC_DB_SET_VALUE, hDB, hKeyRoot, key_name, data, data_size, num_values, type); 03010 03011 #ifdef LOCAL_ROUTINES 03012 { 03013 DATABASE_HEADER *pheader; 03014 KEY *pkey; 03015 HNDLE hKey; 03016 INT status; 03017 03018 if (num_values == 0) 03019 return DB_INVALID_PARAM; 03020 03021 status = db_find_key(hDB, hKeyRoot, key_name, &hKey); 03022 if (status == DB_NO_KEY) { 03023 db_create_key(hDB, hKeyRoot, key_name, type); 03024 status = db_find_link(hDB, hKeyRoot, key_name, &hKey); 03025 } 03026 03027 if (status != DB_SUCCESS) 03028 return status; 03029 03030 db_lock_database(hDB); 03031 pheader = _database[hDB - 1].database_header; 03032 03033 /* get address from handle */ 03034 pkey = (KEY *) ((char *) pheader + hKey); 03035 03036 /* check for write access */ 03037 if (!(pkey->access_mode & MODE_WRITE) || (pkey->access_mode & MODE_EXCLUSIVE)) { 03038 db_unlock_database(hDB); 03039 return DB_NO_ACCESS; 03040 } 03041 03042 if (pkey->type != type) { 03043 db_unlock_database(hDB); 03044 cm_msg(MERROR, "db_set_value", "\"%s\" is of type %s, not %s", 03045 key_name, rpc_tid_name(pkey->type), rpc_tid_name(type)); 03046 return DB_TYPE_MISMATCH; 03047 } 03048 03049 /* keys cannot contain data */ 03050 if (pkey->type == TID_KEY) { 03051 db_unlock_database(hDB); 03052 cm_msg(MERROR, "db_set_value", "key cannot contain data"); 03053 return DB_TYPE_MISMATCH; 03054 } 03055 03056 if (data_size == 0) { 03057 db_unlock_database(hDB); 03058 cm_msg(MERROR, "db_set_value", "zero data size not allowed"); 03059 return DB_TYPE_MISMATCH; 03060 } 03061 03062 if (type != TID_STRING && type != TID_LINK && data_size != rpc_tid_size(type) * num_values) { 03063 db_unlock_database(hDB); 03064 cm_msg(MERROR, "db_set_value", "data_size (%d) does not match num_values (%d)", data_size, num_values); 03065 return DB_TYPE_MISMATCH; 03066 } 03067 03068 /* resize data size if necessary */ 03069 if (pkey->total_size != data_size) { 03070 pkey->data = (POINTER_T) realloc_data(pheader, (char *) pheader + pkey->data, pkey->total_size, data_size); 03071 03072 if (pkey->data == 0) { 03073 db_unlock_database(hDB); 03074 cm_msg(MERROR, "db_set_value", "online database full"); 03075 return DB_FULL; 03076 } 03077 03078 pkey->data -= (POINTER_T) pheader; 03079 pkey->total_size = data_size; 03080 } 03081 03082 /* set number of values */ 03083 pkey->num_values = num_values; 03084 03085 if (type == TID_STRING || type == TID_LINK) 03086 pkey->item_size = data_size / num_values; 03087 else 03088 pkey->item_size = rpc_tid_size(type); 03089 03090 /* copy data */ 03091 memcpy((char *) pheader + pkey->data, data, data_size); 03092 03093 /* update time */ 03094 pkey->last_written = ss_time(); 03095 03096 db_notify_clients(hDB, hKey, TRUE); 03097 db_unlock_database(hDB); 03098 03099 } 03100 #endif /* LOCAL_ROUTINES */ 03101 03102 return DB_SUCCESS; 03103 }
INT db_set_value_index | ( | HNDLE | hDB, | |
HNDLE | hKeyRoot, | |||
const char * | key_name, | |||
const void * | data, | |||
INT | data_size, | |||
INT | idx, | |||
DWORD | type, | |||
BOOL | trunc | |||
) |
Set single value of an array.
The function sets a single value of an ODB key which is an array. key_name can contain the full path of a key (like: "/Equipment/Trigger/Settings/Level1") while hkey is zero which refers to the root, or hkey can refer to a sub-directory (like /Equipment/Trigger) and key_name is interpreted relative to that directory like "Settings/Level1".
INT level1; db_set_value_index(hDB, 0, "/Equipment/Trigger/Settings/Level1", &level1, sizeof(level1), 15, TID_INT, FALSE);
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKeyRoot | Handle for key where search starts, zero for root. | |
key_name | Name of key to search, can contain directories. | |
data | Address of data. | |
data_size | Size of data (in bytes). | |
index | Array index of value. | |
type | Type of key, one of TID_xxx (see Midas Data Types) | |
truncate | Truncate array to current index if TRUE |
Definition at line 3129 of file odb.c.
03131 { 03132 HNDLE hkey; 03133 03134 db_find_key(hDB, hKeyRoot, key_name, &hkey); 03135 if (!hkey) { 03136 db_create_key(hDB, hKeyRoot, key_name, type); 03137 db_find_key(hDB, hKeyRoot, key_name, &hkey); 03138 assert(hkey); 03139 } 03140 if (trunc) 03141 db_set_num_values(hDB, hkey, idx + 1); 03142 03143 return db_set_data_index(hDB, hkey, data, data_size, idx, type); 03144 }
Convert a database value to a string according to its type.
This function is a convenient way to convert a binary ODB value into a string depending on its type if is not known at compile time. If it is known, the normal sprintf() function can be used.
... for (j=0 ; j<key.num_values ; j++) { db_sprintf(pbuf, pdata, key.item_size, j, key.type); strcat(pbuf, "\n"); } ...
string | output ASCII string of data. | |
data | Value data. | |
data_size | Size of single data element. | |
idx | Index for array data. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 6945 of file odb.c.
Referenced by ascii_write(), cmd_dir(), command_loop(), condition_test(), db_copy(), db_save_xml_key(), dump_write(), evaluate_src(), exec_script(), gen_odb_attachment(), hs_dump(), print_key(), scan_tree(), search_callback(), search_key(), show_custom_gif(), show_custom_page(), show_odb_page(), show_odb_tag(), show_sc_page(), show_set_page(), show_start_page(), and write_event_ascii().
06946 { 06947 if (data_size == 0) 06948 sprintf(string, "<NULL>"); 06949 else 06950 switch (type) { 06951 case TID_BYTE: 06952 sprintf(string, "%d", *(((BYTE *) data) + idx)); 06953 break; 06954 case TID_SBYTE: 06955 sprintf(string, "%d", *(((char *) data) + idx)); 06956 break; 06957 case TID_CHAR: 06958 sprintf(string, "%c", *(((char *) data) + idx)); 06959 break; 06960 case TID_WORD: 06961 sprintf(string, "%u", *(((WORD *) data) + idx)); 06962 break; 06963 case TID_SHORT: 06964 sprintf(string, "%d", *(((short *) data) + idx)); 06965 break; 06966 case TID_DWORD: 06967 sprintf(string, "%u", *(((DWORD *) data) + idx)); 06968 break; 06969 case TID_INT: 06970 sprintf(string, "%d", *(((INT *) data) + idx)); 06971 break; 06972 case TID_BOOL: 06973 sprintf(string, "%c", *(((BOOL *) data) + idx) ? 'y' : 'n'); 06974 break; 06975 case TID_FLOAT: 06976 if (ss_isnan(*(((float *) data) + idx))) 06977 sprintf(string, "NAN"); 06978 else 06979 sprintf(string, "%.7g", *(((float *) data) + idx)); 06980 break; 06981 case TID_DOUBLE: 06982 if (ss_isnan(*(((double *) data) + idx))) 06983 sprintf(string, "NAN"); 06984 else 06985 sprintf(string, "%.16lg", *(((double *) data) + idx)); 06986 break; 06987 case TID_BITFIELD: 06988 /* TBD */ 06989 break; 06990 case TID_STRING: 06991 case TID_LINK: 06992 strlcpy(string, ((char *) data) + data_size * idx, MAX_STRING_LENGTH); 06993 break; 06994 default: 06995 sprintf(string, "<unknown>"); 06996 break; 06997 } 06998 06999 return DB_SUCCESS; 07000 }
INT db_sprintff | ( | char * | string, | |
const char * | format, | |||
const void * | data, | |||
INT | data_size, | |||
INT | idx, | |||
DWORD | type | |||
) |
Same as db_sprintf, but with additional format parameter
string | output ASCII string of data. | |
format | Format specifier passed to sprintf() | |
data | Value data. | |
data_size | Size of single data element. | |
idx | Index for array data. | |
type | Type of key, one of TID_xxx (see Midas Data Types). |
Definition at line 7015 of file odb.c.
Referenced by show_custom_page(), and show_odb_tag().
07016 { 07017 if (data_size == 0) 07018 sprintf(string, "<NULL>"); 07019 else 07020 switch (type) { 07021 case TID_BYTE: 07022 sprintf(string, format, *(((BYTE *) data) + idx)); 07023 break; 07024 case TID_SBYTE: 07025 sprintf(string, format, *(((char *) data) + idx)); 07026 break; 07027 case TID_CHAR: 07028 sprintf(string, format, *(((char *) data) + idx)); 07029 break; 07030 case TID_WORD: 07031 sprintf(string, format, *(((WORD *) data) + idx)); 07032 break; 07033 case TID_SHORT: 07034 sprintf(string, format, *(((short *) data) + idx)); 07035 break; 07036 case TID_DWORD: 07037 sprintf(string, format, *(((DWORD *) data) + idx)); 07038 break; 07039 case TID_INT: 07040 sprintf(string, format, *(((INT *) data) + idx)); 07041 break; 07042 case TID_BOOL: 07043 sprintf(string, format, *(((BOOL *) data) + idx) ? 'y' : 'n'); 07044 break; 07045 case TID_FLOAT: 07046 if (ss_isnan(*(((float *) data) + idx))) 07047 sprintf(string, "NAN"); 07048 else 07049 sprintf(string, format, *(((float *) data) + idx)); 07050 break; 07051 case TID_DOUBLE: 07052 if (ss_isnan(*(((double *) data) + idx))) 07053 sprintf(string, "NAN"); 07054 else 07055 sprintf(string, format, *(((double *) data) + idx)); 07056 break; 07057 case TID_BITFIELD: 07058 /* TBD */ 07059 break; 07060 case TID_STRING: 07061 case TID_LINK: 07062 strlcpy(string, ((char *) data) + data_size * idx, MAX_STRING_LENGTH); 07063 break; 07064 default: 07065 sprintf(string, "<unknown>"); 07066 break; 07067 } 07068 07069 return DB_SUCCESS; 07070 }
INT db_unlock_database | ( | HNDLE | hDB | ) |
Unlock a database via system semaphore calls.
hDB | Handle to the database to unlock |
Definition at line 1456 of file odb.c.
Referenced by cm_check_client(), cm_delete_client_info(), cm_get_watchdog_info(), cm_set_client_info(), cm_set_watchdog_params(), db_close_database(), db_create_key(), db_create_record(), db_delete_key1(), db_enum_key(), db_find_key(), db_get_data(), db_get_data_index(), db_get_key(), db_get_key_info(), db_get_key_time(), db_get_link(), db_get_link_data(), db_get_record(), db_get_record_size(), db_get_value(), db_open_database(), db_set_data(), db_set_data_index(), db_set_link_data(), db_set_link_data_index(), db_set_record(), db_set_value(), and log_system_history().
01457 { 01458 01459 #ifdef LOCAL_ROUTINES 01460 01461 #ifdef CHECK_THREAD_ID 01462 if (_lock_tid == 0) 01463 _lock_tid = ss_gettid(); 01464 01465 assert(_lock_tid == ss_gettid()); 01466 #endif 01467 01468 if (hDB > _database_entries || hDB <= 0) { 01469 cm_msg(MERROR, "db_unlock_database", "invalid database handle"); 01470 return DB_INVALID_HANDLE; 01471 } 01472 #ifdef CHECK_LOCK_COUNT 01473 { 01474 char str[256]; 01475 01476 sprintf(str, "db_unlock_database, lock_cnt=%d", _database[hDB - 1].lock_cnt); 01477 ss_stack_history_entry(str); 01478 } 01479 #endif 01480 01481 if (_database[hDB - 1].lock_cnt == 1) 01482 ss_semaphore_release(_database[hDB - 1].semaphore); 01483 01484 if (_database[hDB - 1].lock_cnt > 0) 01485 _database[hDB - 1].lock_cnt--; 01486 01487 if (_database[hDB - 1].protect) { 01488 ss_shm_protect(_database[hDB - 1].shm_handle, _database[hDB - 1].database_header); 01489 _database[hDB - 1].database_header = NULL; 01490 } 01491 #endif /* LOCAL_ROUTINES */ 01492 return DB_SUCCESS; 01493 }
If called locally, update a record (hDB/hKey) and copy its new contents to the local copy of it.
If called from a server, send a network notification to the client.
hDB | ODB handle obtained via cm_get_experiment_database(). | |
hKey | Handle for key where search starts, zero for root. | |
s | optional server socket |
Definition at line 8664 of file odb.c.
08665 { 08666 INT i, size, convert_flags, status; 08667 char buffer[32]; 08668 NET_COMMAND *nc; 08669 08670 /* check if we are the server */ 08671 if (s) { 08672 convert_flags = rpc_get_server_option(RPC_CONVERT_FLAGS); 08673 08674 if (convert_flags & CF_ASCII) { 08675 sprintf(buffer, "MSG_ODB&%d&%d", hDB, hKey); 08676 send_tcp(s, buffer, strlen(buffer) + 1, 0); 08677 } else { 08678 nc = (NET_COMMAND *) buffer; 08679 08680 nc->header.routine_id = MSG_ODB; 08681 nc->header.param_size = 2 * sizeof(INT); 08682 *((INT *) nc->param) = hDB; 08683 *((INT *) nc->param + 1) = hKey; 08684 08685 if (convert_flags) { 08686 rpc_convert_single(&nc->header.routine_id, TID_DWORD, RPC_OUTGOING, convert_flags); 08687 rpc_convert_single(&nc->header.param_size, TID_DWORD, RPC_OUTGOING, convert_flags); 08688 rpc_convert_single(&nc->param[0], TID_DWORD, RPC_OUTGOING, convert_flags); 08689 rpc_convert_single(&nc->param[4], TID_DWORD, RPC_OUTGOING, convert_flags); 08690 } 08691 08692 /* send the update notification to the client */ 08693 send_tcp(s, buffer, sizeof(NET_COMMAND_HEADER) + 2 * sizeof(INT), 0); 08694 } 08695 08696 return DB_SUCCESS; 08697 } 08698 08699 status = DB_INVALID_HANDLE; 08700 08701 /* check all entries for matching key */ 08702 for (i = 0; i < _record_list_entries; i++) 08703 if (_record_list[i].handle == hKey) { 08704 status = DB_SUCCESS; 08705 08706 /* get updated data if record not opened in write mode */ 08707 if ((_record_list[i].access_mode & MODE_WRITE) == 0) { 08708 size = _record_list[i].buf_size; 08709 if (_record_list[i].data != NULL) 08710 db_get_record(hDB, hKey, _record_list[i].data, &size, 0); 08711 08712 /* call dispatcher if requested */ 08713 if (_record_list[i].dispatcher) 08714 _record_list[i].dispatcher(hDB, hKey, _record_list[i].info); 08715 } 08716 } 08717 08718 return DB_SUCCESS; 08719 }
BOOL equal_ustring | ( | const char * | str1, | |
const char * | str2 | |||
) |
Definition at line 1554 of file odb.c.
Referenced by add_event(), al_check(), bm_open_buffer(), bor(), cm_connect_client(), cm_connect_experiment1(), cm_exist(), cm_get_watchdog_info(), cm_list_experiments(), cm_set_client_info(), cm_shutdown(), cmd_dir(), command_loop(), create_experim_h(), db_check_record(), db_create_key(), db_find_key(), db_get_event_definition(), db_open_database(), db_paste(), db_paste_node(), decode_get(), evaluate_src(), export_hist(), find_odb_tag(), FindIndexByColumnName(), FindIndexByEventName(), FindIndexByTableName(), FindIndexByTagName(), gen_odb_attachment(), generate_hist_graph(), get_event_id(), get_variable_id(), get_variable_id_tags(), MidasHistory::GetEventsFromOdbEvents(), MidasHistory::GetEventsFromOdbTags(), getparam(), MidasHistory::GetTagsFromOdb(), SqlHistory::hs_read_old_style(), interprete(), is_editable(), isparam(), lazy_condition_check(), lazy_copy(), lazy_log_update(), lazy_main(), log_callback(), log_open(), logger_root(), main(), print_help(), register_equipment(), send_icon(), set_equipment_status(), setparam(), show_cnaf_page(), show_custom_gif(), show_custom_page(), show_elog_new(), show_elog_page(), show_elog_submit_query(), show_form_query(), show_header(), show_hist_config_page(), show_hist_page(), show_odb_page(), show_odb_tag(), show_programs_page(), show_query_page(), show_rawfile(), show_sc_page(), show_set_page(), show_start_page(), show_status_page(), submit_form(), tr_start(), unsetparam(), and MidasHistory::xhs_event_id().
01555 { 01556 if (str1 == NULL && str2 != NULL) 01557 return FALSE; 01558 if (str1 != NULL && str2 == NULL) 01559 return FALSE; 01560 if (str1 == NULL && str2 == NULL) 01561 return TRUE; 01562 if (strlen(str1) != strlen(str2)) 01563 return FALSE; 01564 01565 while (*str1) 01566 if (toupper(*str1++) != toupper(*str2++)) 01567 return FALSE; 01568 01569 if (*str2) 01570 return FALSE; 01571 01572 return TRUE; 01573 }
const char* extract_key | ( | const char * | key_list, | |
char * | key_name, | |||
int | key_name_length | |||
) |
Definition at line 1540 of file odb.c.
Referenced by db_create_key(), and db_find_key().
01541 { 01542 int i = 0; 01543 01544 if (*key_list == '/') 01545 key_list++; 01546 01547 while (*key_list && *key_list != '/' && ++i < key_name_length) 01548 *key_name++ = *key_list++; 01549 *key_name = 0; 01550 01551 return key_list; 01552 }
void xml_encode | ( | char * | src, | |
int | size | |||
) |
Definition at line 6573 of file odb.c.
06574 { 06575 int i; 06576 char *dst, *p; 06577 06578 dst = (char *) malloc(size); 06579 if (dst == NULL) 06580 return; 06581 06582 *dst = 0; 06583 for (i = 0; i < (int) strlen(src); i++) { 06584 switch (src[i]) { 06585 case '<': 06586 strlcat(dst, "<", size); 06587 break; 06588 case '>': 06589 strlcat(dst, ">", size); 06590 break; 06591 case '&': 06592 strlcat(dst, "&", size); 06593 break; 06594 case '\"': 06595 strlcat(dst, """, size); 06596 break; 06597 case '\'': 06598 strlcat(dst, "'", size); 06599 break; 06600 default: 06601 if ((int) strlen(dst) >= size) { 06602 free(dst); 06603 return; 06604 } 06605 p = dst + strlen(dst); 06606 *p = src[i]; 06607 *(p + 1) = 0; 06608 } 06609 } 06610 06611 strlcpy(src, dst, size); 06612 }