Author: kotkov
Date: Fri Mar  5 15:28:42 2021
New Revision: 1887204

URL: http://svn.apache.org/viewvc?rev=1887204&view=rev
Log:
Fix the update editor so that it would properly take the current locks into
account when setting read-only attributes on files with svn:needs-lock.

This is a follow-up to r1886490, where I inadvertently broke this behavior
during the switch to an implementation that simultaneously writes the pristine
and working files.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_GET_LOCK): New.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_lock_get): Declare.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_lock_get): Implement this new function that allows fetching
   the lock information corresponding to the specified `repos_relpath`.
   Call it...

* subversion/libsvn_wc/update_editor.c
  (open_working_file_writer): ...here for files with svn:needs-lock to see if
   we have locks for them in the working copy.  Take that into account when
   determining if we have to make the file read-only.  Note that previously
   the lock state was fetched in a similar way (with a separate db query)
   while handling OP_FILE_INSTALL, so this does not change the number of
   queries for such files, compared to the state before r1886490.

* subversion/tests/cmdline/lock_tests.py
  (update_add_file_has_lock,
   update_edit_file_has_lock,
   update_remove_needs_lock): New tests.
  (test_list): Run the new tests.

Modified:
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/tests/cmdline/lock_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1887204&r1=1887203&r2=1887204&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Fri Mar  5 15:28:42 
2021
@@ -3627,7 +3627,6 @@ open_working_file_writer(svn_wc__working
   const char *eol;
   const char *keywords_propval;
   apr_hash_t *keywords;
-  const char *lock_token;
   const char *temp_dir_abspath;
   const char *cmt_rev_str;
   const char *cmt_date_str;
@@ -3675,8 +3674,6 @@ open_working_file_writer(svn_wc__working
       keywords = NULL;
     }
 
-  lock_token = svn_prop_get_value(props, SVN_PROP_ENTRY_LOCK_TOKEN);
-
   SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath,
                                          fb->edit_baton->db,
                                          fb->edit_baton->wcroot_abspath,
@@ -3687,10 +3684,22 @@ open_working_file_writer(svn_wc__working
   else
     final_mtime = -1;
 
-  if (needs_lock && !lock_token)
-    is_readonly = TRUE;
+  if (needs_lock)
+    {
+      svn_wc__db_lock_t *lock;
+
+      SVN_ERR(svn_wc__db_lock_get(&lock,
+                                  fb->edit_baton->db,
+                                  fb->edit_baton->wcroot_abspath,
+                                  fb->new_repos_relpath,
+                                  scratch_pool,
+                                  scratch_pool));
+      is_readonly = (lock == NULL);
+    }
   else
-    is_readonly = FALSE;
+    {
+      is_readonly = FALSE;
+    }
 
   SVN_ERR(svn_wc__working_file_writer_open(writer_p,
                                            temp_dir_abspath,

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1887204&r1=1887203&r2=1887204&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Fri Mar  5 15:28:42 
2021
@@ -1807,6 +1807,12 @@ WHERE wc_id = ?1 AND repos_path = ?2 AND
                     AND w.local_relpath = n.local_relpath)
 ORDER BY local_relpath ASC
 
+-- STMT_GET_LOCK
+SELECT lock_token, lock_owner, lock_comment, lock_date
+FROM lock
+WHERE repos_id = ?1 AND (repos_relpath = ?2)
+
+
 /* ------------------------------------------------------------------------- */
 
 /* Grab all the statements related to the schema.  */

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1887204&r1=1887203&r2=1887204&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Mar  5 15:28:42 2021
@@ -12560,6 +12560,43 @@ svn_wc__db_lock_remove(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
+
+svn_error_t *
+svn_wc__db_lock_get(svn_wc__db_lock_t **lock_p,
+                    svn_wc__db_t *db,
+                    const char *wri_abspath,
+                    const char *repos_relpath,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *wri_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  svn_wc__db_lock_t *lock;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db,
+                              wri_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_GET_LOCK));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, repos_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (have_row)
+    lock = lock_from_columns(stmt, 0, 1, 2, 3, result_pool);
+  else
+    lock = NULL;
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  *lock_p = lock;
+  return SVN_NO_ERROR;
+}
+
+
 /* A helper for scan_addition().
  * Compute moved-from information for the node at LOCAL_RELPATH which
  * has been determined as having been moved-here.

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1887204&r1=1887203&r2=1887204&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri Mar  5 15:28:42 2021
@@ -2711,6 +2711,18 @@ svn_wc__db_lock_remove(svn_wc__db_t *db,
                        apr_pool_t *scratch_pool);
 
 
+/* Fetch the information about the lock which corresponds to REPOS_RELPATH
+   within the working copy indicated by WRI_ABSPATH. Set *LOCK_P to NULL
+   if there is no such lock.  */
+svn_error_t *
+svn_wc__db_lock_get(svn_wc__db_lock_t **lock_p,
+                    svn_wc__db_t *db,
+                    const char *wri_abspath,
+                    const char *repos_relpath,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
+
+
 /* @} */
 
 

Modified: subversion/trunk/subversion/tests/cmdline/lock_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/lock_tests.py?rev=1887204&r1=1887203&r2=1887204&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/lock_tests.py Fri Mar  5 15:28:42 
2021
@@ -2509,6 +2509,64 @@ def update_edit_file_needs_lock(sbox):
   sbox.simple_update(revision=2)
   is_readonly(sbox.ospath('dir/file'))
 
+def update_add_file_has_lock(sbox):
+  "update adding svn:needs-lock file with lock"
+
+  sbox.build(empty=True)
+  sbox.simple_mkdir('dir')
+  sbox.simple_add_text('test\n', 'dir/file')
+  sbox.simple_propset('svn:needs-lock', 'yes', 'dir/file')
+  sbox.simple_commit()
+
+  # Acquire the lock for a file.
+  svntest.actions.run_and_verify_svn(".*locked by user", [], 'lock',
+                                     '-m', '', sbox.ospath('dir/file'))
+
+  sbox.simple_update(revision=0)
+  sbox.simple_update(revision=1)
+  # We have a lock for that file, so it should be writable.
+  is_writable(sbox.ospath('dir/file'))
+
+def update_edit_file_has_lock(sbox):
+  "update editing svn:needs-lock file with lock"
+
+  sbox.build(empty=True)
+  sbox.simple_mkdir('dir')
+  sbox.simple_add_text('test\n', 'dir/file')
+  sbox.simple_commit()
+
+  sbox.simple_append('dir/file', 'edited\n', truncate=True)
+  sbox.simple_propset('svn:needs-lock', 'yes', 'dir/file')
+  sbox.simple_commit()
+
+  # Acquire the lock for a file.
+  svntest.actions.run_and_verify_svn(".*locked by user", [], 'lock',
+                                     '-m', '', sbox.ospath('dir/file'))
+
+  sbox.simple_update(revision=1)
+  # No svn:needs-lock on the file, so it should be writable.
+  is_writable(sbox.ospath('dir/file'))
+  sbox.simple_update(revision=2)
+  # We have a lock for that file, so it should be writable.
+  is_writable(sbox.ospath('dir/file'))
+
+def update_remove_needs_lock(sbox):
+  "update removing svn:needs-lock on a file"
+
+  sbox.build(empty=True)
+  sbox.simple_mkdir('dir')
+  sbox.simple_add_text('test\n', 'dir/file')
+  sbox.simple_propset('svn:needs-lock', 'yes', 'dir/file')
+  sbox.simple_commit()
+
+  sbox.simple_propdel('svn:needs-lock', 'dir/file')
+  sbox.simple_commit()
+
+  sbox.simple_update(revision=1)
+  is_readonly(sbox.ospath('dir/file'))
+  sbox.simple_update(revision=2)
+  is_writable(sbox.ospath('dir/file'))
+
 ########################################################################
 # Run the tests
 
@@ -2579,6 +2637,9 @@ test_list = [ None,
               replace_dir_with_lots_of_locked_files,
               update_add_file_needs_lock,
               update_edit_file_needs_lock,
+              update_add_file_has_lock,
+              update_edit_file_has_lock,
+              update_remove_needs_lock,
             ]
 
 if __name__ == '__main__':


Reply via email to