Author: danielsh
Date: Fri Jul 30 10:05:25 2010
New Revision: 980717

URL: http://svn.apache.org/viewvc?rev=980717&view=rev
Log:
On the 'atomic-revprop' branch:

Implement the API over ra_svn.

* subversion/libsvn_ra_svn/protocol
  (atomic-revprops):  New capability.
  (change-rev-prop2):  New verb.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_change_rev_prop):  Implement the OLD_VALUE_P != NULL case.
  (ra_svn_has_capability):  Support SVN_RA_CAPABILITY_ATOMIC_REVPROPS.

* subversion/include/svn_ra_svn.h
  (SVN_RA_SVN_CAP_ATOMIC_REVPROPS):  New ra_svn capability.

* subversion/svnserve/serve.c
  (do_change_rev_prop):  Gutted from change_rev_prop().
  (change_rev_prop2):  New, handles 'change-rev-prop2' verb.
  (change_rev_prop):  Move some code to do_change_rev_prop(), and call it.
  (main_commands):  Add 'change-rev-prop2'.
  (serve):  Advertise SVN_RA_SVN_CAP_ATOMIC_REVPROPS.

Modified:
    subversion/branches/atomic-revprop/subversion/include/svn_ra_svn.h
    subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/client.c
    subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/protocol
    subversion/branches/atomic-revprop/subversion/svnserve/serve.c

Modified: subversion/branches/atomic-revprop/subversion/include/svn_ra_svn.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/include/svn_ra_svn.h?rev=980717&r1=980716&r2=980717&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/include/svn_ra_svn.h 
(original)
+++ subversion/branches/atomic-revprop/subversion/include/svn_ra_svn.h Fri Jul 
30 10:05:25 2010
@@ -60,6 +60,8 @@ extern "C" {
 #define SVN_RA_SVN_CAP_LOG_REVPROPS "log-revprops"
 /* maps to SVN_RA_CAPABILITY_PARTIAL_REPLAY */
 #define SVN_RA_SVN_CAP_PARTIAL_REPLAY "partial-replay"
+/* maps to SVN_RA_CAPABILITY_ATOMIC_REVPROPS */
+#define SVN_RA_SVN_CAP_ATOMIC_REVPROPS "atomic-revprops"
 
 /** ra_svn passes @c svn_dirent_t fields over the wire as a list of
  * words, these are the values used to represent each field.

Modified: subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/client.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/client.c?rev=980717&r1=980716&r2=980717&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/client.c 
(original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/client.c Fri 
Jul 30 10:05:25 2010
@@ -622,6 +622,7 @@ static svn_error_t *open_session(svn_ra_
   /* In protocol version 2, we send back our protocol version, our
    * capability list, and the URL, and subsequently there is an auth
    * request. */
+  /* Client-side capabilities list: */
   SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "n(wwwwww)cc(?c)",
                                  (apr_uint64_t) 2,
                                  SVN_RA_SVN_CAP_EDIT_PIPELINE,
@@ -807,6 +808,12 @@ static svn_error_t *ra_svn_get_dated_rev
   return SVN_NO_ERROR;
 }
 
+/* Forward declaration. */
+static svn_error_t *ra_svn_has_capability(svn_ra_session_t *session,
+                                          svn_boolean_t *has,
+                                          const char *capability,
+                                          apr_pool_t *pool);
+
 static svn_error_t *ra_svn_change_rev_prop(svn_ra_session_t *session, 
svn_revnum_t rev,
                                            const char *name,
                                            const svn_string_t *const 
*old_value_p,
@@ -815,12 +822,35 @@ static svn_error_t *ra_svn_change_rev_pr
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
+  svn_boolean_t dont_care;
+  const svn_string_t *old_value;
+  svn_boolean_t has_atomic_revprops;
+
+  SVN_ERR(ra_svn_has_capability(session, &has_atomic_revprops,
+                                SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
+                                pool));
 
   if (old_value_p)
-    SVN__NOT_IMPLEMENTED();
+    {
+      /* How did you get past the same check in svn_ra_change_rev_prop2()? */
+      SVN_ERR_ASSERT(has_atomic_revprops);
+
+      dont_care = FALSE;
+      old_value = *old_value_p;
+    }
+  else
+    {
+      dont_care = TRUE;
+      old_value = NULL;
+    }
+
+  if (has_atomic_revprops)
+    SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "change-rev-prop2", "rc(?s)(b?s)",
+                                 rev, name, value, dont_care, old_value));
+  else
+    SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "change-rev-prop", "rc?s",
+                                 rev, name, value));
 
-  SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "change-rev-prop", "rc?s",
-                               rev, name, value));
   SVN_ERR(handle_auth_request(sess_baton, pool));
   SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, ""));
   return SVN_NO_ERROR;
@@ -2418,6 +2448,9 @@ static svn_error_t *ra_svn_has_capabilit
   else if (strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0)
     *has = svn_ra_svn_has_capability(sess->conn,
                                      SVN_RA_SVN_CAP_COMMIT_REVPROPS);
