int mdb_index_delete(mdb_table_t *tbl, mdb_row_t *row) { mdb_index_t *ix; int lgh; void *key; mdb_hash_t *hash; mdb_sequence_t *seq; MDB_CHECKARG(tbl && row, -1); ix = &tbl->index; if (!MDB_INDEX_DEFINED(ix)) return 0; hash = ix->hash; seq = ix->sequence; lgh = ix->length; key = (void *)row->data + ix->offset; if (mdb_hash_delete(hash, lgh,key) != row || mdb_sequence_delete(seq, lgh,key) != row) { errno = EIO; return -1; } return 0; }
int mqi_drop_table(mqi_handle_t h) { mqi_table_t *tbl; mqi_db_functbl_t *ftb; char *name; void *data; void *cursor; int sts; MDB_CHECKARG(h != MDB_HANDLE_INVALID, -1); MDB_PREREQUISITE(dbs && ndb > 0, -1); if (!(tbl = mdb_handle_delete(table_handle, h))) return -1; ftb = tbl->db->functbl; MDB_HASH_TABLE_FOR_EACH_WITH_KEY_SAFE(table_name_hash, data,name, cursor) { if ((mqi_handle_t)(data - NULL) == h) { mdb_hash_delete(table_name_hash, 0,name); sts = ftb->drop_table(tbl->handle); free(name); free(tbl); return sts; } } return -1; }
static mqi_handle_t delete_handle(char *name) { void *ptr; if (init() < 0) return MQI_HANDLE_INVALID; if (!(ptr = mdb_hash_delete(transact_handles, 0,name))) return MQI_HANDLE_INVALID; return PTR_TO_HANDLE(ptr); }
int mdb_index_insert(mdb_table_t *tbl, mdb_row_t *row, mqi_bitfld_t cmask, int ignore) { mdb_index_t *ix; int lgh; void *key; mdb_hash_t *hash; mdb_sequence_t *seq; mdb_row_t *old; uint32_t txdepth; MDB_CHECKARG(tbl && row, -1); ix = &tbl->index; if (!MDB_INDEX_DEFINED(ix)) return 1; /* fake a sucessful insertion */ hash = ix->hash; seq = ix->sequence; lgh = ix->length; key = (void *)row->data + ix->offset; if (mdb_hash_add(hash, lgh,key, row) == 0) { mdb_sequence_add(seq, lgh,key, row); return 1; } /* * we have a duplicate at hand */ if (ignore) { /* replace the duplicate with the new row */ /* TODO: move the transaction & log related stuff to table, ie. here deal with indexes only */ if ((txdepth = mdb_transaction_get_depth()) < 1) { errno = EIO; return -1; } if (!(old = mdb_hash_delete(hash, lgh,key)) || (old != mdb_sequence_delete(seq, lgh,key))) { /* something is really broken: get out quickly */ errno = EIO; return -1; } else { if (mdb_row_delete(tbl, old, 0,0) < 0 || mdb_log_change(tbl, txdepth, mdb_log_update,cmask,old,row) < 0) { /* errno is either EEXIST or ENOMEM set by mdb_hash_add */ return -1; } mdb_hash_add(hash, lgh,key, row); mdb_sequence_add(seq, lgh,key, row); } } else { /* duplicate insertion is an error. keep the original row */ mdb_row_delete(tbl, row, 0, 1); /* errno is either EEXIST or ENOMEM set by mdb_hash_add */ return -1; } return 0; }
mqi_handle_t mqi_create_table(char *name, uint32_t flags, char **index_columns, mqi_column_def_t *cdefs) { mqi_db_t *db; mqi_db_functbl_t *ftb; mqi_table_t *tbl = NULL; mqi_handle_t h = MQI_HANDLE_INVALID; char *namedup = NULL; int i; MDB_CHECKARG(name && cdefs, MQI_HANDLE_INVALID); MDB_PREREQUISITE(dbs && ndb > 0, MQI_HANDLE_INVALID); for (i = 0, ftb = NULL; i < ndb; i++) { db = dbs + i; if ((DB_TYPE(db) & flags) != 0) { ftb = db->functbl; break; } } MDB_ASSERT(ftb, ENOENT, MQI_HANDLE_INVALID); if(!(tbl = calloc(1, sizeof(mqi_table_t)))) return MQI_HANDLE_INVALID; tbl->db = db; tbl->handle = NULL; if (!(namedup = strdup(name))) goto cleanup; if (!(tbl->handle = ftb->create_table(name, index_columns, cdefs))) goto cleanup; if ((h = mdb_handle_add(table_handle, tbl)) == MQI_HANDLE_INVALID) goto cleanup; if (mdb_hash_add(table_name_hash, 0,namedup, NULL + h) < 0) { mdb_handle_delete(table_handle, h); h = MQI_HANDLE_INVALID; } ftb->register_table_handle(tbl->handle, h); return h; cleanup: if (tbl) { if (tbl->handle) { mdb_handle_delete(table_handle, h); ftb->drop_table(tbl->handle); } mdb_hash_delete(table_name_hash, 0,name); free(namedup); free(tbl); } return MDB_HANDLE_INVALID; }