Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_fs_base/revs-txns.c view on Meta::CPAN
}
struct change_rev_prop_args {
svn_revnum_t rev;
const char *name;
const svn_string_t *const *old_value_p;
const svn_string_t *value;
};
static svn_error_t *
txn_body_change_rev_prop(void *baton, trail_t *trail)
{
struct change_rev_prop_args *args = baton;
return svn_fs_base__set_rev_prop(trail->fs, args->rev,
args->name, args->old_value_p, args->value,
trail, trail->pool);
}
svn_error_t *
svn_fs_base__change_rev_prop(svn_fs_t *fs,
svn_revnum_t rev,
const char *name,
const svn_string_t *const *old_value_p,
const svn_string_t *value,
apr_pool_t *pool)
{
struct change_rev_prop_args args;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
args.rev = rev;
args.name = name;
args.old_value_p = old_value_p;
args.value = value;
return svn_fs_base__retry_txn(fs, txn_body_change_rev_prop, &args,
TRUE, pool);
}
/*** Transactions ***/
svn_error_t *
svn_fs_base__txn_make_committed(svn_fs_t *fs,
const char *txn_name,
svn_revnum_t revision,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
/* Make sure the TXN is not committed already. */
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
/* Convert TXN to a committed transaction. */
txn->base_id = NULL;
txn->revision = revision;
txn->kind = transaction_kind_committed;
return put_txn(fs, txn, txn_name, trail, pool);
}
svn_error_t *
svn_fs_base__txn_get_revision(svn_revnum_t *revision,
svn_fs_t *fs,
const char *txn_name,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
*revision = txn->revision;
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__get_txn_ids(const svn_fs_id_t **root_id_p,
const svn_fs_id_t **base_root_id_p,
svn_fs_t *fs,
const char *txn_name,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
*root_id_p = txn->root_id;
*base_root_id_p = txn->base_id;
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__set_txn_root(svn_fs_t *fs,
const char *txn_name,
const svn_fs_id_t *new_id,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
if (! svn_fs_base__id_eq(txn->root_id, new_id))
{
txn->root_id = new_id;
SVN_ERR(put_txn(fs, txn, txn_name, trail, pool));
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__set_txn_base(svn_fs_t *fs,
const char *txn_name,
const svn_fs_id_t *new_id,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
if (! svn_fs_base__id_eq(txn->base_id, new_id))
{
txn->base_id = new_id;
SVN_ERR(put_txn(fs, txn, txn_name, trail, pool));
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__add_txn_copy(svn_fs_t *fs,
const char *txn_name,
const char *copy_id,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
/* Get the transaction and ensure its mutability. */
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
/* Allocate a new array if this transaction has no copies. */
if (! txn->copies)
txn->copies = apr_array_make(pool, 1, sizeof(copy_id));
/* Add COPY_ID to the array. */
APR_ARRAY_PUSH(txn->copies, const char *) = copy_id;
/* Finally, write out the transaction. */
return put_txn(fs, txn, txn_name, trail, pool);
}
/* Generic transaction operations. */
struct txn_proplist_args {
apr_hash_t **table_p;
const char *id;
};
static svn_error_t *
txn_body_txn_proplist(void *baton, trail_t *trail)
{
transaction_t *txn;
struct txn_proplist_args *args = baton;
SVN_ERR(get_txn(&txn, trail->fs, args->id, FALSE, trail, trail->pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(trail->fs, args->id);
*(args->table_p) = txn->proplist;
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__txn_proplist_in_trail(apr_hash_t **table_p,
const char *txn_id,
trail_t *trail)
{
struct txn_proplist_args args;
apr_hash_t *table;
args.table_p = &table;
args.id = txn_id;
SVN_ERR(txn_body_txn_proplist(&args, trail));
*table_p = table ? table : apr_hash_make(trail->pool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__txn_proplist(apr_hash_t **table_p,
svn_fs_txn_t *txn,
apr_pool_t *pool)
{
struct txn_proplist_args args;
apr_hash_t *table;
svn_fs_t *fs = txn->fs;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
args.table_p = &table;
args.id = txn->id;
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_txn_proplist, &args,
FALSE, pool));
*table_p = table ? table : apr_hash_make(pool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_base__txn_prop(svn_string_t **value_p,
svn_fs_txn_t *txn,
const char *propname,
apr_pool_t *pool)
{
struct txn_proplist_args args;
apr_hash_t *table;
svn_fs_t *fs = txn->fs;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
/* Get the proplist. */
args.table_p = &table;
args.id = txn->id;
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_txn_proplist, &args,
FALSE, pool));
/* And then the prop from that list (if there was a list). */
*value_p = svn_hash_gets(table, propname);
return SVN_NO_ERROR;
}
struct change_txn_prop_args {
svn_fs_t *fs;
const char *id;
const char *name;
const svn_string_t *value;
};
svn_error_t *
svn_fs_base__set_txn_prop(svn_fs_t *fs,
const char *txn_name,
const char *name,
const svn_string_t *value,
trail_t *trail,
apr_pool_t *pool)
{
transaction_t *txn;
SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
if (txn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(fs, txn_name);
/* If there's no proplist, but we're just deleting a property, exit now. */
if ((! txn->proplist) && (! value))
return SVN_NO_ERROR;
/* Now, if there's no proplist, we know we need to make one. */
if (! txn->proplist)
txn->proplist = apr_hash_make(pool);
/* Set the property. */
svn_hash_sets(txn->proplist, name, value);
/* Now overwrite the transaction. */
return put_txn(fs, txn, txn_name, trail, pool);
}
static svn_error_t *
txn_body_change_txn_prop(void *baton, trail_t *trail)
{
struct change_txn_prop_args *args = baton;
return svn_fs_base__set_txn_prop(trail->fs, args->id, args->name,
args->value, trail, trail->pool);
}
svn_error_t *
svn_fs_base__change_txn_prop(svn_fs_txn_t *txn,
const char *name,
const svn_string_t *value,
apr_pool_t *pool)
{
struct change_txn_prop_args args;
svn_fs_t *fs = txn->fs;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
args.id = txn->id;
args.name = name;
args.value = value;
return svn_fs_base__retry_txn(fs, txn_body_change_txn_prop, &args,
TRUE, pool);
}
svn_error_t *
svn_fs_base__change_txn_props(svn_fs_txn_t *txn,
const apr_array_header_t *props,
apr_pool_t *pool)
{
apr_pool_t *iterpool = svn_pool_create(pool);
int i;
for (i = 0; i < props->nelts; i++)
{
svn_prop_t *prop = &APR_ARRAY_IDX(props, i, svn_prop_t);
svn_pool_clear(iterpool);
SVN_ERR(svn_fs_base__change_txn_prop(txn, prop->name,
src/subversion/subversion/libsvn_fs_base/revs-txns.c view on Meta::CPAN
}
svn_error_t *
svn_fs_base__purge_txn(svn_fs_t *fs,
const char *txn_id,
apr_pool_t *pool)
{
struct cleanup_txn_args args;
transaction_t *txn;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
/* Open the transaction, expecting it to be dead. */
args.txn_p = &txn;
args.name = txn_id;
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_cleanup_txn, &args,
FALSE, pool));
/* Delete the mutable portion of the tree hanging from the
transaction (which should gracefully recover if we've already
done this). */
SVN_ERR(delete_txn_tree(fs, txn->root_id, txn_id, pool));
/* Kill the transaction's changes (which should gracefully recover
if...). */
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_cleanup_txn_changes,
&txn_id, TRUE, pool));
/* Kill the transaction's copies (which should gracefully...). */
if (txn->copies)
{
int i;
for (i = 0; i < txn->copies->nelts; i++)
{
SVN_ERR(svn_fs_base__retry_txn
(fs, txn_body_cleanup_txn_copy,
&APR_ARRAY_IDX(txn->copies, i, const char *),
TRUE, pool));
}
}
/* Kill the transaction itself (which ... just kidding -- this has
no graceful failure mode). */
return svn_fs_base__retry_txn(fs, txn_body_delete_txn, &txn_id,
TRUE, pool);
}
static svn_error_t *
txn_body_abort_txn(void *baton, trail_t *trail)
{
svn_fs_txn_t *txn = baton;
transaction_t *fstxn;
/* Get the transaction by its id, set it to "dead", and store the
transaction. */
SVN_ERR(get_txn(&fstxn, txn->fs, txn->id, FALSE, trail, trail->pool));
if (fstxn->kind != transaction_kind_normal)
return svn_fs_base__err_txn_not_mutable(txn->fs, txn->id);
fstxn->kind = transaction_kind_dead;
return put_txn(txn->fs, fstxn, txn->id, trail, trail->pool);
}
svn_error_t *
svn_fs_base__abort_txn(svn_fs_txn_t *txn,
apr_pool_t *pool)
{
SVN_ERR(svn_fs__check_fs(txn->fs, TRUE));
/* Set the transaction to "dead". */
SVN_ERR(svn_fs_base__retry_txn(txn->fs, txn_body_abort_txn, txn,
TRUE, pool));
/* Now, purge it. */
SVN_ERR_W(svn_fs_base__purge_txn(txn->fs, txn->id, pool),
_("Transaction aborted, but cleanup failed"));
return SVN_NO_ERROR;
}
struct list_transactions_args
{
apr_array_header_t **names_p;
apr_pool_t *pool;
};
static svn_error_t *
txn_body_list_transactions(void* baton, trail_t *trail)
{
struct list_transactions_args *args = baton;
return svn_fs_bdb__get_txn_list(args->names_p, trail->fs,
trail, args->pool);
}
svn_error_t *
svn_fs_base__list_transactions(apr_array_header_t **names_p,
svn_fs_t *fs,
apr_pool_t *pool)
{
apr_array_header_t *names;
struct list_transactions_args args;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
args.names_p = &names;
args.pool = pool;
SVN_ERR(svn_fs_base__retry(fs, txn_body_list_transactions, &args,
FALSE, pool));
*names_p = names;
return SVN_NO_ERROR;
}
( run in 0.876 second using v1.01-cache-2.11-cpan-524268b4103 )