subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject svn commit: r1347790 - in /subversion/trunk/subversion/libsvn_ra_serf: commit.c merge.c ra_serf.h
Date Thu, 07 Jun 2012 20:55:09 GMT
Author: gstein
Date: Thu Jun  7 20:55:09 2012
New Revision: 1347790

URL: http://svn.apache.org/viewvc?rev=1347790&view=rev
Log:
Convert the MERGE request code (ie. the final step in a commit) over
to the new XML processing code.

The old code would capture all properties in the merge response, but
then only examine a few. We now capture just the properties we need,
and ignore the rest.

* subversion/libsvn_ra_serf/ra_serf.h:
  (svn_ra_serf__xml_closed_t): update docstring
  (svn_ra_serf__xml_transition_t): clarify docstring for COLLECT_CDATA
  (svn_ra_serf__merge_context_t): removed typedef.
  (svn_ra_serf__merge_get_done_ptr,
      svn_ra_serf__merge_get_commit_info,
      svn_ra_serf__merge_get_status): removed. no longer needed.
  (svn_ra_serf__merge_create_req): renamed to ...
  (svn_ra_serf__run_merge): ... this. rather than returning an opaque
    context, we return the final commit info and the response code.
    switched to dual-pool semantics.

* subversion/libsvn_ra_serf/merge.c:
  (NONE, NAME, IGNORE_PROP_NAME, NEED_PROP_NAME): removed unused states
  (BASELINE, COLLECTION, CHECKED_IN, VERSION_NAME, POST_COMMIT_ERR):
    new parse states
  (resource_type_e): removed. unused.
  (merge_info_t): removed. unused.
  (svn_ra_serf__merge_context_t): typedef moved here. DONE member
    removed, in favor of the handler's DONE flag.
  (merge_ttable): now compiled. adjusted many flags and introduced new
    states for the properties that we capture.
  (merge_closed): new function to handle the processing
  (push_state, start_merge, end_merge, cdata_merge): removed from
    compilation, but left in file to keep the "diff" reasonable. will
    be removed in a future commit.
  (svn_ra_serf__merge_create_req): renamed to ...
  (svn_ra_serf__run_merge): ... this. adjusted params to return the
    necessary info. switched to dual-pool. switch over to the new xml
    processing. actually run the request here.
  (svn_ra_serf__merge_get_done_ptr,
      svn_ra_serf__merge_get_commit_info,
      svn_ra_serf__merge_get_status): removed. no longer needed.

* subversion/libsvn_ra_serf/commit.c:
  (close_edit): switch call to run_merge() and then deal with the
    results, rather than a bunch of dumb opaque type handling. narrow
    the scope of the HANDLER localvar.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/commit.c
    subversion/trunk/subversion/libsvn_ra_serf/merge.c
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h

Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=1347790&r1=1347789&r2=1347790&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Thu Jun  7 20:55:09 2012
@@ -2135,40 +2135,37 @@ close_edit(void *edit_baton,
            apr_pool_t *pool)
 {
   commit_context_t *ctx = edit_baton;
-  svn_ra_serf__merge_context_t *merge_ctx;
-  svn_ra_serf__handler_t *handler;
-  svn_boolean_t *merge_done;
   const char *merge_target =
     ctx->activity_url ? ctx->activity_url : ctx->txn_url;
+  const svn_commit_info_t *commit_info;
+  int response_code;
 
   /* MERGE our activity */
-  SVN_ERR(svn_ra_serf__merge_create_req(&merge_ctx, ctx->session,
-                                        ctx->session->conns[0],
-                                        merge_target,
-                                        ctx->lock_tokens,
-                                        ctx->keep_locks,
-                                        pool));
-
-  merge_done = svn_ra_serf__merge_get_done_ptr(merge_ctx);
+  SVN_ERR(svn_ra_serf__run_merge(&commit_info, &response_code,
+                                 ctx->session,
+                                 ctx->session->conns[0],
+                                 merge_target,
+                                 ctx->lock_tokens,
+                                 ctx->keep_locks,
+                                 pool, pool));
 
-  SVN_ERR(svn_ra_serf__context_run_wait(merge_done, ctx->session, pool));
-
-  if (svn_ra_serf__merge_get_status(merge_ctx) != 200)
+  if (response_code != 200)
     {
       return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                _("MERGE request failed: returned %d "
                                  "(during commit)"),
-                               svn_ra_serf__merge_get_status(merge_ctx));
+                               response_code);
     }
 
   /* Inform the WC that we did a commit.  */
   if (ctx->callback)
