/* * __session_rename -- * WT_SESSION->rename method. */ static int __session_rename(WT_SESSION *wt_session, const char *uri, const char *newname, const char *config) { WT_SESSION_IMPL *session; int ret; session = (WT_SESSION_IMPL *)wt_session; SESSION_API_CALL(session, rename, config, cfg); ret = __wt_schema_rename(session, uri, newname, cfg); err: API_END_NOTFOUND_MAP(session, ret); }
/* * __session_rename -- * WT_SESSION->rename method. */ static int __session_rename(WT_SESSION *wt_session, const char *uri, const char *newname, const char *config) { WT_DECL_RET; WT_SESSION_IMPL *session; session = (WT_SESSION_IMPL *)wt_session; SESSION_API_CALL(session, rename, config, cfg); WT_WITH_SCHEMA_LOCK(session, ret = __wt_schema_rename(session, uri, newname, cfg)); err: API_END_NOTFOUND_MAP(session, ret); }
/* * __rename_tree -- * Rename an index or colgroup reference. */ static int __rename_tree(WT_SESSION_IMPL *session, WT_TABLE *table, const char *newuri, const char *name, const char *cfg[]) { WT_CONFIG_ITEM cval; WT_DECL_ITEM(nn); WT_DECL_ITEM(ns); WT_DECL_ITEM(nv); WT_DECL_ITEM(os); WT_DECL_RET; bool is_colgroup; const char *newname, *olduri, *suffix; char *value; olduri = table->name; value = NULL; newname = newuri; (void)WT_PREFIX_SKIP(newname, "table:"); /* * Create the new data source URI and update the schema value. * * 'name' has the format (colgroup|index):<tablename>[:<suffix>]; * we need the suffix. */ is_colgroup = WT_PREFIX_MATCH(name, "colgroup:"); if (!is_colgroup && !WT_PREFIX_MATCH(name, "index:")) WT_ERR_MSG(session, EINVAL, "expected a 'colgroup:' or 'index:' source: '%s'", name); suffix = strchr(name, ':'); /* An existing table should have a well formed name. */ WT_ASSERT(session, suffix != NULL); suffix = strchr(suffix + 1, ':'); WT_ERR(__wt_scr_alloc(session, 0, &nn)); WT_ERR(__wt_buf_fmt(session, nn, "%s%s%s", is_colgroup ? "colgroup:" : "index:", newname, (suffix == NULL) ? "" : suffix)); /* Skip the colon, if any. */ if (suffix != NULL) ++suffix; /* Read the old schema value. */ WT_ERR(__wt_metadata_search(session, name, &value)); /* * Calculate the new data source URI. Use the existing table structure * and substitute the new name temporarily. */ WT_ERR(__wt_scr_alloc(session, 0, &ns)); table->name = newuri; if (is_colgroup) WT_ERR(__wt_schema_colgroup_source( session, table, suffix, value, ns)); else WT_ERR(__wt_schema_index_source( session, table, suffix, value, ns)); if ((ret = __wt_config_getones(session, value, "source", &cval)) != 0) WT_ERR_MSG(session, EINVAL, "index or column group has no data source: %s", value); /* Take a copy of the old data source. */ WT_ERR(__wt_scr_alloc(session, 0, &os)); WT_ERR(__wt_buf_fmt(session, os, "%.*s", (int)cval.len, cval.str)); /* Overwrite it with the new data source. */ WT_ERR(__wt_scr_alloc(session, 0, &nv)); WT_ERR(__wt_buf_fmt(session, nv, "%.*s%s%s", (int)WT_PTRDIFF(cval.str, value), value, (const char *)ns->data, cval.str + cval.len)); /* * Do the rename before updating the metadata to avoid leaving the * metadata inconsistent if the rename fails. */ WT_ERR(__wt_schema_rename(session, os->data, ns->data, cfg)); /* * Remove the old metadata entry. * Insert the new metadata entry. */ WT_ERR(__wt_metadata_remove(session, name)); WT_ERR(__wt_metadata_insert(session, nn->data, nv->data)); err: __wt_scr_free(session, &nn); __wt_scr_free(session, &ns); __wt_scr_free(session, &nv); __wt_scr_free(session, &os); __wt_free(session, value); table->name = olduri; return (ret); }
/* * __wt_lsm_tree_rename -- * Rename an LSM tree. */ int __wt_lsm_tree_rename(WT_SESSION_IMPL *session, const char *oldname, const char *newname, const char *cfg[]) { WT_DECL_RET; WT_ITEM buf; WT_LSM_CHUNK *chunk; WT_LSM_TREE *lsm_tree; const char *old; u_int i; int locked; old = NULL; WT_CLEAR(buf); locked = 0; /* Get the LSM tree. */ WT_RET(__wt_lsm_tree_get(session, oldname, 1, &lsm_tree)); /* Shut down the LSM worker. */ WT_ERR(__lsm_tree_close(session, lsm_tree)); /* Prevent any new opens. */ WT_ERR(__wt_try_writelock(session, lsm_tree->rwlock)); locked = 1; /* Set the new name. */ WT_ERR(__lsm_tree_set_name(session, lsm_tree, newname)); /* Rename the chunks. */ for (i = 0; i < lsm_tree->nchunks; i++) { chunk = lsm_tree->chunk[i]; old = chunk->uri; chunk->uri = NULL; WT_ERR(__wt_lsm_tree_chunk_name( session, lsm_tree, chunk->id, &buf)); chunk->uri = __wt_buf_steal(session, &buf, NULL); WT_ERR(__wt_schema_rename(session, old, chunk->uri, cfg)); __wt_free(session, old); if (F_ISSET(chunk, WT_LSM_CHUNK_BLOOM)) { old = chunk->bloom_uri; chunk->bloom_uri = NULL; WT_ERR(__wt_lsm_tree_bloom_name( session, lsm_tree, chunk->id, &buf)); chunk->bloom_uri = __wt_buf_steal(session, &buf, NULL); F_SET(chunk, WT_LSM_CHUNK_BLOOM); WT_ERR(__wt_schema_rename( session, old, chunk->uri, cfg)); __wt_free(session, old); } } ret = __wt_rwunlock(session, lsm_tree->rwlock); locked = 0; if (ret == 0) ret = __wt_lsm_meta_write(session, lsm_tree); if (ret == 0) ret = __wt_metadata_remove(session, oldname); err: if (locked) WT_TRET(__wt_rwunlock(session, lsm_tree->rwlock)); if (old != NULL) __wt_free(session, old); /* * Discard this LSM tree structure. The first operation on the renamed * tree will create a new one. */ WT_TRET(__lsm_tree_discard(session, lsm_tree)); return (ret); }