svn_error_t * svn_fs_bdb__miscellaneous_set(svn_fs_t *fs, const char *key_str, const char *val, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; svn_fs_base__str_to_dbt(&key, key_str); if (val == NULL) { svn_fs_base__trail_debug(trail, "miscellaneous", "del"); return BDB_WRAP(fs, N_("deleting record from 'miscellaneous' table"), bfd->miscellaneous->del(bfd->miscellaneous, trail->db_txn, &key, 0)); } else { svn_fs_base__str_to_dbt(&value, val); svn_fs_base__trail_debug(trail, "miscellaneous", "add"); return BDB_WRAP(fs, N_("storing miscellaneous record"), bfd->miscellaneous->put(bfd->miscellaneous, trail->db_txn, &key, &value, 0)); } }
svn_error_t * svn_fs_bdb__read_rep(representation_t **rep_p, svn_fs_t *fs, const char *key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; svn_skel_t *skel; int db_err; DBT query, result; svn_fs_base__trail_debug(trail, "representations", "get"); db_err = bfd->representations->get(bfd->representations, trail->db_txn, svn_fs_base__str_to_dbt(&query, key), svn_fs_base__result_dbt(&result), 0); svn_fs_base__track_dbt(&result, pool); /* If there's no such node, return an appropriately specific error. */ if (db_err == DB_NOTFOUND) return svn_error_createf (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0, _("No such representation '%s'"), key); /* Handle any other error conditions. */ SVN_ERR(BDB_WRAP(fs, _("reading representation"), db_err)); /* Parse the REPRESENTATION skel. */ skel = svn_skel__parse(result.data, result.size, pool); /* Convert to a native type. */ return svn_fs_base__parse_representation_skel(rep_p, skel, pool); }
/* Get the current 'next-key' value and bump the record. */ static svn_error_t * get_key_and_bump(svn_fs_t *fs, const char **key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBC *cursor; char next_key[MAX_KEY_SIZE]; apr_size_t key_len; int db_err; DBT query; DBT result; /* ### todo: see issue #409 for why bumping the key as part of this trail is problematic. */ /* Open a cursor and move it to the 'next-key' value. We can then fetch the contents and use the cursor to overwrite those contents. Since this database allows duplicates, we can't do an arbitrary 'put' to write the new value -- that would append, not overwrite. */ svn_fs_base__trail_debug(trail, "strings", "cursor"); SVN_ERR(BDB_WRAP(fs, N_("creating cursor for reading a string"), bfd->strings->cursor(bfd->strings, trail->db_txn, &cursor, 0))); /* Advance the cursor to 'next-key' and read it. */ db_err = svn_bdb_dbc_get(cursor, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__result_dbt(&result), DB_SET); if (db_err) { svn_bdb_dbc_close(cursor); return BDB_WRAP(fs, N_("getting next-key value"), db_err); } svn_fs_base__track_dbt(&result, pool); *key = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ key_len = result.size; svn_fs_base__next_key(result.data, &key_len, next_key); /* Shove the new key back into the database, at the cursor position. */ db_err = svn_bdb_dbc_put(cursor, &query, svn_fs_base__str_to_dbt(&result, next_key), DB_CURRENT); if (db_err) { svn_bdb_dbc_close(cursor); /* ignore the error, the original is more important. */ return BDB_WRAP(fs, N_("bumping next string key"), db_err); } return BDB_WRAP(fs, N_("closing string-reading cursor"), svn_bdb_dbc_close(cursor)); }
svn_error_t * svn_fs_bdb__miscellaneous_get(const char **val, svn_fs_t *fs, const char *key_str, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; *val = NULL; svn_fs_base__trail_debug(trail, "miscellaneous", "get"); db_err = bfd->miscellaneous->get(bfd->miscellaneous, trail->db_txn, svn_fs_base__str_to_dbt(&key, key_str), svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err != DB_NOTFOUND) { SVN_ERR(BDB_WRAP(fs, N_("fetching miscellaneous record"), db_err)); *val = apr_pstrmemdup(pool, value.data, value.size); } return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__string_append(svn_fs_t *fs, const char **key, apr_size_t len, const char *buf, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; /* If the passed-in key is NULL, we graciously generate a new string using the value of the `next-key' record in the strings table. */ if (*key == NULL) { SVN_ERR(get_key_and_bump(fs, key, trail, pool)); } /* Store a new record into the database. */ svn_fs_base__trail_debug(trail, "strings", "put"); return BDB_WRAP(fs, N_("appending string"), bfd->strings->put (bfd->strings, trail->db_txn, svn_fs_base__str_to_dbt(&query, *key), svn_fs_base__set_dbt(&result, buf, len), 0)); }
svn_error_t * svn_fs_bdb__delete_rep(svn_fs_t *fs, const char *key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; int db_err; DBT query; svn_fs_base__trail_debug(trail, "representations", "del"); db_err = bfd->representations->del (bfd->representations, trail->db_txn, svn_fs_base__str_to_dbt(&query, key), 0); /* If there's no such node, return an appropriately specific error. */ if (db_err == DB_NOTFOUND) return svn_error_createf (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0, _("No such representation '%s'"), key); /* Handle any other error conditions. */ SVN_ERR(BDB_WRAP(fs, _("deleting representation"), db_err)); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__write_rep(svn_fs_t *fs, const char *key, const representation_t *rep, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; skel_t *skel; /* Convert from native type to skel. */ SVN_ERR(svn_fs_base__unparse_representation_skel(&skel, rep, pool)); /* Now write the record. */ svn_fs_base__trail_debug(trail, "representations", "put"); SVN_ERR(BDB_WRAP(fs, _("storing representation"), bfd->representations->put (bfd->representations, trail->db_txn, svn_fs_base__str_to_dbt(&query, key), svn_fs_base__skel_to_dbt(&result, skel, pool), 0))); return SVN_NO_ERROR; }
svn_error_t *svn_fs_bdb__get_checksum_rep(const char **rep_key, svn_fs_t *fs, svn_checksum_t *checksum, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; /* We only allow SHA1 checksums in this table. */ if (checksum->kind != svn_checksum_sha1) return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL, _("Only SHA1 checksums can be used as keys in the " "checksum-reps table.\n")); svn_fs_base__trail_debug(trail, "checksum-reps", "get"); db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn, svn_fs_base__checksum_to_dbt(&key, checksum), svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err == DB_NOTFOUND) return svn_fs_base__err_no_such_checksum_rep(fs, checksum); *rep_key = apr_pstrmemdup(pool, value.data, value.size); return SVN_NO_ERROR; }
svn_error_t *svn_fs_bdb__set_node_origin(svn_fs_t *fs, const char *node_id, const svn_fs_id_t *origin_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; /* Create a key from our NODE_ID. */ svn_fs_base__str_to_dbt(&key, node_id); /* Check to see if we already have a mapping for NODE_ID. If so, and the value is the same one we were about to write. That's cool -- just do nothing. If, however, the value is *different*, that's a red flag! */ svn_fs_base__trail_debug(trail, "node-origins", "get"); db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn, &key, svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err != DB_NOTFOUND) { const svn_string_t *origin_id_str = svn_fs_base__id_unparse(origin_id, pool); const svn_string_t *old_origin_id_str = svn_string_ncreate(value.data, value.size, pool); if (! svn_string_compare(origin_id_str, old_origin_id_str)) return svn_error_createf (SVN_ERR_FS_CORRUPT, NULL, _("Node origin for '%s' exists in filesystem '%s' with a different " "value (%s) than what we were about to store (%s)"), node_id, fs->path, old_origin_id_str->data, origin_id_str->data); else return SVN_NO_ERROR; } /* Create a value from our ORIGIN_ID, and add this record to the table. */ svn_fs_base__id_to_dbt(&value, origin_id, pool); svn_fs_base__trail_debug(trail, "node-origins", "put"); SVN_ERR(BDB_WRAP(fs, _("storing node-origins record"), bfd->node_origins->put(bfd->node_origins, trail->db_txn, &key, &value, 0))); return SVN_NO_ERROR; }
svn_error_t *svn_fs_bdb__set_checksum_rep(svn_fs_t *fs, svn_checksum_t *checksum, const char *rep_key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; /* We only allow SHA1 checksums in this table. */ if (checksum->kind != svn_checksum_sha1) return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL, _("Only SHA1 checksums can be used as keys in the " "checksum-reps table.\n")); /* Create a key from our CHECKSUM. */ svn_fs_base__checksum_to_dbt(&key, checksum); /* Check to see if we already have a mapping for CHECKSUM. If so, and the value is the same one we were about to write, that's cool -- just do nothing. If, however, the value is *different*, that's a red flag! */ svn_fs_base__trail_debug(trail, "checksum-reps", "get"); db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn, &key, svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err != DB_NOTFOUND) { const char *sum_str = svn_checksum_to_cstring_display(checksum, pool); return svn_error_createf (SVN_ERR_FS_ALREADY_EXISTS, NULL, _("Representation key for checksum '%s' exists in filesystem '%s'."), sum_str, fs->path); } /* Create a value from our REP_KEY, and add this record to the table. */ svn_fs_base__str_to_dbt(&value, rep_key); svn_fs_base__trail_debug(trail, "checksum-reps", "put"); SVN_ERR(BDB_WRAP(fs, _("storing checksum-reps record"), bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn, &key, &value, 0))); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__write_new_rep(const char **key, svn_fs_t *fs, const representation_t *rep, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; int db_err; apr_size_t len; char next_key[MAX_KEY_SIZE]; /* ### todo: see issue #409 for why bumping the key as part of this trail is problematic. */ /* Get the current value associated with `next-key'. */ svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__trail_debug(trail, "representations", "get"); SVN_ERR(BDB_WRAP(fs, _("allocating new representation (getting next-key)"), bfd->representations->get (bfd->representations, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Store the new rep. */ *key = apr_pstrmemdup(pool, result.data, result.size); SVN_ERR(svn_fs_bdb__write_rep(fs, *key, rep, trail, pool)); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "representations", "put"); db_err = bfd->representations->put (bfd->representations, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); SVN_ERR(BDB_WRAP(fs, _("bumping next representation key"), db_err)); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__new_node_id(svn_fs_id_t **id_p, svn_fs_t *fs, const char *copy_id, const char *txn_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; const char *next_node_id; SVN_ERR_ASSERT(txn_id); /* Get the current value associated with the `next-key' key in the table. */ svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__trail_debug(trail, "nodes", "get"); SVN_ERR(BDB_WRAP(fs, N_("allocating new node ID (getting 'next-key')"), bfd->nodes->get(bfd->nodes, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Squirrel away our next node id value. */ next_node_id = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "nodes", "put"); db_err = bfd->nodes->put(bfd->nodes, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); SVN_ERR(BDB_WRAP(fs, N_("bumping next node ID key"), db_err)); /* Create and return the new node id. */ *id_p = svn_fs_base__id_create(next_node_id, copy_id, txn_id, pool); return SVN_NO_ERROR; }
svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p, svn_fs_t *fs, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); /* Get the current value associated with the `next-key' key in the `checksum-reps' table. */ svn_fs_base__trail_debug(trail, "checksum-reps", "get"); SVN_ERR(BDB_WRAP(fs, _("allocating new representation reuse ID " "(getting 'next-key')"), bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Set our return value. */ *id_p = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "checksum_reps", "put"); db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); return BDB_WRAP(fs, _("bumping next copy key"), db_err); }
/* Allocate a Subversion transaction ID in FS, as part of TRAIL. Set *ID_P to the new transaction ID, allocated in POOL. */ static svn_error_t * allocate_txn_id(const char **id_p, svn_fs_t *fs, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); /* Get the current value associated with the `next-key' key in the table. */ svn_fs_base__trail_debug(trail, "transactions", "get"); SVN_ERR(BDB_WRAP(fs, "allocating new transaction ID (getting 'next-key')", bfd->transactions->get(bfd->transactions, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Set our return value. */ *id_p = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__str_to_dbt(&result, next_key); svn_fs_base__trail_debug(trail, "transactions", "put"); db_err = bfd->transactions->put(bfd->transactions, trail->db_txn, &query, &result, 0); return BDB_WRAP(fs, "bumping next transaction key", db_err); }
svn_error_t *svn_fs_bdb__delete_node_origin(svn_fs_t *fs, const char *node_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; svn_fs_base__str_to_dbt(&key, node_id); svn_fs_base__trail_debug(trail, "node-origins", "del"); SVN_ERR(BDB_WRAP(fs, "deleting entry from 'node-origins' table", bfd->node_origins->del(bfd->node_origins, trail->db_txn, &key, 0))); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__string_clear(svn_fs_t *fs, const char *key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; int db_err; DBT query, result; svn_fs_base__str_to_dbt(&query, key); /* Torch the prior contents */ svn_fs_base__trail_debug(trail, "strings", "del"); db_err = bfd->strings->del(bfd->strings, trail->db_txn, &query, 0); /* If there's no such node, return an appropriately specific error. */ if (db_err == DB_NOTFOUND) return svn_error_createf (SVN_ERR_FS_NO_SUCH_STRING, 0, "No such string '%s'", key); /* Handle any other error conditions. */ SVN_ERR(BDB_WRAP(fs, N_("clearing string"), db_err)); /* Shove empty data back in for this key. */ svn_fs_base__clear_dbt(&result); result.data = 0; result.size = 0; result.flags |= DB_DBT_USERMEM; svn_fs_base__trail_debug(trail, "strings", "put"); return BDB_WRAP(fs, N_("storing empty contents"), bfd->strings->put(bfd->strings, trail->db_txn, &query, &result, 0)); }
/* Removing node revisions. */ svn_error_t * svn_fs_bdb__delete_nodes_entry(svn_fs_t *fs, const svn_fs_id_t *id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; svn_fs_base__trail_debug(trail, "nodes", "del"); return BDB_WRAP(fs, N_("deleting entry from 'nodes' table"), bfd->nodes->del(bfd->nodes, trail->db_txn, svn_fs_base__id_to_dbt(&key, id, pool), 0)); }
svn_error_t * svn_fs_bdb__delete_copy(svn_fs_t *fs, const char *copy_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; int db_err; svn_fs_base__str_to_dbt(&key, copy_id); svn_fs_base__trail_debug(trail, "copies", "del"); db_err = bfd->copies->del(bfd->copies, trail->db_txn, &key, 0); if (db_err == DB_NOTFOUND) return svn_fs_base__err_no_such_copy(fs, copy_id); return BDB_WRAP(fs, N_("deleting entry from 'copies' table"), db_err); }
svn_error_t * svn_fs_bdb__lock_delete(svn_fs_t *fs, const char *lock_token, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; int db_err; svn_fs_base__str_to_dbt(&key, lock_token); svn_fs_base__trail_debug(trail, "locks", "del"); db_err = bfd->locks->del(bfd->locks, trail->db_txn, &key, 0); if (db_err == DB_NOTFOUND) return svn_fs_base__err_bad_lock_token(fs, lock_token); return BDB_WRAP(fs, "deleting lock from 'locks' table", db_err); }
svn_error_t * svn_fs_bdb__lock_get(svn_lock_t **lock_p, svn_fs_t *fs, const char *lock_token, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; svn_skel_t *skel; svn_lock_t *lock; svn_fs_base__trail_debug(trail, "lock", "get"); db_err = bfd->locks->get(bfd->locks, trail->db_txn, svn_fs_base__str_to_dbt(&key, lock_token), svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err == DB_NOTFOUND) return svn_fs_base__err_bad_lock_token(fs, lock_token); SVN_ERR(BDB_WRAP(fs, "reading lock", db_err)); /* Parse TRANSACTION skel */ skel = svn_skel__parse(value.data, value.size, pool); if (! skel) return svn_fs_base__err_corrupt_lock(fs, lock_token); /* Convert skel to native type. */ SVN_ERR(svn_fs_base__parse_lock_skel(&lock, skel, pool)); /* Possibly auto-expire the lock. */ if (lock->expiration_date && (apr_time_now() > lock->expiration_date)) { SVN_ERR(svn_fs_bdb__lock_delete(fs, lock_token, trail, pool)); return SVN_FS__ERR_LOCK_EXPIRED(fs, lock_token); } *lock_p = lock; return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__lock_add(svn_fs_t *fs, const char *lock_token, svn_lock_t *lock, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; svn_skel_t *lock_skel; DBT key, value; /* Convert native type to skel. */ SVN_ERR(svn_fs_base__unparse_lock_skel(&lock_skel, lock, pool)); svn_fs_base__str_to_dbt(&key, lock_token); svn_fs_base__skel_to_dbt(&value, lock_skel, pool); svn_fs_base__trail_debug(trail, "lock", "add"); return BDB_WRAP(fs, "storing lock record", bfd->locks->put(bfd->locks, trail->db_txn, &key, &value, 0)); }
svn_error_t *svn_fs_bdb__delete_checksum_rep(svn_fs_t *fs, svn_checksum_t *checksum, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; /* We only allow SHA1 checksums in this table. */ if (checksum->kind != svn_checksum_sha1) return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL, _("Only SHA1 checksums can be used as keys in the " "checksum-reps table.\n")); svn_fs_base__checksum_to_dbt(&key, checksum); svn_fs_base__trail_debug(trail, "checksum-reps", "del"); SVN_ERR(BDB_WRAP(fs, "deleting entry from 'checksum-reps' table", bfd->checksum_reps->del(bfd->checksum_reps, trail->db_txn, &key, 0))); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__get_node_revision(node_revision_t **noderev_p, svn_fs_t *fs, const svn_fs_id_t *id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; node_revision_t *noderev; svn_skel_t *skel; int db_err; DBT key, value; svn_fs_base__trail_debug(trail, "nodes", "get"); db_err = bfd->nodes->get(bfd->nodes, trail->db_txn, svn_fs_base__id_to_dbt(&key, id, pool), svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); /* If there's no such node, return an appropriately specific error. */ if (db_err == DB_NOTFOUND) return svn_fs_base__err_dangling_id(fs, id); /* Handle any other error conditions. */ SVN_ERR(BDB_WRAP(fs, N_("reading node revision"), db_err)); /* If our caller doesn't really care about the return value here, just return successfully. */ if (! noderev_p) return SVN_NO_ERROR; /* Parse and the NODE-REVISION skel. */ skel = svn_skel__parse(value.data, value.size, pool); /* Convert to a native FS type. */ SVN_ERR(svn_fs_base__parse_node_revision_skel(&noderev, skel, pool)); *noderev_p = noderev; return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__delete_txn(svn_fs_t *fs, const char *txn_name, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key; transaction_t *txn; /* Make sure TXN is dead. */ SVN_ERR(svn_fs_bdb__get_txn(&txn, fs, txn_name, trail, pool)); if (is_committed(txn)) return svn_fs_base__err_txn_not_mutable(fs, txn_name); /* Delete the transaction from the `transactions' table. */ svn_fs_base__str_to_dbt(&key, txn_name); svn_fs_base__trail_debug(trail, "transactions", "del"); return BDB_WRAP(fs, "deleting entry from 'transactions' table", bfd->transactions->del(bfd->transactions, trail->db_txn, &key, 0)); }
svn_error_t * svn_fs_bdb__changes_add(svn_fs_t *fs, const char *key, change_t *change, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, value; svn_skel_t *skel; /* Convert native type to skel. */ SVN_ERR(svn_fs_base__unparse_change_skel(&skel, change, pool)); /* Store a new record into the database. */ svn_fs_base__str_to_dbt(&query, key); svn_fs_base__skel_to_dbt(&value, skel, pool); svn_fs_base__trail_debug(trail, "changes", "put"); return BDB_WRAP(fs, N_("creating change"), bfd->changes->put(bfd->changes, trail->db_txn, &query, &value, 0)); }
svn_error_t *svn_fs_bdb__get_node_origin(const svn_fs_id_t **origin_id, svn_fs_t *fs, const char *node_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT key, value; int db_err; svn_fs_base__trail_debug(trail, "node-origins", "get"); db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn, svn_fs_base__str_to_dbt(&key, node_id), svn_fs_base__result_dbt(&value), 0); svn_fs_base__track_dbt(&value, pool); if (db_err == DB_NOTFOUND) return svn_fs_base__err_no_such_node_origin(fs, node_id); *origin_id = svn_fs_base__id_parse(value.data, value.size, pool); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__string_delete(svn_fs_t *fs, const char *key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; int db_err; DBT query; svn_fs_base__trail_debug(trail, "strings", "del"); db_err = bfd->strings->del(bfd->strings, trail->db_txn, svn_fs_base__str_to_dbt(&query, key), 0); /* If there's no such node, return an appropriately specific error. */ if (db_err == DB_NOTFOUND) return svn_error_createf (SVN_ERR_FS_NO_SUCH_STRING, 0, "No such string '%s'", key); /* Handle any other error conditions. */ return BDB_WRAP(fs, N_("deleting string"), db_err); }
svn_error_t * svn_fs_bdb__put_txn(svn_fs_t *fs, const transaction_t *txn, const char *txn_name, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; svn_skel_t *txn_skel; DBT key, value; /* Convert native type to skel. */ SVN_ERR(svn_fs_base__unparse_transaction_skel(&txn_skel, txn, pool)); /* Only in the context of this function do we know that the DB call will not attempt to modify txn_name, so the cast belongs here. */ svn_fs_base__str_to_dbt(&key, txn_name); svn_fs_base__skel_to_dbt(&value, txn_skel, pool); svn_fs_base__trail_debug(trail, "transactions", "put"); return BDB_WRAP(fs, _("storing transaction record"), bfd->transactions->put(bfd->transactions, trail->db_txn, &key, &value, 0)); }
/* ### only has one caller; might not need to be abstracted */ static svn_error_t * put_copy(svn_fs_t *fs, const copy_t *copy, const char *copy_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; svn_skel_t *copy_skel; DBT key, value; /* Convert native type to skel. */ SVN_ERR(svn_fs_base__unparse_copy_skel(©_skel, copy, pool)); /* Only in the context of this function do we know that the DB call will not attempt to modify COPY_ID, so the cast belongs here. */ svn_fs_base__str_to_dbt(&key, copy_id); svn_fs_base__skel_to_dbt(&value, copy_skel, pool); svn_fs_base__trail_debug(trail, "copies", "put"); return BDB_WRAP(fs, N_("storing copy record"), bfd->copies->put(bfd->copies, trail->db_txn, &key, &value, 0)); }
svn_error_t * svn_fs_bdb__changes_delete(svn_fs_t *fs, const char *key, trail_t *trail, apr_pool_t *pool) { int db_err; DBT query; base_fs_data_t *bfd = fs->fsap_data; svn_fs_base__trail_debug(trail, "changes", "del"); db_err = bfd->changes->del(bfd->changes, trail->db_txn, svn_fs_base__str_to_dbt(&query, key), 0); /* If there're no changes for KEY, that is acceptable. Any other error should be propagated to the caller, though. */ if ((db_err) && (db_err != DB_NOTFOUND)) { SVN_ERR(BDB_WRAP(fs, N_("deleting changes"), db_err)); } return SVN_NO_ERROR; }