-    SVN_ERR(ctx->callback(svn_ra_serf__merge_get_commit_info(merge_ctx),
-                          ctx->callback_baton, pool));
+    SVN_ERR(ctx->callback(commit_info, ctx->callback_baton, pool));
 
   /* If we're using activities, DELETE our completed activity.  */
   if (ctx->activity_url)
     {
+      svn_ra_serf__handler_t *handler;
+
       handler = apr_pcalloc(pool, sizeof(*handler));
       handler->handler_pool = pool;
       handler->method = "DELETE";

Modified: subversion/trunk/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/merge.c?rev=1347790&r1=1347789&r2=1347790&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/merge.c Thu Jun  7 20:55:09 2012
@@ -48,7 +48,6 @@
  */
 typedef enum merge_state_e {
   INITIAL = 0,
-  NONE = 0,
   MERGE_RESPONSE,
   UPDATED_SET,
   RESPONSE,
@@ -56,38 +55,21 @@ typedef enum merge_state_e {
   PROPSTAT,
   PROP,
   RESOURCE_TYPE,
-  AUTHOR,
-  NAME,
-  DATE,
-  SKIP_HREF,
-  IGNORE_PROP_NAME = SKIP_HREF, /* ### leave old name for now  */
-  NEED_PROP_NAME,
-  PROP_VAL
-} merge_state_e;
-
-typedef enum resource_type_e {
-  UNSET,
   BASELINE,
   COLLECTION,
-  CHECKED_IN
-} resource_type_e;
-
-typedef struct merge_info_t {
-  /* Temporary allocations here please */
-  apr_pool_t *pool;
-
-  resource_type_e type;
-
-  apr_hash_t *props;
+  SKIP_HREF,
+  CHECKED_IN,
+  VERSION_NAME,
+  DATE,
+  AUTHOR,
+  POST_COMMIT_ERR,
 
-  const char *prop_ns;
-  const char *prop_name;
-  svn_stringbuf_t *prop_value;
+  PROP_VAL
+} merge_state_e;
 
-} merge_info_t;
 
 /* Structure associated with a MERGE request. */
-struct svn_ra_serf__merge_context_t
+typedef struct svn_ra_serf__merge_context_t
 {
   apr_pool_t *pool;
 
@@ -100,67 +82,190 @@ struct svn_ra_serf__merge_context_t
   const char *merge_resource_url; /* URL of resource to be merged. */
   const char *merge_url; /* URL at which the MERGE request is aimed. */
 
-  svn_boolean_t done;
-
   svn_commit_info_t *commit_info;
-};
 
-#if 0
-/* ### can't do this yet because we don't have wildcard transitions, which
-   ### is needed to capture a property name.  */
+} svn_ra_serf__merge_context_t;
+
 
 #define D_ "DAV:"
 #define S_ SVN_XML_NAMESPACE
 static const svn_ra_serf__xml_transition_t merge_ttable[] = {
-  { INITIAL, S_, "merge-response", MERGE_RESPONSE,
+  { INITIAL, D_, "merge-response", MERGE_RESPONSE,
     FALSE, { NULL }, FALSE },
 
-  { MERGE_RESPONSE, S_, "updated-set", UPDATED_SET,
+  { MERGE_RESPONSE, D_, "updated-set", UPDATED_SET,
     FALSE, { NULL }, FALSE },
 
   { UPDATED_SET, D_, "response", RESPONSE,
-    FALSE, { NULL }, FALSE },
+    FALSE, { NULL }, TRUE },
 
   { RESPONSE, D_, "href", HREF,
-    FALSE, { NULL }, FALSE },
+    TRUE, { NULL }, TRUE },
 
   { RESPONSE, D_, "propstat", PROPSTAT,
     FALSE, { NULL }, FALSE },
 
-  { PROPSTAT, D_, "prop", PROP,
-    FALSE, { NULL }, FALSE },
-
 #if 0
   /* Not needed.  */
   { PROPSTAT, D_, "status", STATUS,
     FALSE, { NULL }, FALSE },
 #endif
 
+  { PROPSTAT, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE },
+
   { PROP, D_, "resourcetype", RESOURCE_TYPE,
     FALSE, { NULL }, FALSE },
 
   { RESOURCE_TYPE, D_, "baseline", BASELINE,
-    FALSE, { NULL }, FALSE },
+    FALSE, { NULL }, TRUE },
 
   { RESOURCE_TYPE, D_, "collection", COLLECTION,
-    FALSE, { NULL }, FALSE },
+    FALSE, { NULL }, TRUE },
 
   { PROP, D_, "checked-in", SKIP_HREF,
     FALSE, { NULL }, FALSE },
 
