Author: philip
Date: Sat Feb 28 00:51:41 2015
New Revision: 1662867
URL: http://svn.apache.org/r1662867
Log:
SWIG Python support for svn_fs_lock_many, svn_fs_unlock_many,
svn_repos_fs_lock_many and svn_repos_unlock_many.
* subversion/include/svn_fs.h
(svn_fs_lock_many, svn_fs_unlock_many): Rename parameter so that it
can be mapped by SWIG.
* subversion/include/svn_repos.h
(svn_repos_fs_lock_many, svn_repos_fs_unlock_many): Rename parameter
so that it can be mapped by SWIG.
* subversion/bindings/swig/include/svn_containers.swg
(unlock_targets, lock_targets): New typemaps.
* subversion/bindings/swig/svn_fs.i
(svn_swig_py_fs_lock_callback): New callback_typemap.
* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
(svn_swig_py_fs_lock_callback): New.
* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
(make_ob_error, svn_swig_py_fs_lock_callback): New.
* subversion/bindings/swig/python/tests/repository.py
(test_lock_unlock): New test.
Modified:
subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
subversion/trunk/subversion/bindings/swig/python/tests/repository.py
subversion/trunk/subversion/bindings/swig/svn_fs.i
subversion/trunk/subversion/include/svn_fs.h
subversion/trunk/subversion/include/svn_repos.h
Modified: subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/include/svn_containers.swg?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
(original)
+++ subversion/trunk/subversion/bindings/swig/include/svn_containers.swg Sat
Feb 28 00:51:41 2015
@@ -426,6 +426,25 @@
{
$1 = svn_swig_py_path_revs_hash_from_dict($input, _global_pool);
}
+%typemap(in) apr_hash_t *unlock_targets
+{
+ $1 = svn_swig_py_stringhash_from_dict($input, _global_pool);
+}
+%typemap(in) apr_hash_t *lock_targets
+ (apr_pool_t *_global_pool, PyObject *_global_pool = NULL)
+{
+ if (_global_pool == NULL)
+ {
+ if (svn_swig_py_get_parent_pool(args, $descriptor(apr_pool_t *),
+ &_global_py_pool, &_global_pool))
+ SWIG_fail;
+ }
+ $1 = svn_swig_py_struct_ptr_hash_from_dict($input,
+ $descriptor(svn_fs_lock_target_t *), _global_pool);
+ if (PyErr_Occurred()) {
+ SWIG_fail;
+ }
+}
#endif
#ifdef SWIGPERL
Modified:
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
(original)
+++
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
Sat Feb 28 00:51:41 2015
@@ -459,6 +459,14 @@ static PyObject *make_ob_wc_adm_access(v
NULL);
}
+static PyObject *make_ob_error(svn_error_t *err)
+{
+ if (err)
+ return svn_swig_NewPointerObjString(err, "svn_error_t *", NULL);
+ else
+ return Py_None;
+}
+
/***/
@@ -2853,6 +2861,42 @@ svn_error_t *svn_swig_py_fs_get_locks_fu
return err;
}
+svn_error_t *svn_swig_py_fs_lock_callback(
+ void *baton,
+ const char *path,
+ const svn_lock_t *lock,
+ svn_error_t *fs_err,
+ apr_pool_t *pool)
+{
+ svn_error_t *err = SVN_NO_ERROR;
+ PyObject *py_callback = baton, *result;
+
+ if (py_callback == NULL || py_callback == Py_None)
+ return SVN_NO_ERROR;
+
+ svn_swig_py_acquire_py_lock();
+
+ if ((result = PyObject_CallFunction(py_callback,
+ (char *)"sO&O&O&",
+ path,
+ make_ob_lock, lock,
+ make_ob_error, fs_err,
+ make_ob_pool, pool)) == NULL)
+ {
+ err = callback_exception_error();
+ }
+ else if (result != Py_None)
+ {
+ err = callback_bad_return_error("Not None");
+ }
+
+ Py_XDECREF(result);
+
+ svn_swig_py_release_py_lock();
+ return err;
+}
+
+
svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg,
const char **tmp_file,
const apr_array_header_t *
Modified:
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
(original)
+++
subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
Sat Feb 28 00:51:41 2015
@@ -316,6 +316,13 @@ svn_error_t *svn_swig_py_fs_get_locks_fu
svn_lock_t *lock,
apr_pool_t *pool);
+svn_error_t *svn_swig_py_fs_lock_callback(
+ void *baton,
+ const char *path,
+ const svn_lock_t *lock,
+ svn_error_t *ra_err,
+ apr_pool_t *pool);
+
/* thunked commit log fetcher */
svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg,
const char **tmp_file,
Modified: subversion/trunk/subversion/bindings/swig/python/tests/repository.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/tests/repository.py?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/tests/repository.py
(original)
+++ subversion/trunk/subversion/bindings/swig/python/tests/repository.py Sat
Feb 28 00:51:41 2015
@@ -311,6 +311,98 @@ class SubversionRepositoryTestCase(unitt
repos.freeze([self.repos_path], self.freeze_body)
self.assertEqual(self.freeze_invoked, 1)
+ def test_lock_unlock(self):
+ """Basic lock/unlock"""
+
+ access = fs.create_access('jrandom')
+ fs.set_access(self.fs, access)
+ fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, False)
+ try:
+ fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, False)
+ except core.SubversionException, exc:
+ self.assertEqual(exc.apr_err, core.SVN_ERR_FS_PATH_ALREADY_LOCKED)
+ fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, True)
+
+ self.calls = 0
+ self.errors = 0
+ def unlock_callback(path, lock, err, pool):
+ self.assertEqual(path, '/trunk/README.txt')
+ self.assertEqual(lock, None)
+ self.calls += 1
+ if err != None:
+ self.assertEqual(err.apr_err, core.SVN_ERR_FS_NO_SUCH_LOCK)
+ self.errors += 1
+
+ the_lock = fs.get_lock(self.fs, '/trunk/README.txt')
+ fs.unlock_many(self.fs, {'/trunk/README.txt':the_lock.token}, False,
+ unlock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.errors, 0)
+
+ self.calls = 0
+ fs.unlock_many(self.fs, {'/trunk/README.txt':the_lock.token}, False,
+ unlock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.errors, 1)
+
+ self.locks = 0
+ def lock_callback(path, lock, err, pool):
+ self.assertEqual(path, '/trunk/README.txt')
+ if lock != None:
+ self.assertEqual(lock.owner, 'jrandom')
+ self.locks += 1
+ self.calls += 1
+ if err != None:
+ self.assertEqual(err.apr_err, core.SVN_ERR_FS_PATH_ALREADY_LOCKED)
+ self.errors += 1
+
+ self.calls = 0
+ self.errors = 0
+ target = fs.lock_target_create(None, self.rev)
+ fs.lock_many(self.fs, {'trunk/README.txt':target},
+ None, False, 0, False, lock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.locks, 1)
+ self.assertEqual(self.errors, 0)
+
+ self.calls = 0
+ self.locks = 0
+ fs.lock_many(self.fs, {'trunk/README.txt':target},
+ None, False, 0, False, lock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.locks, 0)
+ self.assertEqual(self.errors, 1)
+
+ self.calls = 0
+ self.errors = 0
+ the_lock = fs.get_lock(self.fs, '/trunk/README.txt')
+ repos.fs_unlock_many(self.repos, {'trunk/README.txt':the_lock.token},
+ False, unlock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.errors, 0)
+
+ self.calls = 0
+ repos.fs_unlock_many(self.repos, {'trunk/README.txt':the_lock.token},
+ False, unlock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.errors, 1)
+
+ self.calls = 0
+ self.errors = 0
+ repos.fs_lock_many(self.repos, {'trunk/README.txt':target},
+ None, False, 0, False, lock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.locks, 1)
+ self.assertEqual(self.errors, 0)
+
+ self.calls = 0
+ self.locks = 0
+ repos.fs_lock_many(self.repos, {'trunk/README.txt':target},
+ None, False, 0, False, lock_callback)
+ self.assertEqual(self.calls, 1)
+ self.assertEqual(self.locks, 0)
+ self.assertEqual(self.errors, 1)
+
def suite():
return unittest.defaultTestLoader.loadTestsFromTestCase(
SubversionRepositoryTestCase)
Modified: subversion/trunk/subversion/bindings/swig/svn_fs.i
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/svn_fs.i?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/svn_fs.i (original)
+++ subversion/trunk/subversion/bindings/swig/svn_fs.i Sat Feb 28 00:51:41 2015
@@ -71,6 +71,14 @@
,
svn_swig_rb_fs_get_locks_callback)
#endif
+
+#ifdef SWIGPYTHON
+%callback_typemap(svn_fs_lock_callback_t lock_callback, void *lock_baton,
+ svn_swig_py_fs_lock_callback,
+ ,
+ )
+#endif
+
/* -----------------------------------------------------------------------
svn_fs_get_merge_info
*/
Modified: subversion/trunk/subversion/include/svn_fs.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Sat Feb 28 00:51:41 2015
@@ -2661,7 +2661,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
svn_error_t *fs_err,
apr_pool_t *pool);
-/** Lock the paths in @a targets in @a fs.
+/** Lock the paths in @a lock_targets in @a fs.
*
* @a fs must have a username associated with it (see
* #svn_fs_access_t), else return #SVN_ERR_FS_NO_USER. Set the
@@ -2675,7 +2675,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
* to use it. If in doubt, pass 0.
*
* The paths to be locked are passed as the <tt>const char *</tt> keys
- * of the @a targets hash. The hash values are
+ * of the @a lock_targets hash. The hash values are
* <tt>svn_fs_lock_target_t *</tt> and provide the token and
* @a current_rev for each path. The token is a lock token such as can
* be generated using svn_fs_generate_lock_token() (indicating that
@@ -2697,7 +2697,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
* If @a expiration_date is zero, then create a non-expiring lock.
* Else, the lock will expire at @a expiration_date.
*
- * For each path in @a targets @a lock_callback will be invoked
+ * For each path in @a lock_targets @a lock_callback will be invoked
* passing @a lock_baton and the lock and error that apply to path.
* @a lock_callback can be NULL in which case it is not called.
*
@@ -2713,7 +2713,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
*/
svn_error_t *
svn_fs_lock_many(svn_fs_t *fs,
- apr_hash_t *targets,
+ apr_hash_t *lock_targets,
const char *comment,
svn_boolean_t is_dav_comment,
apr_time_t expiration_date,
@@ -2753,10 +2753,10 @@ svn_fs_generate_lock_token(const char **
apr_pool_t *pool);
-/** Remove the locks on the paths in @a targets in @a fs.
+/** Remove the locks on the paths in @a unlock_targets in @a fs.
*
* The paths to be unlocked are passed as <tt>const char *</tt> keys
- * of the @a targets hash with the corresponding lock tokens as
+ * of the @a unlock_targets hash with the corresponding lock tokens as
* <tt>const char *</tt> values. If the token doesn't point to a
* lock, yield an #SVN_ERR_FS_BAD_LOCK_TOKEN error for this path. If
* the token points to an expired lock, yield an
@@ -2770,7 +2770,7 @@ svn_fs_generate_lock_token(const char **
* however, don't return error; allow the lock to be "broken" in any
* case. In the latter case, the token shall be @c NULL.
*
- * For each path in @a targets @a lock_callback will be invoked
+ * For each path in @a unlock_targets @a lock_callback will be invoked
* passing @a lock_baton and error that apply to path. The @a lock
* passed to the callback will be NULL. @a lock_callback can be NULL
* in which case it is not called.
@@ -2785,7 +2785,7 @@ svn_fs_generate_lock_token(const char **
*/
svn_error_t *
svn_fs_unlock_many(svn_fs_t *fs,
- apr_hash_t *targets,
+ apr_hash_t *unlock_targets,
svn_boolean_t break_lock,
svn_fs_lock_callback_t lock_callback,
void *lock_baton,
Modified: subversion/trunk/subversion/include/svn_repos.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1662867&r1=1662866&r2=1662867&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Sat Feb 28 00:51:41 2015
@@ -2273,7 +2273,7 @@ svn_repos_fs_begin_txn_for_update(svn_fs
*/
svn_error_t *
svn_repos_fs_lock_many(svn_repos_t *repos,
- apr_hash_t *targets,
+ apr_hash_t *lock_targets,
const char *comment,
svn_boolean_t is_dav_comment,
apr_time_t expiration_date,
@@ -2325,7 +2325,7 @@ svn_repos_fs_lock(svn_lock_t **lock,
*/
svn_error_t *
svn_repos_fs_unlock_many(svn_repos_t *repos,
- apr_hash_t *targets,
+ apr_hash_t *unlock_targets,
svn_boolean_t break_lock,
svn_fs_lock_callback_t lock_callback,
void *lock_baton,