danie...@apache.org writes:

> Author: danielsh
> Date: Wed Jun 16 06:05:17 2010
> New Revision: 955136
>
> URL: http://svn.apache.org/viewvc?rev=955136&view=rev
> Log:
> Revv the FS change_rev_prop() interface towards more atomicity.
>
> Suggested by: philip
>
>
> * subversion/include/svn_fs.h
>   (svn_fs_change_rev_prop2):  New, takes OLD_VALUE_P parameter.
>   (svn_fs_change_rev_prop):  Deprecate.

I don't think the old interface should be deprecated.

> ==============================================================================
> --- subversion/trunk/subversion/include/svn_fs.h (original)
> +++ subversion/trunk/subversion/include/svn_fs.h Wed Jun 16 06:05:17 2010
> @@ -1894,6 +1894,10 @@ svn_fs_revision_proplist(apr_hash_t **ta
>   * - @a fs is a filesystem, and @a rev is the revision in that filesystem
>   *   whose property should change.
>   * - @a name is the name of the property to change.
> + * - if @a old_value_p is not @c NULL, then @a *old_value_p is the expected 
> old
> + *   value of the property, and changing the value will fail with error
> + *   #SVN_ERR_BAD_PROPERTY_VALUE if the present value of the property is not 
> @a
> + *   *old_value_p.
>   * - @a value is the new value of the property, or zero if the property 
> should

How are you going to check adds?  During an add the old value is NULL
but must still be checked.


>   *   be removed altogether.
>   *
> @@ -1902,7 +1906,25 @@ svn_fs_revision_proplist(apr_hash_t **ta
>   * via transactions.
>   *
>   * Do any necessary temporary allocation in @a pool.
> + *
> + * @since New in 1.7.
> + */
> +svn_error_t *
> +svn_fs_change_rev_prop2(svn_fs_t *fs,
> +                        svn_revnum_t rev,
> +                        const char *name,
> +                        const svn_string_t **old_value_p,
> +                        const svn_string_t *value,
> +                        apr_pool_t *pool);
> +
> +

>  svn_fs_base__set_rev_prop(svn_fs_t *fs,
>                            svn_revnum_t rev,
>                            const char *name,
> +                          const svn_string_t **old_value_p,
>                            const svn_string_t *value,
>                            trail_t *trail,
>                            apr_pool_t *pool)
> @@ -259,6 +260,23 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,
>      txn->proplist = apr_hash_make(pool);
>  
>    /* Set the property. */
> +  if (old_value_p)
> +    {

That's not going to work for adds because it will skip the validation.

> +      const svn_string_t *wanted_value = *old_value_p;
> +      const svn_string_t *present_value = apr_hash_get(txn->proplist, name,
> +                                                       APR_HASH_KEY_STRING);
> +      if ((!wanted_value != !present_value)
> +          || (wanted_value && present_value
> +              && !svn_string_compare(wanted_value, present_value)))
> +        {
> +          /* What we expected isn't what we found. */
> +          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
> +                                   _("revprop '%s' has unexpected value in "
> +                                     "filesystem"),
> +                                   name);
> +        }
> +      /* Fall through. */
> +    }
>    apr_hash_set(txn->proplist, name, APR_HASH_KEY_STRING, value);

> Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
> URL: 
> http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=955136&r1=955135&r2=955136&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
> +++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Wed Jun 16 06:05:17 2010
> @@ -7167,6 +7167,7 @@ struct change_rev_prop_baton {
>    svn_fs_t *fs;
>    svn_revnum_t rev;
>    const char *name;
> +  const svn_string_t **old_value_p;
>    const svn_string_t *value;
>  };
>  
> @@ -7182,6 +7183,23 @@ change_rev_prop_body(void *baton, apr_po
>  
>    SVN_ERR(svn_fs_fs__revision_proplist(&table, cb->fs, cb->rev, pool));
>  
> +  if (cb->old_value_p)
> +    {

Again, that's not going to work for adds.

> +      const svn_string_t *wanted_value = *cb->old_value_p;
> +      const svn_string_t *present_value = apr_hash_get(table, cb->name,
> +                                                       APR_HASH_KEY_STRING);
> +      if ((!wanted_value != !present_value)
> +          || (wanted_value && present_value
> +              && !svn_string_compare(wanted_value, present_value)))
> +        {
> +          /* What we expected isn't what we found. */
> +          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
> +                                   _("revprop '%s' has unexpected value in "
> +                                     "filesystem"),
> +                                   cb->name);
> +        }
> +      /* Fall through. */
> +    }

> --- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
> +++ subversion/trunk/subversion/tests/libsvn_fs/fs-test.c Wed Jun 16 06:05:17 
> 2010
> @@ -593,8 +593,11 @@ revision_props(const svn_test_opts_t *op
>    svn_fs_t *fs;
>    apr_hash_t *proplist;
>    svn_string_t *value;
> +  svn_error_t *err;
>    int i;
>    svn_string_t s1;
> +  const svn_string_t s2 = { "wrong value", 11 };
> +  const svn_string_t *s2_p = &s2;
>  
>    const char *initial_props[4][2] = {
>      { "color", "red" },
> @@ -638,6 +641,14 @@ revision_props(const svn_test_opts_t *op
>    s1.len = value->len;
>    SVN_ERR(svn_fs_change_rev_prop(fs, 0, "flower", &s1, pool));
>  
> +  err = svn_fs_change_rev_prop2(fs, 0, "flower", &s2_p, &s1, pool);
> +  if (!err || err->apr_err != SVN_ERR_BAD_PROPERTY_VALUE)
> +    return svn_error_create(SVN_ERR_TEST_FAILED, err,
> +                            "svn_fs_change_rev_prop2() failed to "
> +                            "detect unexpected old value");
> +  else
> +    svn_error_clear(err);

I'd like to see adds, modifications and deletes all tested to pass and
fail.

> +
>    /* Obtain a list of all current properties, and make sure it matches
>       the expected values. */
>    SVN_ERR(svn_fs_revision_proplist(&proplist, fs, 0, pool));
>
>

-- 
Philip

Reply via email to