-  { PROP, "*", "*", PROP_VAL,
-    FALSE, { NULL }, FALSE },
+  { SKIP_HREF, D_, "href", CHECKED_IN,
+    TRUE, { NULL }, TRUE },
 
-  { SKIP_HREF, D_, "href", PROP_VAL,
-    FALSE, { NULL }, FALSE },
+  { PROP, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, D_, SVN_DAV__CREATIONDATE, DATE,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, D_, "creator-displayname", AUTHOR,
+    TRUE, { NULL }, TRUE },
+
+  { PROP, S_, "post-commit-err", POST_COMMIT_ERR,
+    TRUE, { NULL }, TRUE },
 
   { 0 }
 };
 
-#endif
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
+static svn_error_t *
+merge_closed(svn_ra_serf__xml_estate_t *xes,
+             void *baton,
+             int leaving_state,
+             const svn_string_t *cdata,
+             apr_hash_t *attrs,
+             apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__merge_context_t *merge_ctx = baton;
+
+  if (leaving_state == RESPONSE)
+    {
+      const char *rtype;
+
+      rtype = apr_hash_get(attrs, "resourcetype", APR_HASH_KEY_STRING);
+
+      /* rtype can only be "baseline" or "collection" (or NULL). We can
+         keep this check simple.  */
+      if (rtype && *rtype == 'b')
+        {
+          const char *rev_str;
+
+          rev_str = apr_hash_get(attrs, "revision", APR_HASH_KEY_STRING);
+          if (rev_str)
+            merge_ctx->commit_info->revision = SVN_STR_TO_REV(rev_str);
+          else
+            merge_ctx->commit_info->revision = SVN_INVALID_REVNUM;
+
+          merge_ctx->commit_info->date =
+              apr_pstrdup(merge_ctx->pool,
+                          apr_hash_get(attrs, "date", APR_HASH_KEY_STRING));
+
+          merge_ctx->commit_info->author =
+              apr_pstrdup(merge_ctx->pool,
+                          apr_hash_get(attrs, "author", APR_HASH_KEY_STRING));
+
+          merge_ctx->commit_info->post_commit_err =
+             apr_pstrdup(merge_ctx->pool,
+                         apr_hash_get(attrs,
+                                      "post-commit-err", APR_HASH_KEY_STRING));
+        }
+      else
+        {
+          const char *href;
+
+          href = svn_urlpath__skip_ancestor(
+                   merge_ctx->merge_url,
+                   apr_hash_get(attrs, "href", APR_HASH_KEY_STRING));
+
+          if (href == NULL)
+            return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                     _("A MERGE response for '%s' is not "
+                                       "a child of the destination ('%s')"),
+                                     href, merge_ctx->merge_url);
+
+          /* We now need to dive all the way into the WC to update the
+             base VCC url.  */
+          if (!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(merge_ctx->session)
+              && merge_ctx->session->wc_callbacks->push_wc_prop)
+            {
+              const char *checked_in;
+              svn_string_t checked_in_str;
+
+              checked_in = apr_hash_get(attrs,
+                                        "checked-in", APR_HASH_KEY_STRING);
+              checked_in_str.data = checked_in;
+              checked_in_str.len = strlen(checked_in);
+
+              SVN_ERR(merge_ctx->session->wc_callbacks->push_wc_prop(
+                        merge_ctx->session->wc_callback_baton,
+                        href,
+                        SVN_RA_SERF__WC_CHECKED_IN_URL,
+                        &checked_in_str,
+                        scratch_pool));
+            }
+        }
+    }
+  else if (leaving_state == BASELINE)
+    {
+      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "baseline");
+    }
+  else if (leaving_state == COLLECTION)
+    {
+      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "collection");
+    }
+  else
+    {
+      const char *name;
+      const char *value = cdata->data;
+
+      if (leaving_state == HREF)
+        {
+          name = "href";
+          value = svn_urlpath__canonicalize(value, scratch_pool);
+        }
+      else if (leaving_state == CHECKED_IN)
+        {
+          name = "checked-in";
+          value = svn_urlpath__canonicalize(value, scratch_pool);
+        }
+      else if (leaving_state == VERSION_NAME)
+        name = "revision";
+      else if (leaving_state == DATE)
+        name = "date";
+      else if (leaving_state == AUTHOR)
+        name = "author";
+      else if (leaving_state == POST_COMMIT_ERR)
+        name = "post-commit-err";
+      else
+        SVN_ERR_MALFUNCTION();
+
+      svn_ra_serf__xml_note(xes, RESPONSE, name, value);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+#if 0
 
-
 static merge_info_t *
 push_state(svn_ra_serf__xml_parser_t *parser,
            svn_ra_serf__merge_context_t *ctx,
@@ -451,6 +556,9 @@ cdata_merge(svn_ra_serf__xml_parser_t *p
   return SVN_NO_ERROR;
 }
 
+#endif /* 0 */
+
+
 static svn_error_t *
 setup_merge_headers(serf_bucket_t *headers,
                     void *baton,
@@ -563,21 +671,23 @@ create_merge_body(serf_bucket_t **bkt,
 
 
 svn_error_t *
-svn_ra_serf__merge_create_req(svn_ra_serf__merge_context_t **ret_ctx,
-                              svn_ra_serf__session_t *session,
-                              svn_ra_serf__connection_t *conn,
-                              const char *merge_resource_url,
-                              apr_hash_t *lock_tokens,
-                              svn_boolean_t keep_locks,
-                              apr_pool_t *pool)
+svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
+                       int *response_code,
+                       svn_ra_serf__session_t *session,
+                       svn_ra_serf__connection_t *conn,
+                       const char *merge_resource_url,
+                       apr_hash_t *lock_tokens,
+                       svn_boolean_t keep_locks,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   svn_ra_serf__merge_context_t *merge_ctx;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
 
-  merge_ctx = apr_pcalloc(pool, sizeof(*merge_ctx));
+  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));
 
-  merge_ctx->pool = pool;
+  merge_ctx->pool = result_pool;
   merge_ctx->session = session;
 
   merge_ctx->merge_resource_url = merge_resource_url;
@@ -585,13 +695,16 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   merge_ctx->lock_tokens = lock_tokens;
   merge_ctx->keep_locks = keep_locks;
 
-  merge_ctx->commit_info = svn_create_commit_info(pool);
+  merge_ctx->commit_info = svn_create_commit_info(result_pool);
 
   merge_ctx->merge_url = session->session_url.path;
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
+                                           NULL, merge_closed, NULL,
+                                           merge_ctx,
+                                           scratch_pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
 
-  handler->handler_pool = pool;
   handler->method = "MERGE";
   handler->path = merge_ctx->merge_url;
   handler->body_delegate = create_merge_body;
@@ -599,44 +712,15 @@ svn_ra_serf__merge_create_req(svn_ra_ser
   handler->conn = conn;
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = merge_ctx;
-  parser_ctx->start = start_merge;
-  parser_ctx->end = end_merge;
-  parser_ctx->cdata = cdata_merge;
-  parser_ctx->done = &merge_ctx->done;
-
   handler->header_delegate = setup_merge_headers;
   handler->header_delegate_baton = merge_ctx;
 
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
   merge_ctx->handler = handler;
 
-  svn_ra_serf__request_create(handler);
+  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
-  *ret_ctx = merge_ctx;
+  *commit_info = merge_ctx->commit_info;
+  *response_code = handler->sline.code;
 
   return SVN_NO_ERROR;
 }
-
-svn_boolean_t*
-svn_ra_serf__merge_get_done_ptr(svn_ra_serf__merge_context_t *ctx)
-{
-  return &ctx->done;
-}
-
-svn_commit_info_t*
-svn_ra_serf__merge_get_commit_info(svn_ra_serf__merge_context_t *ctx)
-{
-  return ctx->commit_info;
-}
-
-int
-svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx)
-{
-  return ctx->handler->sline.code;
-}

Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1347790&r1=1347789&r2=1347790&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Thu Jun  7 20:55:09 2012
@@ -642,8 +642,11 @@ typedef svn_error_t *
    non-NULL and contain the collected cdata.
 
    If attribute collection was enabled for this state, then ATTRS will
-   contain the attributes collected for this element only. Use
-   svn_ra_serf__xml_gather_since() to gather up data from outer states.
+   contain the attributes collected for this element only, along with
+   any values stored via svn_ra_serf__xml_note().
+
+   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
+
    ATTRS is char* -> char*.
 
    Temporary allocations may be made in SCRATCH_POOL.  */
@@ -687,7 +690,8 @@ typedef struct svn_ra_serf__xml_transiti
   /* Moving to this state  */
   int to_state;
 
-  /* Should the cdata of NAME be collected?  */
+  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
+     be TRUE in order to capture this cdata.  */
   svn_boolean_t collect_cdata;
 
   /* Which attributes of NAME should be collected? Terminate with NULL.
@@ -1240,17 +1244,6 @@ svn_ra_serf__get_resource_type(svn_kind_
 
 /** MERGE-related functions **/
 
-typedef struct svn_ra_serf__merge_context_t svn_ra_serf__merge_context_t;
-
-svn_boolean_t*
-svn_ra_serf__merge_get_done_ptr(svn_ra_serf__merge_context_t *ctx);
-
-svn_commit_info_t*
-svn_ra_serf__merge_get_commit_info(svn_ra_serf__merge_context_t *ctx);
-
-int
-svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx);
-
 void
 svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
                                    const char *parent,
@@ -1264,13 +1257,16 @@ svn_ra_serf__merge_lock_token_list(apr_h
    client.  If KEEP_LOCKS is set, instruct the server to not release
    locks set on the paths included in this commit.  */
 svn_error_t *
-svn_ra_serf__merge_create_req(svn_ra_serf__merge_context_t **merge_ctx,
-                              svn_ra_serf__session_t *session,
-                              svn_ra_serf__connection_t *conn,
-                              const char *merge_resource_url,
-                              apr_hash_t *lock_tokens,
-                              svn_boolean_t keep_locks,
-                              apr_pool_t *pool);
+svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
+                       int *response_code,
+                       svn_ra_serf__session_t *session,
+                       svn_ra_serf__connection_t *conn,
+                       const char *merge_resource_url,
+                       apr_hash_t *lock_tokens,
+                       svn_boolean_t keep_locks,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
+
 
 /** OPTIONS-related functions **/
 



Mime
View raw message