+  else if (strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0)
+    *has = svn_ra_svn_has_capability(sess->conn,
+                                     SVN_RA_SVN_CAP_ATOMIC_REVPROPS);
   else  /* Don't know any other capabilities, so error. */
     {
       return svn_error_createf

Modified: subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/protocol
URL: 
http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/protocol?rev=980717&r1=980716&r2=980717&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/protocol 
(original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_ra_svn/protocol Fri 
Jul 30 10:05:25 2010
@@ -199,6 +199,9 @@ capability and C indicates a client capa
 [S]  depth             If the server presents this capability, it understands
                        requested operational depth (see section 3.1.1) and
                        per-path ambient depth (see section 3.1.3).
+[S]  atomic-revprops   If the server presents support this capability, it
+                       supports the change-rev-prop2 command.
+                       See section 3.1.1.
 
 3. Commands
 -----------
@@ -261,6 +264,16 @@ second place for auth-request point as n
      changed to be optional without creating an optional tuple for
      that one parameter as we normally do.)
 
+  change-rev-prop2
+    params:   ( rev:number name:string [ value:string ]
+                ( dont-care:bool ? previous-value:string ) )
+    response: ( )
+    If value is not specified, the rev-prop is removed.  If dont-care is false,
+    then the rev-prop is changed only if it is currently set as previous-value
+    indicates.  (If dont-care is false and previous-value is unspecified, then
+    the revision property must be previously unset.)  If dont-care is true,
+    then previous-value must not be specified.
+
   rev-proplist
     params:   ( rev:number )
     response: ( props:proplist )

Modified: subversion/branches/atomic-revprop/subversion/svnserve/serve.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnserve/serve.c?rev=980717&r1=980716&r2=980717&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnserve/serve.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnserve/serve.c Fri Jul 30 
10:05:25 2010
@@ -994,6 +994,65 @@ static svn_error_t *get_dated_rev(svn_ra
   return SVN_NO_ERROR;
 }
 
+/* Common logic for change_rev_prop() and change_rev_prop2(). */
+static svn_error_t *do_change_rev_prop(svn_ra_svn_conn_t *conn,
+                                       server_baton_t *b,
+                                       svn_revnum_t rev,
+                                       const char *name,
+                                       const svn_string_t *const *old_value_p,
+                                       const svn_string_t *value,
+                                       apr_pool_t *pool)
+{
+  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, FALSE));
+  SVN_ERR(log_command(b, conn, pool, "%s",
+                      svn_log__change_rev_prop(rev, name, pool)));
+  SVN_CMD_ERR(svn_repos_fs_change_rev_prop4(b->repos, rev, b->user,
+                                            name, old_value_p, value,
+                                            TRUE, TRUE,
+                                            authz_check_access_cb_func(b), b,
+                                            pool));
+  SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, ""));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *change_rev_prop2(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+                                     apr_array_header_t *params, void *baton)
+{
+  server_baton_t *b = baton;
+  svn_revnum_t rev;
+  const char *name;
+  svn_string_t *value;
+  
+  svn_string_t *old_value;
+  svn_boolean_t dont_care;
+
+  SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "rc(?s)(b?s)",
+                                 &rev, &name, &value,
+                                 &dont_care, &old_value));
+
+  /* Argument parsing. */
+  if (dont_care)
+    old_value_p = NULL;
+  else
+    old_value_p = (const svn_string_t *const *)&old_value;
+
+  /* Input validation. */
+  if (dont_care && old_value)
+    {
+      svn_error_t *err;
+      err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                             "'previous-value' and 'dont-care' cannot both be "
+                             "set in 'change-rev-prop2' request");
+      return log_fail_and_flush(err, b, conn, pool);
+    }
+
+  /* Do it. */
+  SVN_ERR(do_change_rev_prop(conn, b, rev, name, old_value_p, value, pool));
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *change_rev_prop(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                     apr_array_header_t *params, void *baton)
 {
@@ -1006,14 +1065,8 @@ static svn_error_t *change_rev_prop(svn_
      optional element pattern "(?s)" isn't used. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "rc?s", &rev, &name, &value));
 
-  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, FALSE));
-  SVN_ERR(log_command(b, conn, pool, "%s",
-                      svn_log__change_rev_prop(rev, name, pool)));
-  SVN_CMD_ERR(svn_repos_fs_change_rev_prop3(b->repos, rev, b->user,
-                                            name, value, TRUE, TRUE,
-                                            authz_check_access_cb_func(b), b,
-                                            pool));
-  SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, ""));
+  SVN_ERR(do_change_rev_prop(conn, b, rev, name, NULL, value, pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -2755,6 +2808,7 @@ static const svn_ra_svn_cmd_entry_t main
   { "get-latest-rev",  get_latest_rev },
   { "get-dated-rev",   get_dated_rev },
   { "change-rev-prop", change_rev_prop },
+  { "change-rev-prop2",change_rev_prop2 },
   { "rev-proplist",    rev_proplist },
   { "rev-prop",        rev_prop },
   { "commit",          commit },
@@ -2978,7 +3032,8 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
 
   /* Send greeting.  We don't support version 1 any more, so we can
    * send an empty mechlist. */
-  SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwww)",
+  /* Server-side capabilities list: */
+  SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "nn()(wwwwwwww)",
                                         (apr_uint64_t) 2, (apr_uint64_t) 2,
                                         SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                         SVN_RA_SVN_CAP_SVNDIFF1,
@@ -2986,6 +3041,7 @@ svn_error_t *serve(svn_ra_svn_conn_t *co
                                         SVN_RA_SVN_CAP_COMMIT_REVPROPS,
                                         SVN_RA_SVN_CAP_DEPTH,
                                         SVN_RA_SVN_CAP_LOG_REVPROPS,
+                                        SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
                                         SVN_RA_SVN_CAP_PARTIAL_REPLAY));
 
   /* Read client response, which we assume to be in version 2 format:


Reply via email to