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

📄 revs-txns.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Get the proplist. */  args.table_p = &table;  args.id = txn->id;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_txn_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;}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. */  apr_hash_set(txn->proplist, name, APR_HASH_KEY_STRING, 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_base__check_fs(fs));  args.id = txn->id;  args.name = name;  args.value = value;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_change_txn_prop, &args, pool));  return SVN_NO_ERROR;}/* Creating a transaction */txn_vtable_t txn_vtable = {  svn_fs_base__commit_txn,  svn_fs_base__abort_txn,  svn_fs_base__txn_prop,  svn_fs_base__txn_proplist,  svn_fs_base__change_txn_prop,  svn_fs_base__txn_root};/* Allocate and return a new transaction object in POOL for FS whose   transaction ID is ID.  ID is not copied.  */static svn_fs_txn_t *make_txn(svn_fs_t *fs,         const char *id,         svn_revnum_t base_rev,         apr_pool_t *pool){  svn_fs_txn_t *txn = apr_pcalloc(pool, sizeof(*txn));  txn->fs = fs;  txn->id = id;  txn->base_rev = base_rev;  txn->vtable = &txn_vtable;  txn->fsap_data = NULL;  return txn;}struct begin_txn_args{  svn_fs_txn_t **txn_p;  svn_revnum_t rev;  apr_uint32_t flags;};static svn_error_t *txn_body_begin_txn(void *baton, trail_t *trail){  struct begin_txn_args *args = baton;  const svn_fs_id_t *root_id;  const char *txn_id;  SVN_ERR(svn_fs_base__rev_get_root(&root_id, trail->fs, args->rev,                                     trail, trail->pool));  SVN_ERR(svn_fs_bdb__create_txn(&txn_id, trail->fs, root_id,                                  trail, trail->pool));  if (args->flags & SVN_FS_TXN_CHECK_OOD)    {      struct change_txn_prop_args cpargs;      cpargs.fs = trail->fs;      cpargs.id = txn_id;      cpargs.name = SVN_FS_PROP_TXN_CHECK_OOD;      cpargs.value = svn_string_create("true", trail->pool);      SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));    }  if (args->flags & SVN_FS_TXN_CHECK_LOCKS)    {      struct change_txn_prop_args cpargs;      cpargs.fs = trail->fs;      cpargs.id = txn_id;      cpargs.name = SVN_FS_PROP_TXN_CHECK_LOCKS;      cpargs.value = svn_string_create("true", trail->pool);      SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));    }      *args->txn_p = make_txn(trail->fs, txn_id, args->rev, trail->pool);  return SVN_NO_ERROR;}/* Note:  it is acceptable for this function to call back into   public FS API interfaces because it does not itself use trails.  */svn_error_t *svn_fs_base__begin_txn(svn_fs_txn_t **txn_p,                       svn_fs_t *fs,                       svn_revnum_t rev,                       apr_uint32_t flags,                       apr_pool_t *pool){  svn_fs_txn_t *txn;  struct begin_txn_args args;  svn_string_t date;  SVN_ERR(svn_fs_base__check_fs(fs));  args.txn_p = &txn;  args.rev   = rev;  args.flags = flags;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_begin_txn, &args, pool));  *txn_p = txn;  /* Put a datestamp on the newly created txn, so we always know     exactly how old it is.  (This will help sysadmins identify     long-abandoned txns that may need to be manually removed.)  When     a txn is promoted to a revision, this property will be     automatically overwritten with a revision datestamp. */  date.data = svn_time_to_cstring(apr_time_now(), pool);  date.len = strlen(date.data);  SVN_ERR(svn_fs_base__change_txn_prop(txn, SVN_PROP_REVISION_DATE,                                       &date, pool));  return SVN_NO_ERROR;}struct open_txn_args{  svn_fs_txn_t **txn_p;  const char *name;};static svn_error_t *txn_body_open_txn(void *baton, trail_t *trail){  struct open_txn_args *args = baton;  transaction_t *fstxn;  svn_revnum_t base_rev = SVN_INVALID_REVNUM;  const char *txn_id;  SVN_ERR(get_txn(&fstxn, trail->fs, args->name, FALSE, trail, trail->pool));  if (fstxn->kind != transaction_kind_committed)    {      txn_id = svn_fs_base__id_txn_id(fstxn->base_id);      SVN_ERR(svn_fs_base__txn_get_revision(&base_rev, trail->fs, txn_id,                                            trail, trail->pool));    }    *args->txn_p = make_txn(trail->fs, args->name, base_rev, trail->pool);  return SVN_NO_ERROR;}svn_error_t *svn_fs_base__open_txn(svn_fs_txn_t **txn_p,                      svn_fs_t *fs,                      const char *name,                      apr_pool_t *pool){  svn_fs_txn_t *txn;  struct open_txn_args args;  SVN_ERR(svn_fs_base__check_fs(fs));  args.txn_p = &txn;  args.name = name;  SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_open_txn, &args, pool));  *txn_p = txn;  return SVN_NO_ERROR;}struct cleanup_txn_args{  transaction_t **txn_p;  const char *name;};static svn_error_t *txn_body_cleanup_txn(void *baton, trail_t *trail){  struct cleanup_txn_args *args = baton;  return get_txn(args->txn_p, trail->fs, args->name, TRUE,                  trail, trail->pool);}static svn_error_t *txn_body_cleanup_txn_copy(void *baton, trail_t *trail){  svn_error_t *err = svn_fs_bdb__delete_copy(trail->fs, baton, trail,                                              trail->pool);  /* Copy doesn't exist?  No sweat. */  if (err && (err->apr_err == SVN_ERR_FS_NO_SUCH_COPY))    {      svn_error_clear(err);      err = SVN_NO_ERROR;    }  return err;}static svn_error_t *txn_body_cleanup_txn_changes(void *baton, trail_t *trail){  return svn_fs_bdb__changes_delete(trail->fs, baton, trail, trail->pool);}struct get_dirents_args{  apr_hash_t **dirents;  const svn_fs_id_t *id;  const char *txn_id;};static svn_error_t *txn_body_get_dirents(void *baton, trail_t *trail){  struct get_dirents_args *args = baton;  dag_node_t *node;  /* Get the node. */  SVN_ERR(svn_fs_base__dag_get_node(&node, trail->fs, args->id,                                     trail, trail->pool));  /* If immutable, do nothing and return. */  if (! svn_fs_base__dag_check_mutable(node, args->txn_id))    return SVN_NO_ERROR;  /* If a directory, do nothing and return. */  *(args->dirents) = NULL;  if (svn_fs_base__dag_node_kind(node) != svn_node_dir)    return SVN_NO_ERROR;  /* Else it's mutable.  Get its dirents. */  return svn_fs_base__dag_dir_entries(args->dirents, node,                                       trail, trail->pool);}struct remove_node_args{  const svn_fs_id_t *id;  const char *txn_id;};static svn_error_t *txn_body_remove_node(void *baton, trail_t *trail){  struct remove_node_args *args = baton;  return svn_fs_base__dag_remove_node(trail->fs, args->id, args->txn_id,                                      trail, trail->pool);}static svn_error_t *delete_txn_tree(svn_fs_t *fs,                const svn_fs_id_t *id,                const char *txn_id,                apr_pool_t *pool){  struct get_dirents_args dirent_args;  struct remove_node_args rm_args;  apr_hash_t *dirents = NULL;  apr_hash_index_t *hi;  svn_error_t *err;  /* If this sucker isn't mutable, there's nothing to do. */  if (svn_fs_base__key_compare(svn_fs_base__id_txn_id(id), txn_id) != 0)    return SVN_NO_ERROR;  /* See if the thing has dirents that need to be recursed upon.  If     you can't find the thing itself, don't sweat it.  We probably     already cleaned it up. */  dirent_args.dirents = &dirents;  dirent_args.id = id;  dirent_args.txn_id = txn_id;  err = svn_fs_base__retry_txn(fs, txn_body_get_dirents, &dirent_args, pool);  if (err && (err->apr_err == SVN_ERR_FS_ID_NOT_FOUND))    {      svn_error_clear(err);      return SVN_NO_ERROR;    }  SVN_ERR(err);  /* If there are dirents upon which to recurse ... recurse. */  if (dirents)    {      apr_pool_t *subpool = svn_pool_create(pool);      /* Loop over hash entries */      for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))        {          void *val;          svn_fs_dirent_t *dirent;          svn_pool_clear(subpool);          apr_hash_this(hi, NULL, NULL, &val);          dirent = val;          SVN_ERR(delete_txn_tree(fs, dirent->id, txn_id, subpool));        }      svn_pool_destroy(subpool);    }  /* Remove the node. */  rm_args.id = id;  rm_args.txn_id = txn_id;  return svn_fs_base__retry_txn(fs, txn_body_remove_node, &rm_args, pool);}static svn_error_t *txn_body_delete_txn(void *baton, trail_t *trail){  return svn_fs_bdb__delete_txn(trail->fs, baton, trail, trail->pool);}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;  int i;  SVN_ERR(svn_fs_base__check_fs(fs));  /* 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, 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,                                 (void *)txn_id, pool));  /* Kill the transaction's copies (which should gracefully...). */  if (txn->copies)    {      for (i = 0; i < txn->copies->nelts; i++)        {          SVN_ERR(svn_fs_base__retry_txn                  (fs, txn_body_cleanup_txn_copy,                   (void *)APR_ARRAY_IDX(txn->copies, i, const char *),                   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, (void *)txn_id,                                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_base__check_fs(txn->fs));  /* Set the transaction to "dead". */  SVN_ERR(svn_fs_base__retry_txn(txn->fs, txn_body_abort_txn, txn, 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_base__check_fs(fs));  args.names_p = &names;  args.pool = pool;  SVN_ERR(svn_fs_base__retry(fs, txn_body_list_transactions, &args, pool));  *names_p = names;  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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