You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/06/04 21:33:36 UTC
svn commit: r951539 - in /subversion/trunk/subversion: include/svn_repos.h
libsvn_repos/deprecated.c libsvn_repos/load.c
Author: hwright
Date: Fri Jun 4 19:33:35 2010
New Revision: 951539
URL: http://svn.apache.org/viewvc?rev=951539&view=rev
Log:
Rev the repos load API to take advantage of the repository notification system.
* subversion/include/svn_repos.h
(svn_node_action, svn_repos_load_uuid): Move up in the file.
(svn_repos_notify_action_t): Add several more actions.
(svn_repos_notify_t): Add several more fields needed for the load
notification.
(svn_repos_load_fs3, svn_repos_get_fs_build_parser3): New.
(svn_repos_load_fs2, svn_repos_get_fs_build_parser2): Deprecate.
* subversion/libsvn_repos/deprecated.c
(repos_notify_handler): Support the new notification actions for load
backward compat.
(svn_repos_load_fs2, svn_repos_get_fs_build_parser2): Moved here from load.c
* subversion/libsvn_repos/load.c
(parse_baton): Remove the output stream, and use the notification func and
baton.
(parse_property_block, new_revision_record, maybe_add_with_history,
new_node_record, close_node, close_revision): Emit notifications.
(svn_repos_get_fs_build_parser2, svn_repos_load_fs2): Move to deprecated.c.
(svn_repos_get_fs_build_parser3, svn_repos_load_fs3): New.
Modified:
subversion/trunk/subversion/include/svn_repos.h
subversion/trunk/subversion/libsvn_repos/deprecated.c
subversion/trunk/subversion/libsvn_repos/load.c
Modified: subversion/trunk/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=951539&r1=951538&r2=951539&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Fri Jun 4 19:33:35 2010
@@ -56,6 +56,25 @@ const svn_version_t *
svn_repos_version(void);
+/* Some useful enums. They need to be declared here for the notification
+ system to pick them up. */
+/** The different "actions" attached to nodes in the dumpfile. */
+enum svn_node_action
+{
+ svn_node_action_change,
+ svn_node_action_add,
+ svn_node_action_delete,
+ svn_node_action_replace
+};
+
+/** The different policies for processing the UUID in the dumpfile. */
+enum svn_repos_load_uuid
+{
+ svn_repos_load_uuid_default,
+ svn_repos_load_uuid_ignore,
+ svn_repos_load_uuid_force
+};
+
/** Callback type for checking authorization on paths produced by (at
* least) svn_repos_dir_delta2().
@@ -191,7 +210,25 @@ typedef enum svn_repos_notify_action_t
svn_repos_notify_pack_shard_start_revprop,
/** packing of the shard revprops has completed */
- svn_repos_notify_pack_shard_end_revprop
+ svn_repos_notify_pack_shard_end_revprop,
+
+ /** A revision has begun loading */
+ svn_repos_notify_load_txn_start,
+
+ /** A revision has finished loading */
+ svn_repos_notify_load_txn_committed,
+
+ /** A node has begun loading */
+ svn_repos_notify_load_node_start,
+
+ /** A node has finished loading */
+ svn_repos_notify_load_node_done,
+
+ /** A copied node has been encountered */
+ svn_repos_notify_load_copied_node,
+
+ /** Mergeinfo has been normalized */
+ svn_repos_notify_load_normalized_mergeinfo
} svn_repos_notify_action_t;
@@ -219,8 +256,27 @@ typedef struct svn_repos_notify_t
/** For #svn_repos_notify_warning, the warning text. */
const char *warning;
+ /** For #svn_repos_notify_pack_shard_start,
+ #svn_repos_notify_pack_shard_end,
+ #svn_repos_notify_pack_shard_start_revprop, and
+ #svn_repos_notify_pack_shard_end_revprop, the shard processed. */
apr_int64_t shard;
+ /** For #svn_repos_notify_load_commited_rev, the revision committed. */
+ svn_revnum_t new_revision;
+
+ /** For #svn_repos_notify_load_commited_rev, the source revision, if
+ different from #new_revision, otherwise #SVN_INVALID_REVNUM.
+ For #svn_repos_notify_load_txn_start, the source revision. */
+ svn_revnum_t old_revision;
+
+ /** For #svn_repos_notify_load_node_start, the action being taken on the
+ node. */
+ enum svn_node_action node_action;
+
+ /** For #svn_repos_notify_load_node_start, the path of the node. */
+ const char *path;
+
/* NOTE: Add new fields at the end to preserve binary compatibility.
Also, if you add fields here, you have to update
svn_repos_notify_create(). */
@@ -2195,23 +2251,6 @@ svn_repos_node_from_baton(void *edit_bat
#define SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_CHECKSUM \
SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_MD5
-/** The different "actions" attached to nodes in the dumpfile. */
-enum svn_node_action
-{
- svn_node_action_change,
- svn_node_action_add,
- svn_node_action_delete,
- svn_node_action_replace
-};
-
-/** The different policies for processing the UUID in the dumpfile. */
-enum svn_repos_load_uuid
-{
- svn_repos_load_uuid_default,
- svn_repos_load_uuid_ignore,
- svn_repos_load_uuid_force
-};
-
/**
* Verify the contents of the file system in @a repos.
*
@@ -2347,8 +2386,7 @@ svn_repos_dump_fs(svn_repos_t *repos,
/**
* Read and parse dumpfile-formatted @a dumpstream, reconstructing
* filesystem revisions in already-open @a repos, handling uuids in
- * accordance with @a uuid_action. If non-@c NULL, send feedback to
- * @a feedback_stream. Use @a pool for all allocation.
+ * accordance with @a uuid_action. Use @a pool for all allocation.
*
* If the dumpstream contains copy history that is unavailable in the
* repository, an error will be thrown.
@@ -2372,11 +2410,34 @@ svn_repos_dump_fs(svn_repos_t *repos,
* If @a use_post_commit_hook is set, call the repository's
* post-commit hook after committing each loaded revision.
*
+ * If non-NULL, use @a notify_func and @a notify_baton to send notification
+ * of events to the caller.
+ *
* If @a cancel_func is not @c NULL, it is called periodically with
* @a cancel_baton as argument to see if the client wishes to cancel
* the load.
*
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_repos_load_fs3(svn_repos_t *repos,
+ svn_stream_t *dumpstream,
+ enum svn_repos_load_uuid uuid_action,
+ const char *parent_dir,
+ svn_boolean_t use_pre_commit_hook,
+ svn_boolean_t use_post_commit_hook,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_repos_load_fs3(), but with @a feedback_stream in place of
+ * the #svn_repos_notify_func_t and baton.
+ *
* @since New in 1.2.
+ * @deprecated Provided for backward compatibility with the 1.6 API.
*/
svn_error_t *
svn_repos_load_fs2(svn_repos_t *repos,
@@ -2554,8 +2615,27 @@ svn_repos_parse_dumpstream2(svn_stream_t
* Print all parsing feedback to @a outstream (if non-@c NULL).
*
*
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **parser,
+ void **parse_baton,
+ svn_repos_t *repos,
+ svn_boolean_t use_history,
+ enum svn_repos_load_uuid uuid_action,
+ const char *parent_dir,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_repos_get_fs_build_parser3(), but with @a outstream in place
+ * if a #svn_repos_notify_func_t and baton.
+ *
* @since New in 1.1.
+ * @deprecated Provided for backward compatibility with the 1.6 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **parser,
void **parse_baton,
@@ -2566,7 +2646,6 @@ svn_repos_get_fs_build_parser2(const svn
const char *parent_dir,
apr_pool_t *pool);
-
/**
* A vtable that is driven by svn_repos_parse_dumpstream().
* Similar to #svn_repos_parse_fns2_t except that it lacks
Modified: subversion/trunk/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/deprecated.c?rev=951539&r1=951538&r2=951539&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_repos/deprecated.c Fri Jun 4 19:33:35 2010
@@ -470,16 +470,14 @@ repos_notify_handler(void *baton,
apr_pool_t *scratch_pool)
{
svn_stream_t *feedback_stream = baton;
+ apr_size_t len;
switch (notify->action)
{
case svn_repos_notify_warning:
- {
- apr_size_t len = strlen(notify->warning);
- svn_error_clear(svn_stream_write(feedback_stream, notify->warning,
- &len));
- return;
- }
+ len = strlen(notify->warning);
+ svn_error_clear(svn_stream_write(feedback_stream, notify->warning, &len));
+ return;
case svn_repos_notify_dump_rev_end:
svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
@@ -493,6 +491,78 @@ repos_notify_handler(void *baton,
notify->revision));
return;
+ case svn_repos_notify_load_txn_committed:
+ if (notify->old_revision == SVN_INVALID_REVNUM)
+ {
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("\n------- Committed revision %ld >>>\n\n"),
+ notify->new_revision));
+ }
+ else
+ {
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("\n------- Committed new rev %ld"
+ " (loaded from original rev %ld"
+ ") >>>\n\n"), notify->new_revision,
+ notify->old_revision));
+ }
+ return;
+
+ case svn_repos_notify_load_node_start:
+ {
+ switch (notify->node_action)
+ {
+ case svn_node_action_change:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * editing path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_delete:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * deleting path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_add:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * adding path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_replace:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * replacing path : %s ..."),
+ notify->path));
+ break;
+
+ }
+ }
+ return;
+
+ case svn_repos_notify_load_node_done:
+ len = 7;
+ svn_error_clear(svn_stream_write(feedback_stream, _(" done.\n"), &len));
+ return;
+
+ case svn_repos_notify_load_copied_node:
+ len = 9;
+ svn_error_clear(svn_stream_write(feedback_stream, "COPIED...", &len));
+ return;
+
+ case svn_repos_notify_load_txn_start:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("<<< Started new transaction, based on "
+ "original revision %ld\n"),
+ notify->old_revision));
+ return;
+
+ case svn_repos_notify_load_normalized_mergeinfo:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" removing '\\r' from %s ..."),
+ SVN_PROP_MERGEINFO));
+ return;
+
default:
return;
}
@@ -548,6 +618,26 @@ svn_repos_verify_fs(svn_repos_t *repos,
}
/*** From load.c ***/
+
+svn_error_t *
+svn_repos_load_fs2(svn_repos_t *repos,
+ svn_stream_t *dumpstream,
+ svn_stream_t *feedback_stream,
+ enum svn_repos_load_uuid uuid_action,
+ const char *parent_dir,
+ svn_boolean_t use_pre_commit_hook,
+ svn_boolean_t use_post_commit_hook,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ return svn_repos_load_fs3(repos, dumpstream, uuid_action, parent_dir,
+ use_pre_commit_hook, use_post_commit_hook,
+ feedback_stream ? repos_notify_handler : NULL,
+ feedback_stream, cancel_func, cancel_baton, pool);
+}
+
+
static svn_repos_parser_fns_t *
fns_from_fns2(const svn_repos_parse_fns2_t *fns2,
apr_pool_t *pool)
@@ -566,6 +656,7 @@ fns_from_fns2(const svn_repos_parse_fns2
fns->close_revision = fns2->close_revision;
return fns;
}
+
static svn_repos_parse_fns2_t *
fns2_from_fns(const svn_repos_parser_fns_t *fns,
apr_pool_t *pool)
@@ -617,6 +708,22 @@ svn_repos_load_fs(svn_repos_t *repos,
}
svn_error_t *
+svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **parser,
+ void **parse_baton,
+ svn_repos_t *repos,
+ svn_boolean_t use_history,
+ enum svn_repos_load_uuid uuid_action,
+ svn_stream_t *outstream,
+ const char *parent_dir,
+ apr_pool_t *pool)
+{
+ return svn_repos_get_fs_build_parser3(parser, parse_baton, repos, use_history,
+ uuid_action, parent_dir,
+ outstream ? repos_notify_handler : NULL,
+ outstream, pool);
+}
+
+svn_error_t *
svn_repos_get_fs_build_parser(const svn_repos_parser_fns_t **parser_callbacks,
void **parse_baton,
svn_repos_t *repos,
Modified: subversion/trunk/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/load.c?rev=951539&r1=951538&r2=951539&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/load.c (original)
+++ subversion/trunk/subversion/libsvn_repos/load.c Fri Jun 4 19:33:35 2010
@@ -51,9 +51,10 @@ struct parse_baton
svn_boolean_t use_history;
svn_boolean_t use_pre_commit_hook;
svn_boolean_t use_post_commit_hook;
- svn_stream_t *outstream;
enum svn_repos_load_uuid uuid_action;
const char *parent_dir;
+ svn_repos_notify_func_t notify_func;
+ void *notify_baton;
apr_pool_t *pool;
/* A hash mapping copy-from revisions and mergeinfo range revisions
@@ -465,12 +466,14 @@ parse_property_block(svn_stream_t *strea
propstring.data = prop_eol_normalized;
propstring.len = strlen(prop_eol_normalized);
- if (pb->outstream)
- SVN_ERR(svn_stream_printf(
- pb->outstream,
- proppool,
- _(" removing '\\r' from %s ..."),
- SVN_PROP_MERGEINFO));
+ if (pb->notify_func)
+ {
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_normalized_mergeinfo,
+ proppool);
+
+ pb->notify_func(pb->notify_baton, notify, proppool);
+ }
}
SVN_ERR(parse_fns->set_node_property(record_baton,
@@ -1050,9 +1053,14 @@ new_revision_record(void **revision_bato
SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
SVN_ERR(svn_fs_txn_root(&(rb->txn_root), rb->txn, pool));
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _("<<< Started new transaction, based on "
- "original revision %ld\n"), rb->rev));
+ if (pb->notify_func)
+ {
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_txn_start, rb->pool);
+
+ notify->old_revision = rb->rev;
+ pb->notify_func(pb->notify_baton, notify, rb->pool);
+ }
}
/* If we're parsing revision 0, only the revision are (possibly)
@@ -1073,7 +1081,6 @@ maybe_add_with_history(struct node_baton
apr_pool_t *pool)
{
struct parse_baton *pb = rb->pb;
- apr_size_t len;
if ((nb->copyfrom_path == NULL) || (! pb->use_history))
{
@@ -1125,8 +1132,12 @@ maybe_add_with_history(struct node_baton
SVN_ERR(svn_fs_copy(copy_root, nb->copyfrom_path,
rb->txn_root, nb->path, pool));
- len = 9;
- SVN_ERR(svn_stream_write(pb->outstream, "COPIED...", &len));
+ if (pb->notify_func)
+ {
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_copied_node, rb->pool);
+ pb->notify_func(pb->notify_baton, notify, rb->pool);
+ }
}
return SVN_NO_ERROR;
@@ -1171,47 +1182,40 @@ new_node_record(void **node_baton,
nb = make_node_baton(headers, rb, pool);
+ /* Make sure we have an action we recognize. */
+ if (nb->action < svn_node_action_change
+ || nb->action > svn_node_action_replace)
+ return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
+ _("Unrecognized node-action on node '%s'"),
+ nb->path);
+
+ if (pb->notify_func)
+ {
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_node_start, rb->pool);
+
+ notify->node_action = nb->action;
+ notify->path = nb->path;
+ pb->notify_func(pb->notify_baton, notify, rb->pool);
+ }
+
switch (nb->action)
{
case svn_node_action_change:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * editing path : %s ..."),
- nb->path));
- break;
- }
+ break;
+
case svn_node_action_delete:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * deleting path : %s ..."),
- nb->path));
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
- break;
- }
+ SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
+ break;
+
case svn_node_action_add:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * adding path : %s ..."),
- nb->path));
-
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
- }
+ SVN_ERR(maybe_add_with_history(nb, rb, pool));
+ break;
+
case svn_node_action_replace:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * replacing path : %s ..."),
- nb->path));
-
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
-
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
- }
- default:
- return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
- _("Unrecognized node-action on node '%s'"),
- nb->path);
+ SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
+ SVN_ERR(maybe_add_with_history(nb, rb, pool));
+ break;
}
*node_baton = nb;
@@ -1364,9 +1368,16 @@ close_node(void *baton)
struct node_baton *nb = baton;
struct revision_baton *rb = nb->rb;
struct parse_baton *pb = rb->pb;
- apr_size_t len = 7;
- return svn_stream_write(pb->outstream, _(" done.\n"), &len);
+ if (pb->notify_func)
+ {
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_node_done, rb->pool);
+
+ pb->notify_func(pb->notify_baton, notify, rb->pool);
+ }
+
+ return SVN_NO_ERROR;
}
@@ -1467,19 +1478,19 @@ close_revision(void *baton)
SVN_PROP_REVISION_DATE, rb->datestamp,
rb->pool));
- if (*new_rev == rb->rev)
+ if (pb->notify_func)
{
- return svn_stream_printf(pb->outstream, rb->pool,
- _("\n------- Committed revision %ld"
- " >>>\n\n"), *new_rev);
- }
- else
- {
- return svn_stream_printf(pb->outstream, rb->pool,
- _("\n------- Committed new rev %ld"
- " (loaded from original rev %ld"
- ") >>>\n\n"), *new_rev, rb->rev);
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_load_txn_committed, rb->pool);
+
+ notify->new_revision = *new_rev;
+ notify->old_revision = ((*new_rev == rb->rev)
+ ? SVN_INVALID_REVNUM
+ : rb->rev);
+ pb->notify_func(pb->notify_baton, notify, rb->pool);
}
+
+ return SVN_NO_ERROR;
}
@@ -1489,13 +1500,14 @@ close_revision(void *baton)
svn_error_t *
-svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
void **parse_baton,
svn_repos_t *repos,
svn_boolean_t use_history,
enum svn_repos_load_uuid uuid_action,
- svn_stream_t *outstream,
const char *parent_dir,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
apr_pool_t *pool)
{
svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
@@ -1516,7 +1528,8 @@ svn_repos_get_fs_build_parser2(const svn
pb->repos = repos;
pb->fs = svn_repos_fs(repos);
pb->use_history = use_history;
- pb->outstream = outstream ? outstream : svn_stream_empty(pool);
+ pb->notify_func = notify_func;
+ pb->notify_baton = notify_baton;
pb->uuid_action = uuid_action;
pb->parent_dir = parent_dir;
pb->pool = pool;
@@ -1531,13 +1544,14 @@ svn_repos_get_fs_build_parser2(const svn
svn_error_t *
-svn_repos_load_fs2(svn_repos_t *repos,
+svn_repos_load_fs3(svn_repos_t *repos,
svn_stream_t *dumpstream,
- svn_stream_t *feedback_stream,
enum svn_repos_load_uuid uuid_action,
const char *parent_dir,
svn_boolean_t use_pre_commit_hook,
svn_boolean_t use_post_commit_hook,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
@@ -1548,12 +1562,13 @@ svn_repos_load_fs2(svn_repos_t *repos,
/* This is really simple. */
- SVN_ERR(svn_repos_get_fs_build_parser2(&parser, &parse_baton,
+ SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
repos,
TRUE, /* look for copyfrom revs */
uuid_action,
- feedback_stream,
parent_dir,
+ notify_func,
+ notify_baton,
pool));
/* Heh. We know this is a parse_baton. This file made it. So