diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/schema/schema_drop.c')
-rw-r--r-- | src/third_party/wiredtiger/src/schema/schema_drop.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/src/schema/schema_drop.c b/src/third_party/wiredtiger/src/schema/schema_drop.c new file mode 100644 index 00000000000..6df7e6930c9 --- /dev/null +++ b/src/third_party/wiredtiger/src/schema/schema_drop.c @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#include "wt_internal.h" + +/* + * __drop_file -- + * Drop a file. + */ +static int +__drop_file( + WT_SESSION_IMPL *session, const char *uri, int force, const char *cfg[]) +{ + WT_CONFIG_ITEM cval; + WT_DECL_RET; + int exist, remove_files; + const char *filename; + + WT_RET(__wt_config_gets(session, cfg, "remove_files", &cval)); + remove_files = (cval.val != 0); + + filename = uri; + if (!WT_PREFIX_SKIP(filename, "file:")) + return (EINVAL); + + /* Close all btree handles associated with this file. */ + WT_RET(__wt_conn_dhandle_close_all(session, uri, force)); + + /* Remove the metadata entry (ignore missing items). */ + WT_TRET(__wt_metadata_remove(session, uri)); + if (force && ret == WT_NOTFOUND) + ret = 0; + + if (!remove_files) + return (ret); + + /* Remove the underlying physical file. */ + exist = 0; + WT_TRET(__wt_exist(session, filename, &exist)); + if (exist) { + /* + * There is no point tracking this operation: there is no going + * back from here. + */ + WT_TRET(__wt_remove(session, filename)); + } + + return (ret); +} + +/* + * __drop_colgroup -- + * WT_SESSION::drop for a colgroup. + */ +static int +__drop_colgroup( + WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) +{ + WT_COLGROUP *colgroup; + WT_DECL_RET; + WT_TABLE *table; + + /* If we can get the colgroup, detach it from the table. */ + if ((ret = __wt_schema_get_colgroup( + session, uri, &table, &colgroup)) == 0) { + table->cg_complete = 0; + WT_TRET(__wt_schema_drop(session, colgroup->source, cfg)); + } + + WT_TRET(__wt_metadata_remove(session, uri)); + return (ret); +} + +/* + * __drop_index -- + * WT_SESSION::drop for a colgroup. + */ +static int +__drop_index( + WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) +{ + WT_INDEX *idx; + WT_DECL_RET; + WT_TABLE *table; + + /* If we can get the colgroup, detach it from the table. */ + if ((ret = __wt_schema_get_index(session, uri, &table, &idx)) == 0) { + table->idx_complete = 0; + WT_TRET(__wt_schema_drop(session, idx->source, cfg)); + } + + WT_TRET(__wt_metadata_remove(session, uri)); + return (ret); +} + +/* + * __drop_table -- + * WT_SESSION::drop for a table. + */ +static int +__drop_table( + WT_SESSION_IMPL *session, const char *uri, int force, const char *cfg[]) +{ + WT_COLGROUP *colgroup; + WT_DECL_RET; + WT_INDEX *idx; + WT_TABLE *table; + const char *name; + u_int i; + + name = uri; + (void)WT_PREFIX_SKIP(name, "table:"); + + table = NULL; + WT_ERR(__wt_schema_get_table(session, name, strlen(name), 1, &table)); + + /* Drop the column groups. */ + for (i = 0; i < WT_COLGROUPS(table); i++) { + if ((colgroup = table->cgroups[i]) == NULL) + continue; + WT_ERR(__wt_metadata_remove(session, colgroup->name)); + WT_ERR(__wt_schema_drop(session, colgroup->source, cfg)); + } + + /* Drop the indices. */ + WT_ERR(__wt_schema_open_indices(session, table)); + for (i = 0; i < table->nindices; i++) { + if ((idx = table->indices[i]) == NULL) + continue; + WT_ERR(__wt_metadata_remove(session, idx->name)); + WT_ERR(__wt_schema_drop(session, idx->source, cfg)); + } + + __wt_schema_remove_table(session, table); + table = NULL; + + /* Remove the metadata entry (ignore missing items). */ + WT_ERR(__wt_metadata_remove(session, uri)); + +err: if (force && ret == WT_NOTFOUND) + ret = 0; + if (table != NULL) + __wt_schema_release_table(session, table); + return (ret); +} + +/* + * __wt_schema_drop -- + * Process a WT_SESSION::drop operation for all supported types. + */ +int +__wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) +{ + WT_CONFIG_ITEM cval; + WT_DATA_SOURCE *dsrc; + WT_DECL_RET; + int force; + + WT_RET(__wt_config_gets_def(session, cfg, "force", 0, &cval)); + force = (cval.val != 0); + + WT_RET(__wt_meta_track_on(session)); + + /* Be careful to ignore any btree handle in our caller. */ + WT_CLEAR_BTREE_IN_SESSION(session); + + if (WT_PREFIX_MATCH(uri, "colgroup:")) + ret = __drop_colgroup(session, uri, cfg); + else if (WT_PREFIX_MATCH(uri, "file:")) + ret = __drop_file(session, uri, force, cfg); + else if (WT_PREFIX_MATCH(uri, "index:")) + ret = __drop_index(session, uri, cfg); + else if (WT_PREFIX_MATCH(uri, "lsm:")) + ret = __wt_lsm_tree_drop(session, uri, cfg); + else if (WT_PREFIX_MATCH(uri, "table:")) + ret = __drop_table(session, uri, force, cfg); + else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL) + ret = dsrc->drop == NULL ? + __wt_object_unsupported(session, uri) : + dsrc->drop( + dsrc, &session->iface, uri, (WT_CONFIG_ARG *)cfg); + else + ret = __wt_bad_object_type(session, uri); + + /* + * Map WT_NOTFOUND to ENOENT (or to 0 if "force" is set), based on the + * assumption WT_NOTFOUND means there was no metadata entry. The + * underlying drop functions should handle this case (we passed them + * the "force" value), but better safe than sorry. + */ + if (ret == WT_NOTFOUND) + ret = force ? 0 : ENOENT; + + /* Bump the schema generation so that stale data is ignored. */ + ++S2C(session)->schema_gen; + + WT_TRET(__wt_meta_track_off(session, ret != 0)); + + return (ret); +} |