⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 revs-txns.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* revs-txns.c : operations on revision and transactions * * ==================================================================== * Copyright (c) 2000-2004 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <assert.h>#include <string.h>#include <apr_tables.h>#include <apr_pools.h>#include "svn_pools.h"#include "svn_time.h"#include "svn_fs.h"#include "svn_props.h"#include "fs.h"#include "dag.h"#include "err.h"#include "trail.h"#include "tree.h"#include "revs-txns.h"#include "key-gen.h"#include "id.h"#include "bdb/rev-table.h"#include "bdb/txn-table.h"#include "bdb/copies-table.h"#include "bdb/changes-table.h"#include "../libsvn_fs/fs-loader.h"#include "svn_private_config.h"/*** Helpers ***//* Set *txn_p to a transaction object allocated in POOL for the   transaction in FS whose id is TXN_ID.  If EXPECT_DEAD is set, this   transaction must be a dead one, else an error is returned.  If   EXPECT_DEAD is not set, an error is thrown if the transaction is   *not* dead. */static svn_error_t *get_txn(transaction_t **txn_p,        svn_fs_t *fs,        const char *txn_id,        svn_boolean_t expect_dead,        trail_t *trail,        apr_pool_t *pool){  transaction_t *txn;  SVN_ERR(svn_fs_bdb__get_txn(&txn, fs, txn_id, trail, pool));  if (expect_dead && (txn->kind != transaction_kind_dead))    return svn_error_createf(SVN_ERR_FS_TRANSACTION_NOT_DEAD, 0,                             _("Transaction is not dead: '%s'"), txn_id);  if ((! expect_dead) && (txn->kind == transaction_kind_dead))    return svn_error_createf(SVN_ERR_FS_TRANSACTION_DEAD, 0,                             _("Transaction is dead: '%s'"), txn_id);  *txn_p = txn;  return SVN_NO_ERROR;}/* This is only for symmetry with the get_txn() helper. */#define put_txn svn_fs_bdb__put_txn/*** Revisions ***//* Return the committed transaction record *TXN_P and its ID *TXN_ID   (as long as those parameters aren't NULL) for the revision REV in   FS as part of TRAIL.  */static svn_error_t *get_rev_txn(transaction_t **txn_p,            const char **txn_id,            svn_fs_t *fs,            svn_revnum_t rev,            trail_t *trail,            apr_pool_t *pool){  revision_t *revision;  transaction_t *txn;  SVN_ERR(svn_fs_bdb__get_rev(&revision, fs, rev, trail, pool));  if (revision->txn_id == NULL)    return svn_fs_base__err_corrupt_fs_revision(fs, rev);  SVN_ERR(get_txn(&txn, fs, revision->txn_id, FALSE, trail, pool));  if (txn->revision != rev)    return svn_fs_base__err_corrupt_txn(fs, revision->txn_id);  if (txn_p)    *txn_p = txn;  if (txn_id)    *txn_id = revision->txn_id;  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__rev_get_root(const svn_fs_id_t **root_id_p,                          svn_fs_t *fs,                          svn_revnum_t rev,                          trail_t *trail,                          apr_pool_t *pool){  transaction_t *txn;  SVN_ERR(get_rev_txn(&txn, NULL, fs, rev, trail, pool));  if (txn->root_id == NULL)    return svn_fs_base__err_corrupt_fs_revision(fs, rev);  *root_id_p = txn->root_id;  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__rev_get_txn_id(const char **txn_id_p,                            svn_fs_t *fs,                            svn_revnum_t rev,                            trail_t *trail,                            apr_pool_t *pool){  revision_t *revision;  SVN_ERR(svn_fs_bdb__get_rev(&revision, fs, rev, trail, pool));  if (revision->txn_id == NULL)    return svn_fs_base__err_corrupt_fs_revision(fs, rev);  *txn_id_p = revision->txn_id;  return SVN_NO_ERROR;}static svn_error_t *txn_body_youngest_rev(void *baton, trail_t *trail){  return svn_fs_bdb__youngest_rev(baton, trail->fs, trail, trail->pool);}svn_error_t *svn_fs_base__youngest_rev(svn_revnum_t *youngest_p,                          svn_fs_t *fs,                          apr_pool_t *pool){  svn_revnum_t youngest;  SVN_ERR(svn_fs_base__check_fs(fs));  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_youngest_rev, &youngest,                                 pool));  *youngest_p = youngest;  return SVN_NO_ERROR;}struct revision_proplist_args {  apr_hash_t **table_p;  svn_revnum_t rev;};static svn_error_t *txn_body_revision_proplist(void *baton, trail_t *trail){  struct revision_proplist_args *args = baton;  transaction_t *txn;  SVN_ERR(get_rev_txn(&txn, NULL, trail->fs, args->rev, trail, trail->pool));  *(args->table_p) = txn->proplist;  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__revision_proplist(apr_hash_t **table_p,                               svn_fs_t *fs,                               svn_revnum_t rev,                               apr_pool_t *pool){  struct revision_proplist_args args;  apr_hash_t *table;  SVN_ERR(svn_fs_base__check_fs(fs));  args.table_p = &table;  args.rev = rev;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args,                                 pool));  *table_p = table ? table : apr_hash_make(pool);  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__revision_prop(svn_string_t **value_p,                           svn_fs_t *fs,                           svn_revnum_t rev,                           const char *propname,                           apr_pool_t *pool){  struct revision_proplist_args args;  apr_hash_t *table;  SVN_ERR(svn_fs_base__check_fs(fs));  /* Get the proplist. */  args.table_p = &table;  args.rev = rev;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args,                                 pool));  /* And then the prop from that list (if there was a list). */  *value_p = NULL;  if (table)    *value_p = apr_hash_get(table, propname, APR_HASH_KEY_STRING);  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__set_rev_prop(svn_fs_t *fs,                          svn_revnum_t rev,                          const char *name,                          const svn_string_t *value,                          trail_t *trail,                          apr_pool_t *pool){  transaction_t *txn;  const char *txn_id;  SVN_ERR(get_rev_txn(&txn, &txn_id, fs, rev, trail, pool));  /* 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. */  apr_hash_set(txn->proplist, name, APR_HASH_KEY_STRING, value);  /* Overwrite the revision. */  return put_txn(fs, txn, txn_id, trail, pool);}struct change_rev_prop_args {  svn_revnum_t rev;  const char *name;  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;  SVN_ERR(svn_fs_base__set_rev_prop(trail->fs, args->rev,                                    args->name, args->value,                                     trail, trail->pool));  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__change_rev_prop(svn_fs_t *fs,                             svn_revnum_t rev,                             const char *name,                             const svn_string_t *value,                             apr_pool_t *pool){  struct change_rev_prop_args args;  SVN_ERR(svn_fs_base__check_fs(fs));  args.rev = rev;  args.name = name;  args.value = value;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_change_rev_prop, &args, pool));  return SVN_NO_ERROR;}/*** 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;  /* Don't you dare call this with an invalid REVISION. */  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. */  (*((const char **)(apr_array_push(txn->copies)))) = 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_base__check_fs(fs));  args.table_p = &table;  args.id = txn->id;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_txn_proplist, &args, 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_base__check_fs(fs));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -