You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/03/21 02:48:34 UTC
svn commit: r1303252 -
/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
Author: pburba
Date: Wed Mar 21 01:48:34 2012
New Revision: 1303252
URL: http://svn.apache.org/viewvc?rev=1303252&view=rev
Log:
On the inheritable-props branch: Develop a fallback which allows new clients
to get inherited props from servers that don't have the
SVN_RA_CAPABILITY_INHERITED_PROPS capability.
* subversion/libsvn_ra/ra_loader.c
(svn_props.h, svn_sorts.h): New #includes.
(get_inherited_props): New.
(svn_ra_get_file2,
svn_ra_get_dir3): Use new fallback code when getting inherited props from
and old server.
Modified:
subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c?rev=1303252&r1=1303251&r2=1303252&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c Wed Mar 21 01:48:34 2012
@@ -43,6 +43,9 @@
#include "svn_xml.h"
#include "svn_path.h"
#include "svn_dso.h"
+#include "svn_props.h"
+#include "svn_sorts.h"
+
#include "svn_config.h"
#include "ra_loader.h"
@@ -733,6 +736,97 @@ svn_error_t *svn_ra_get_commit_editor3(s
lock_tokens, keep_locks, pool);
}
+/* Helper for svn_ra_get_file2 and svn_ra_get_dir3 when those APIs need to
+ find PATH's inherited properties on a legacy server that doesn't have the
+ SVN_RA_CAPABILITY_INHERITED_PROPS capability.
+
+ All arguments are as per the two aforementioned APIs. */
+static svn_error_t*
+get_inherited_props(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ apr_array_header_t **inherited_props,
+ apr_pool_t *pool)
+{
+ const char *repos_root_url;
+ const char *session_url;
+ const char *parent_url;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ apr_pool_t *iterpool = svn_pool_create(pool);
+
+ *inherited_props =
+ apr_array_make(pool, 1, sizeof(svn_prop_inherited_item_t *));
+
+ /* Walk to the root of the repository getting inherited
+ props for PATH. */
+ SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, subpool));
+ SVN_ERR(svn_ra_get_session_url(session, &session_url, subpool));
+ parent_url = session_url;
+
+ while (strcmp(repos_root_url, parent_url))
+ {
+ apr_hash_index_t *hi;
+ apr_hash_t *parent_props;
+ apr_hash_t *final_hash = apr_hash_make(pool);
+ svn_error_t *err;
+
+ svn_pool_clear(iterpool);
+ parent_url = svn_uri_dirname(parent_url, iterpool);
+ SVN_ERR(svn_ra_reparent(session, parent_url, iterpool));
+ err = session->vtable->get_dir(session, NULL, NULL,
+ &parent_props, NULL, "",
+ revision, SVN_DIRENT_ALL,
+ iterpool);
+
+ /* If the user doesn't have read access to a parent path then
+ skip, but allow them to inherit from further up. */
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_RA_NOT_AUTHORIZED)
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ else
+ {
+ return svn_error_trace(err);
+ }
+ }
+
+ for (hi = apr_hash_first(subpool, parent_props);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *name = svn__apr_hash_index_key(hi);
+ apr_ssize_t klen = svn__apr_hash_index_klen(hi);
+ svn_string_t *value = svn__apr_hash_index_val(hi);
+
+ if (svn_property_kind(NULL, name) == svn_prop_regular_kind)
+ {
+ name = apr_pstrdup(pool, name);
+ value = svn_string_dup(value, pool);
+ apr_hash_set(final_hash, name, klen, value);
+ }
+ }
+
+ if (apr_hash_count(final_hash))
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(pool, sizeof(*new_iprop));
+ new_iprop->path_or_url = apr_pstrdup(pool, parent_url);
+ new_iprop->prop_hash = final_hash;
+ svn_sort__array_insert(&new_iprop, *inherited_props, 0);
+ }
+ }
+
+ /* Reparent session back to original URL. */
+ SVN_ERR(svn_ra_reparent(session, session_url, subpool));
+
+ svn_pool_destroy(iterpool);
+ svn_pool_destroy(subpool);
+ return SVN_NO_ERROR;
+}
+
svn_error_t *svn_ra_get_file2(svn_ra_session_t *session,
const char *path,
svn_revnum_t revision,
@@ -743,8 +837,37 @@ svn_error_t *svn_ra_get_file2(svn_ra_ses
apr_pool_t *pool)
{
SVN_ERR_ASSERT(*path != '/');
- return session->vtable->get_file(session, path, revision, stream,
- fetched_rev, props, inherited_props, pool);
+
+ if (inherited_props)
+ {
+ svn_boolean_t gets_iprops;
+
+ /* We want inherited props too, can the server deliver? */
+ SVN_ERR(svn_ra_has_capability(session, &gets_iprops,
+ SVN_RA_CAPABILITY_INHERITED_PROPS,
+ pool));
+ if (gets_iprops)
+ {
+ SVN_ERR(session->vtable->get_file(session, path, revision, stream,
+ fetched_rev, props,
+ inherited_props, pool));
+ }
+ else
+ {
+ /* Get the explicit props on PATH. */
+ SVN_ERR(session->vtable->get_file(session, path, revision, stream,
+ fetched_rev, props, NULL, pool));
+ SVN_ERR(get_inherited_props(session, path, revision,
+ inherited_props, pool));
+ }
+ }
+ else
+ {
+ SVN_ERR(session->vtable->get_file(session, path, revision, stream,
+ fetched_rev, props, NULL, pool));
+ }
+
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -759,9 +882,39 @@ svn_ra_get_dir3(svn_ra_session_t *sessio
apr_pool_t *pool)
{
SVN_ERR_ASSERT(*path != '/');
- return session->vtable->get_dir(session, dirents, fetched_rev, props,
- inherited_props, path, revision,
- dirent_fields, pool);
+
+ if (inherited_props)
+ {
+ svn_boolean_t gets_iprops;
+
+ /* We want inherited props too, can the server deliver? */
+ SVN_ERR(svn_ra_has_capability(session, &gets_iprops,
+ SVN_RA_CAPABILITY_INHERITED_PROPS,
+ pool));
+ if (gets_iprops)
+ {
+ SVN_ERR(session->vtable->get_dir(session, dirents, fetched_rev, props,
+ inherited_props, path, revision,
+ dirent_fields, pool));
+ }
+ else
+ {
+ /* Get the explicit props on PATH. */
+ SVN_ERR(session->vtable->get_dir(session, dirents, fetched_rev,
+ props, NULL, path, revision,
+ dirent_fields, pool));
+ SVN_ERR(get_inherited_props(session, path, revision,
+ inherited_props, pool));
+ }
+ }
+ else
+ {
+ return session->vtable->get_dir(session, dirents, fetched_rev, props,
+ NULL, path, revision, dirent_fields,
+ pool);
+ }
+
+ return SVN_NO_ERROR;
}
svn_error_t *svn_ra_get_mergeinfo(svn_ra_session_t *session,
Re: svn commit: r1303252 -
/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
Posted by Daniel Shahaf <da...@elego.de>.
pburba@apache.org wrote on Wed, Mar 21, 2012 at 01:48:34 -0000:
> +/* Helper for svn_ra_get_file2 and svn_ra_get_dir3 when those APIs need to
> + find PATH's inherited properties on a legacy server that doesn't have the
> + SVN_RA_CAPABILITY_INHERITED_PROPS capability.
> +
> + All arguments are as per the two aforementioned APIs. */
> +static svn_error_t*
> +get_inherited_props(svn_ra_session_t *session,
> + const char *path,
> + svn_revnum_t revision,
> + apr_array_header_t **inherited_props,
> + apr_pool_t *pool)
> +{
> + /* Walk to the root of the repository getting inherited
> + props for PATH. */
> + SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, subpool));
> + SVN_ERR(svn_ra_get_session_url(session, &session_url, subpool));
> + parent_url = session_url;
> +
> + while (strcmp(repos_root_url, parent_url))
> + {
> + parent_url = svn_uri_dirname(parent_url, iterpool);
> + SVN_ERR(svn_ra_reparent(session, parent_url, iterpool));
* danielsh wonders if an assert(parent_url.startswith(repos_root_url)) is in order
Re: svn commit: r1303252 -
/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c
Posted by Daniel Shahaf <da...@elego.de>.
pburba@apache.org wrote on Wed, Mar 21, 2012 at 01:48:34 -0000:
> +/* Helper for svn_ra_get_file2 and svn_ra_get_dir3 when those APIs need to
> + find PATH's inherited properties on a legacy server that doesn't have the
> + SVN_RA_CAPABILITY_INHERITED_PROPS capability.
> +
> + All arguments are as per the two aforementioned APIs. */
> +static svn_error_t*
> +get_inherited_props(svn_ra_session_t *session,
> + const char *path,
> + svn_revnum_t revision,
> + apr_array_header_t **inherited_props,
> + apr_pool_t *pool)
> +{
> + /* Walk to the root of the repository getting inherited
> + props for PATH. */
> + SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, subpool));
> + SVN_ERR(svn_ra_get_session_url(session, &session_url, subpool));
> + parent_url = session_url;
> +
> + while (strcmp(repos_root_url, parent_url))
> + {
> + parent_url = svn_uri_dirname(parent_url, iterpool);
> + SVN_ERR(svn_ra_reparent(session, parent_url, iterpool));
* danielsh wonders if an assert(parent_url.startswith(repos_root_url)) is in order