Deleted Added
full compact
wc_db.c (286506) wc_db.c (289180)
1/*
2 * wc_db.c : manipulating the administrative database
3 *
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file

--- 13 unchanged lines hidden (view full) ---

22 */
23
24#define SVN_WC__I_AM_WC_DB
25
26#include <assert.h>
27#include <apr_pools.h>
28#include <apr_hash.h>
29
1/*
2 * wc_db.c : manipulating the administrative database
3 *
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file

--- 13 unchanged lines hidden (view full) ---

22 */
23
24#define SVN_WC__I_AM_WC_DB
25
26#include <assert.h>
27#include <apr_pools.h>
28#include <apr_hash.h>
29
30#include "svn_private_config.h"
30#include "svn_types.h"
31#include "svn_error.h"
32#include "svn_dirent_uri.h"
33#include "svn_path.h"
34#include "svn_hash.h"
35#include "svn_sorts.h"
36#include "svn_wc.h"
37#include "svn_checksum.h"

--- 5 unchanged lines hidden (view full) ---

43#include "wc-queries.h"
44#include "entries.h"
45#include "lock.h"
46#include "conflicts.h"
47#include "wc_db_private.h"
48#include "workqueue.h"
49#include "token-map.h"
50
31#include "svn_types.h"
32#include "svn_error.h"
33#include "svn_dirent_uri.h"
34#include "svn_path.h"
35#include "svn_hash.h"
36#include "svn_sorts.h"
37#include "svn_wc.h"
38#include "svn_checksum.h"

--- 5 unchanged lines hidden (view full) ---

44#include "wc-queries.h"
45#include "entries.h"
46#include "lock.h"
47#include "conflicts.h"
48#include "wc_db_private.h"
49#include "workqueue.h"
50#include "token-map.h"
51
51#include "svn_private_config.h"
52#include "private/svn_sorts_private.h"
52#include "private/svn_sqlite.h"
53#include "private/svn_skel.h"
54#include "private/svn_wc_private.h"
55#include "private/svn_token.h"
56
57
58#define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
59

--- 212 unchanged lines hidden (view full) ---

272
273/* Forward declarations */
274static svn_error_t *
275add_work_items(svn_sqlite__db_t *sdb,
276 const svn_skel_t *skel,
277 apr_pool_t *scratch_pool);
278
279static svn_error_t *
53#include "private/svn_sqlite.h"
54#include "private/svn_skel.h"
55#include "private/svn_wc_private.h"
56#include "private/svn_token.h"
57
58
59#define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
60

--- 212 unchanged lines hidden (view full) ---

273
274/* Forward declarations */
275static svn_error_t *
276add_work_items(svn_sqlite__db_t *sdb,
277 const svn_skel_t *skel,
278 apr_pool_t *scratch_pool);
279
280static svn_error_t *
280set_actual_props(apr_int64_t wc_id,
281set_actual_props(svn_wc__db_wcroot_t *wcroot,
281 const char *local_relpath,
282 apr_hash_t *props,
282 const char *local_relpath,
283 apr_hash_t *props,
283 svn_sqlite__db_t *db,
284 apr_pool_t *scratch_pool);
285
286static svn_error_t *
287insert_incomplete_children(svn_sqlite__db_t *sdb,
288 apr_int64_t wc_id,
289 const char *local_relpath,
290 apr_int64_t repos_id,
291 const char *repos_relpath,

--- 57 unchanged lines hidden (view full) ---

349 apr_pool_t *result_pool,
350 apr_pool_t *scratch_pool);
351
352static svn_error_t *
353convert_to_working_status(svn_wc__db_status_t *working_status,
354 svn_wc__db_status_t status);
355
356static svn_error_t *
284 apr_pool_t *scratch_pool);
285
286static svn_error_t *
287insert_incomplete_children(svn_sqlite__db_t *sdb,
288 apr_int64_t wc_id,
289 const char *local_relpath,
290 apr_int64_t repos_id,
291 const char *repos_relpath,

--- 57 unchanged lines hidden (view full) ---

349 apr_pool_t *result_pool,
350 apr_pool_t *scratch_pool);
351
352static svn_error_t *
353convert_to_working_status(svn_wc__db_status_t *working_status,
354 svn_wc__db_status_t status);
355
356static svn_error_t *
357wclock_owns_lock(svn_boolean_t *own_lock,
358 svn_wc__db_wcroot_t *wcroot,
359 const char *local_relpath,
360 svn_boolean_t exact,
361 apr_pool_t *scratch_pool);
362
363static svn_error_t *
364db_is_switched(svn_boolean_t *is_switched,
365 svn_node_kind_t *kind,
366 svn_wc__db_wcroot_t *wcroot,
367 const char *local_relpath,
368 apr_pool_t *scratch_pool);
369
370
371/* Return the absolute path, in local path style, of LOCAL_RELPATH

--- 47 unchanged lines hidden (view full) ---

419 }
420 return lock;
421}
422
423
424svn_error_t *
425svn_wc__db_fetch_repos_info(const char **repos_root_url,
426 const char **repos_uuid,
357db_is_switched(svn_boolean_t *is_switched,
358 svn_node_kind_t *kind,
359 svn_wc__db_wcroot_t *wcroot,
360 const char *local_relpath,
361 apr_pool_t *scratch_pool);
362
363
364/* Return the absolute path, in local path style, of LOCAL_RELPATH

--- 47 unchanged lines hidden (view full) ---

412 }
413 return lock;
414}
415
416
417svn_error_t *
418svn_wc__db_fetch_repos_info(const char **repos_root_url,
419 const char **repos_uuid,
427 svn_sqlite__db_t *sdb,
420 svn_wc__db_wcroot_t *wcroot,
428 apr_int64_t repos_id,
429 apr_pool_t *result_pool)
430{
431 svn_sqlite__stmt_t *stmt;
432 svn_boolean_t have_row;
433
434 if (!repos_root_url && !repos_uuid)
435 return SVN_NO_ERROR;
436
437 if (repos_id == INVALID_REPOS_ID)
438 {
439 if (repos_root_url)
440 *repos_root_url = NULL;
441 if (repos_uuid)
442 *repos_uuid = NULL;
443 return SVN_NO_ERROR;
444 }
445
421 apr_int64_t repos_id,
422 apr_pool_t *result_pool)
423{
424 svn_sqlite__stmt_t *stmt;
425 svn_boolean_t have_row;
426
427 if (!repos_root_url && !repos_uuid)
428 return SVN_NO_ERROR;
429
430 if (repos_id == INVALID_REPOS_ID)
431 {
432 if (repos_root_url)
433 *repos_root_url = NULL;
434 if (repos_uuid)
435 *repos_uuid = NULL;
436 return SVN_NO_ERROR;
437 }
438
446 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
439 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
447 STMT_SELECT_REPOSITORY_BY_ID));
448 SVN_ERR(svn_sqlite__bindf(stmt, "i", repos_id));
449 SVN_ERR(svn_sqlite__step(&have_row, stmt));
450 if (!have_row)
451 return svn_error_createf(SVN_ERR_WC_CORRUPT, svn_sqlite__reset(stmt),
452 _("No REPOSITORY table entry for id '%ld'"),
453 (long int)repos_id);
454

--- 33 unchanged lines hidden (view full) ---

488 }
489 if (repos_relpath)
490 {
491 *repos_relpath = svn_sqlite__column_text(stmt, col_repos_relpath,
492 result_pool);
493 }
494}
495
440 STMT_SELECT_REPOSITORY_BY_ID));
441 SVN_ERR(svn_sqlite__bindf(stmt, "i", repos_id));
442 SVN_ERR(svn_sqlite__step(&have_row, stmt));
443 if (!have_row)
444 return svn_error_createf(SVN_ERR_WC_CORRUPT, svn_sqlite__reset(stmt),
445 _("No REPOSITORY table entry for id '%ld'"),
446 (long int)repos_id);
447

--- 33 unchanged lines hidden (view full) ---

481 }
482 if (repos_relpath)
483 {
484 *repos_relpath = svn_sqlite__column_text(stmt, col_repos_relpath,
485 result_pool);
486 }
487}
488
496
497/* Get the statement given by STMT_IDX, and bind the appropriate wc_id and
498 local_relpath based upon LOCAL_ABSPATH. Store it in *STMT, and use
499 SCRATCH_POOL for temporary allocations.
500
501 Note: WC_ID and LOCAL_RELPATH must be arguments 1 and 2 in the statement. */
502static svn_error_t *
503get_statement_for_path(svn_sqlite__stmt_t **stmt,
504 svn_wc__db_t *db,
505 const char *local_abspath,
506 int stmt_idx,
507 apr_pool_t *scratch_pool)
508{
509 svn_wc__db_wcroot_t *wcroot;
510 const char *local_relpath;
511
512 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
513
514 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
515 local_abspath, scratch_pool, scratch_pool));
516 VERIFY_USABLE_WCROOT(wcroot);
517
518 SVN_ERR(svn_sqlite__get_statement(stmt, wcroot->sdb, stmt_idx));
519 SVN_ERR(svn_sqlite__bindf(*stmt, "is", wcroot->wc_id, local_relpath));
520
521 return SVN_NO_ERROR;
522}
523
524
525/* For a given REPOS_ROOT_URL/REPOS_UUID pair, return the existing REPOS_ID
526 value. If one does not exist, then create a new one. */
527static svn_error_t *
528create_repos_id(apr_int64_t *repos_id,
529 const char *repos_root_url,
530 const char *repos_uuid,
531 svn_sqlite__db_t *sdb,
532 apr_pool_t *scratch_pool)

--- 37 unchanged lines hidden (view full) ---

570 memset(pibb, 0, sizeof(*pibb));
571 pibb->revision = SVN_INVALID_REVNUM;
572 pibb->changed_rev = SVN_INVALID_REVNUM;
573 pibb->depth = svn_depth_infinity;
574 pibb->repos_id = INVALID_REPOS_ID;
575}
576
577
489/* For a given REPOS_ROOT_URL/REPOS_UUID pair, return the existing REPOS_ID
490 value. If one does not exist, then create a new one. */
491static svn_error_t *
492create_repos_id(apr_int64_t *repos_id,
493 const char *repos_root_url,
494 const char *repos_uuid,
495 svn_sqlite__db_t *sdb,
496 apr_pool_t *scratch_pool)

--- 37 unchanged lines hidden (view full) ---

534 memset(pibb, 0, sizeof(*pibb));
535 pibb->revision = SVN_INVALID_REVNUM;
536 pibb->changed_rev = SVN_INVALID_REVNUM;
537 pibb->depth = svn_depth_infinity;
538 pibb->repos_id = INVALID_REPOS_ID;
539}
540
541
578svn_error_t *
579svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
580 const char *local_relpath,
581 svn_node_kind_t kind,
582 int op_depth,
583 apr_pool_t *scratch_pool)
542/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
543
544 ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm
545 discussing on dev@ whether we can let that be null for presence
546 == base-deleted. OP_DEPTH is the op-depth of what, and why?
547 It is used to select the lowest working node higher than OP_DEPTH,
548 so, in terms of the API, OP_DEPTH means ...?
549
550 Given a wc:
551
552 0 1 2 3 4
553 normal
554 A normal
555 A/B normal normal
556 A/B/C not-pres normal
557 A/B/C/D normal
558
559 That is checkout, delete A/B, copy a replacement A/B, delete copied
560 child A/B/C, add replacement A/B/C, add A/B/C/D.
561
562 Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
563 must extend the A/B deletion:
564
565 0 1 2 3 4
566 normal
567 A normal
568 A/B normal normal
569 A/B/C normal not-pres normal
570 A/B/C/D normal base-del normal
571 A/B/C/D/E normal base-del
572
573 When adding a node if the parent has a higher working node then the
574 parent node is deleted (or replaced) and the delete must be extended
575 to cover new node.
576
577 In the example above A/B/C/D and A/B/C/D/E are the nodes that get
578 the extended delete, A/B/C is already deleted.
579
580 If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
581 was recorded, otherwise to FALSE.
582 */
583static svn_error_t *
584db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
585 const char *local_relpath,
586 svn_node_kind_t kind,
587 int op_depth,
588 apr_pool_t *scratch_pool)
584{
585 svn_boolean_t have_row;
586 svn_sqlite__stmt_t *stmt;
587 int parent_op_depth;
588 const char *parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
589
590 SVN_ERR_ASSERT(local_relpath[0]);
591

--- 25 unchanged lines hidden (view full) ---

617 SVN_ERR(svn_sqlite__update(NULL, stmt));
618 }
619 }
620
621 return SVN_NO_ERROR;
622}
623
624
589{
590 svn_boolean_t have_row;
591 svn_sqlite__stmt_t *stmt;
592 int parent_op_depth;
593 const char *parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
594
595 SVN_ERR_ASSERT(local_relpath[0]);
596

--- 25 unchanged lines hidden (view full) ---

622 SVN_ERR(svn_sqlite__update(NULL, stmt));
623 }
624 }
625
626 return SVN_NO_ERROR;
627}
628
629
625/* This is the reverse of svn_wc__db_extend_parent_delete.
630/* This is the reverse of db_extend_parent_delete.
626
627 When removing a node if the parent has a higher working node then
628 the parent node and this node are both deleted or replaced and any
629 delete over this node must be removed.
630
631 This function (like most wcroot functions) assumes that its caller
632 only uses this function within an sqlite transaction if atomic
633 behavior is needed.
634 */
631
632 When removing a node if the parent has a higher working node then
633 the parent node and this node are both deleted or replaced and any
634 delete over this node must be removed.
635
636 This function (like most wcroot functions) assumes that its caller
637 only uses this function within an sqlite transaction if atomic
638 behavior is needed.
639 */
635svn_error_t *
636svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
637 const char *local_relpath,
638 int op_depth,
639 apr_pool_t *scratch_pool)
640static svn_error_t *
641db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
642 const char *local_relpath,
643 int op_depth,
644 apr_pool_t *scratch_pool)
640{
641 svn_sqlite__stmt_t *stmt;
642 svn_boolean_t have_row;
643 int working_depth;
644 svn_wc__db_status_t presence;
645 const char *moved_to;
646
647 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,

--- 172 unchanged lines hidden (view full) ---

820
821 SVN_ERR(svn_prop_diffs(&diffs, new_actual_props, base_props,
822 scratch_pool));
823
824 if (diffs->nelts == 0)
825 new_actual_props = NULL;
826 }
827
645{
646 svn_sqlite__stmt_t *stmt;
647 svn_boolean_t have_row;
648 int working_depth;
649 svn_wc__db_status_t presence;
650 const char *moved_to;
651
652 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,

--- 172 unchanged lines hidden (view full) ---

825
826 SVN_ERR(svn_prop_diffs(&diffs, new_actual_props, base_props,
827 scratch_pool));
828
829 if (diffs->nelts == 0)
830 new_actual_props = NULL;
831 }
832
828 SVN_ERR(set_actual_props(wcroot->wc_id, local_relpath, new_actual_props,
829 wcroot->sdb, scratch_pool));
833 SVN_ERR(set_actual_props(wcroot, local_relpath, new_actual_props,
834 scratch_pool));
830 }
831
832 if (pibb->kind == svn_node_dir && pibb->children)
833 SVN_ERR(insert_incomplete_children(wcroot->sdb, wcroot->wc_id,
834 local_relpath,
835 repos_id,
836 pibb->repos_relpath,
837 pibb->revision,

--- 4 unchanged lines hidden (view full) ---

842 /* When this is not the root node, check shadowing behavior */
843 if (*local_relpath)
844 {
845 if (parent_relpath
846 && ((pibb->status == svn_wc__db_status_normal)
847 || (pibb->status == svn_wc__db_status_incomplete))
848 && ! pibb->file_external)
849 {
835 }
836
837 if (pibb->kind == svn_node_dir && pibb->children)
838 SVN_ERR(insert_incomplete_children(wcroot->sdb, wcroot->wc_id,
839 local_relpath,
840 repos_id,
841 pibb->repos_relpath,
842 pibb->revision,

--- 4 unchanged lines hidden (view full) ---

847 /* When this is not the root node, check shadowing behavior */
848 if (*local_relpath)
849 {
850 if (parent_relpath
851 && ((pibb->status == svn_wc__db_status_normal)
852 || (pibb->status == svn_wc__db_status_incomplete))
853 && ! pibb->file_external)
854 {
850 SVN_ERR(svn_wc__db_extend_parent_delete(wcroot, local_relpath,
851 pibb->kind, 0,
852 scratch_pool));
855 SVN_ERR(db_extend_parent_delete(wcroot, local_relpath,
856 pibb->kind, 0,
857 scratch_pool));
853 }
854 else if (pibb->status == svn_wc__db_status_not_present
855 || pibb->status == svn_wc__db_status_server_excluded
856 || pibb->status == svn_wc__db_status_excluded)
857 {
858 }
859 else if (pibb->status == svn_wc__db_status_not_present
860 || pibb->status == svn_wc__db_status_server_excluded
861 || pibb->status == svn_wc__db_status_excluded)
862 {
858 SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
859 scratch_pool));
863 SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0,
864 scratch_pool));
860 }
861 }
862
863 if (pibb->delete_working)
864 {
865 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
866 STMT_DELETE_WORKING_NODE));
867 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));

--- 228 unchanged lines hidden (view full) ---

1096
1097 SVN_ERR(svn_prop_diffs(&diffs, new_actual_props, base_props,
1098 scratch_pool));
1099
1100 if (diffs->nelts == 0)
1101 new_actual_props = NULL;
1102 }
1103
865 }
866 }
867
868 if (pibb->delete_working)
869 {
870 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
871 STMT_DELETE_WORKING_NODE));
872 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));

--- 228 unchanged lines hidden (view full) ---

1101
1102 SVN_ERR(svn_prop_diffs(&diffs, new_actual_props, base_props,
1103 scratch_pool));
1104
1105 if (diffs->nelts == 0)
1106 new_actual_props = NULL;
1107 }
1108
1104 SVN_ERR(set_actual_props(wcroot->wc_id, local_relpath, new_actual_props,
1105 wcroot->sdb, scratch_pool));
1109 SVN_ERR(set_actual_props(wcroot, local_relpath, new_actual_props,
1110 scratch_pool));
1106 }
1107
1108 if (piwb->kind == svn_node_dir)
1109 {
1110 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
1111 STMT_UPDATE_ACTUAL_CLEAR_CHANGELIST));
1112 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
1113 SVN_ERR(svn_sqlite__step_done(stmt));

--- 29 unchanged lines hidden (view full) ---

1143 if (piwb->conflict)
1144 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
1145 piwb->conflict, scratch_pool));
1146
1147 return SVN_NO_ERROR;
1148}
1149
1150
1111 }
1112
1113 if (piwb->kind == svn_node_dir)
1114 {
1115 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
1116 STMT_UPDATE_ACTUAL_CLEAR_CHANGELIST));
1117 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
1118 SVN_ERR(svn_sqlite__step_done(stmt));

--- 29 unchanged lines hidden (view full) ---

1148 if (piwb->conflict)
1149 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
1150 piwb->conflict, scratch_pool));
1151
1152 return SVN_NO_ERROR;
1153}
1154
1155
1151/* Each name is allocated in RESULT_POOL and stored into CHILDREN as a key
1152 pointed to the same name. */
1153static svn_error_t *
1154add_children_to_hash(apr_hash_t *children,
1155 int stmt_idx,
1156 svn_sqlite__db_t *sdb,
1157 apr_int64_t wc_id,
1158 const char *parent_relpath,
1159 apr_pool_t *result_pool)
1160{
1161 svn_sqlite__stmt_t *stmt;
1162 svn_boolean_t have_row;
1163
1164 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, stmt_idx));
1165 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, parent_relpath));
1166 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1167 while (have_row)
1168 {
1169 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
1170 const char *name = svn_relpath_basename(child_relpath, result_pool);
1171
1172 svn_hash_sets(children, name, name);
1173
1174 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1175 }
1176
1177 return svn_sqlite__reset(stmt);
1178}
1179
1180
1181/* Set *CHILDREN to a new array of the (const char *) basenames of the
1182 immediate children, whatever their status, of the working node at
1183 LOCAL_RELPATH. */
1184static svn_error_t *
1185gather_children2(const apr_array_header_t **children,
1186 svn_wc__db_wcroot_t *wcroot,
1187 const char *local_relpath,
1188 apr_pool_t *result_pool,
1189 apr_pool_t *scratch_pool)
1190{
1191 apr_hash_t *names_hash = apr_hash_make(scratch_pool);
1192 apr_array_header_t *names_array;
1193
1194 /* All of the names get allocated in RESULT_POOL. It
1195 appears to be faster to use the hash to remove duplicates than to
1196 use DISTINCT in the SQL query. */
1197 SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_WORKING_CHILDREN,
1198 wcroot->sdb, wcroot->wc_id,
1199 local_relpath, result_pool));
1200
1201 SVN_ERR(svn_hash_keys(&names_array, names_hash, result_pool));
1202 *children = names_array;
1203 return SVN_NO_ERROR;
1204}
1205
1206/* Return in *CHILDREN all of the children of the directory LOCAL_RELPATH,
1207 of any status, in all op-depths in the NODES table. */
1208static svn_error_t *
1209gather_children(const apr_array_header_t **children,
1210 svn_wc__db_wcroot_t *wcroot,
1156/* Return in *CHILDREN all of the children of the directory LOCAL_RELPATH,
1157 of any status, in all op-depths in the NODES table. */
1158static svn_error_t *
1159gather_children(const apr_array_header_t **children,
1160 svn_wc__db_wcroot_t *wcroot,
1211 const char *local_relpath,
1161 const char *parent_relpath,
1162 int stmt_idx,
1163 int op_depth,
1212 apr_pool_t *result_pool,
1213 apr_pool_t *scratch_pool)
1214{
1164 apr_pool_t *result_pool,
1165 apr_pool_t *scratch_pool)
1166{
1215 apr_hash_t *names_hash = apr_hash_make(scratch_pool);
1216 apr_array_header_t *names_array;
1217
1218 /* All of the names get allocated in RESULT_POOL. It
1219 appears to be faster to use the hash to remove duplicates than to
1220 use DISTINCT in the SQL query. */
1221 SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_NODE_CHILDREN,
1222 wcroot->sdb, wcroot->wc_id,
1223 local_relpath, result_pool));
1224
1225 SVN_ERR(svn_hash_keys(&names_array, names_hash, result_pool));
1226 *children = names_array;
1227 return SVN_NO_ERROR;
1228}
1229
1230
1231/* Set *CHILDREN to a new array of (const char *) names of the children of
1232 the repository directory corresponding to WCROOT:LOCAL_RELPATH:OP_DEPTH -
1233 that is, only the children that are at the same op-depth as their parent. */
1234static svn_error_t *
1235gather_repo_children(const apr_array_header_t **children,
1236 svn_wc__db_wcroot_t *wcroot,
1237 const char *local_relpath,
1238 int op_depth,
1239 apr_pool_t *result_pool,
1240 apr_pool_t *scratch_pool)
1241{
1242 apr_array_header_t *result
1243 = apr_array_make(result_pool, 0, sizeof(const char *));
1167 apr_array_header_t *result;
1244 svn_sqlite__stmt_t *stmt;
1245 svn_boolean_t have_row;
1246
1168 svn_sqlite__stmt_t *stmt;
1169 svn_boolean_t have_row;
1170
1247 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
1248 STMT_SELECT_OP_DEPTH_CHILDREN));
1249 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
1250 op_depth));
1251 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1252 while (have_row)
1253 {
1254 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
1171 result = apr_array_make(result_pool, 16, sizeof(const char*));
1255
1172
1256 /* Allocate the name in RESULT_POOL so we won't have to copy it. */
1257 APR_ARRAY_PUSH(result, const char *)
1258 = svn_relpath_basename(child_relpath, result_pool);
1173 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_idx));
1174 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, parent_relpath));
1175 if (op_depth >= 0)
1176 SVN_ERR(svn_sqlite__bind_int(stmt, 3, op_depth));
1259
1177
1260 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1261 }
1262 SVN_ERR(svn_sqlite__reset(stmt));
1263
1264 *children = result;
1265 return SVN_NO_ERROR;
1266}
1267
1268svn_error_t *
1269svn_wc__db_get_children_op_depth(apr_hash_t **children,
1270 svn_wc__db_wcroot_t *wcroot,
1271 const char *local_relpath,
1272 int op_depth,
1273 apr_pool_t *result_pool,
1274 apr_pool_t *scratch_pool)
1275{
1276 svn_sqlite__stmt_t *stmt;
1277 svn_boolean_t have_row;
1278
1279 *children = apr_hash_make(result_pool);
1280
1281 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
1282 STMT_SELECT_OP_DEPTH_CHILDREN));
1283 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
1284 op_depth));
1285 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1286 while (have_row)
1287 {
1288 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
1178 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1179 while (have_row)
1180 {
1181 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
1289 svn_node_kind_t *child_kind = apr_palloc(result_pool, sizeof(svn_node_kind_t));
1182 const char *name = svn_relpath_basename(child_relpath, result_pool);
1290
1183
1291 *child_kind = svn_sqlite__column_token(stmt, 1, kind_map);
1292 svn_hash_sets(*children,
1293 svn_relpath_basename(child_relpath, result_pool),
1294 child_kind);
1184 APR_ARRAY_PUSH(result, const char *) = name;
1295
1296 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1297 }
1185
1186 SVN_ERR(svn_sqlite__step(&have_row, stmt));
1187 }
1298 SVN_ERR(svn_sqlite__reset(stmt));
1299
1188
1189 SVN_ERR(svn_sqlite__reset(stmt));
1190 *children = result;
1300 return SVN_NO_ERROR;
1301}
1302
1191 return SVN_NO_ERROR;
1192}
1193
1303
1304/* Return TRUE if CHILD_ABSPATH is an immediate child of PARENT_ABSPATH.
1305 * Else, return FALSE. */
1306static svn_boolean_t
1307is_immediate_child_path(const char *parent_abspath, const char *child_abspath)
1308{
1309 const char *local_relpath = svn_dirent_skip_ancestor(parent_abspath,
1310 child_abspath);
1311

--- 41 unchanged lines hidden (view full) ---

1353 {
1354 apr_hash_index_t *hi;
1355
1356 /* Flush access batons of children within the specified depth. */
1357 for (hi = apr_hash_first(scratch_pool, wcroot->access_cache);
1358 hi;
1359 hi = apr_hash_next(hi))
1360 {
1194/* Return TRUE if CHILD_ABSPATH is an immediate child of PARENT_ABSPATH.
1195 * Else, return FALSE. */
1196static svn_boolean_t
1197is_immediate_child_path(const char *parent_abspath, const char *child_abspath)
1198{
1199 const char *local_relpath = svn_dirent_skip_ancestor(parent_abspath,
1200 child_abspath);
1201

--- 41 unchanged lines hidden (view full) ---

1243 {
1244 apr_hash_index_t *hi;
1245
1246 /* Flush access batons of children within the specified depth. */
1247 for (hi = apr_hash_first(scratch_pool, wcroot->access_cache);
1248 hi;
1249 hi = apr_hash_next(hi))
1250 {
1361 const char *item_abspath = svn__apr_hash_index_key(hi);
1251 const char *item_abspath = apr_hash_this_key(hi);
1362
1363 if ((depth == svn_depth_files || depth == svn_depth_immediates) &&
1364 is_immediate_child_path(local_abspath, item_abspath))
1365 {
1366 remove_from_access_cache(wcroot->access_cache, item_abspath);
1367 }
1368 else if (depth == svn_depth_infinity &&
1369 svn_dirent_is_ancestor(local_abspath, item_abspath))

--- 110 unchanged lines hidden (view full) ---

1480 svn_sqlite__stmt_t *stmt;
1481
1482 /* Create the database's schema. */
1483 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA));
1484 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES));
1485 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS));
1486 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
1487
1252
1253 if ((depth == svn_depth_files || depth == svn_depth_immediates) &&
1254 is_immediate_child_path(local_abspath, item_abspath))
1255 {
1256 remove_from_access_cache(wcroot->access_cache, item_abspath);
1257 }
1258 else if (depth == svn_depth_infinity &&
1259 svn_dirent_is_ancestor(local_abspath, item_abspath))

--- 110 unchanged lines hidden (view full) ---

1370 svn_sqlite__stmt_t *stmt;
1371
1372 /* Create the database's schema. */
1373 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA));
1374 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES));
1375 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS));
1376 SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
1377
1378 SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
1379
1488 /* Insert the repository. */
1489 SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid,
1490 db, scratch_pool));
1491
1380 /* Insert the repository. */
1381 SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid,
1382 db, scratch_pool));
1383
1492 SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
1493
1494 /* Insert the wcroot. */
1495 /* ### Right now, this just assumes wc metadata is being stored locally. */
1496 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
1497 SVN_ERR(svn_sqlite__insert(wc_id, stmt));
1498
1499 if (root_node_repos_relpath)
1500 {
1501 svn_wc__db_status_t status = svn_wc__db_status_normal;
1502
1503 if (root_node_revision > 0)
1504 status = svn_wc__db_status_incomplete; /* Will be filled by update */
1505
1506 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_NODE));
1507 SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtst",
1508 *wc_id, /* 1 */
1509 "", /* 2 */
1510 0, /* op_depth is 0 for base */
1384 /* Insert the wcroot. */
1385 /* ### Right now, this just assumes wc metadata is being stored locally. */
1386 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
1387 SVN_ERR(svn_sqlite__insert(wc_id, stmt));
1388
1389 if (root_node_repos_relpath)
1390 {
1391 svn_wc__db_status_t status = svn_wc__db_status_normal;
1392
1393 if (root_node_revision > 0)
1394 status = svn_wc__db_status_incomplete; /* Will be filled by update */
1395
1396 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_NODE));
1397 SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtst",
1398 *wc_id, /* 1 */
1399 "", /* 2 */
1400 0, /* op_depth is 0 for base */
1511 NULL, /* 4 */
1401 SVN_VA_NULL, /* 4 */
1512 *repos_id,
1513 root_node_repos_relpath,
1514 root_node_revision,
1515 presence_map, status, /* 8 */
1516 svn_token__to_word(depth_map,
1517 root_node_depth),
1518 kind_map, svn_node_dir /* 10 */));
1519

--- 19 unchanged lines hidden (view full) ---

1539 const char *dir_abspath,
1540 const char *repos_root_url,
1541 const char *repos_uuid,
1542 const char *sdb_fname,
1543 const char *root_node_repos_relpath,
1544 svn_revnum_t root_node_revision,
1545 svn_depth_t root_node_depth,
1546 svn_boolean_t exclusive,
1402 *repos_id,
1403 root_node_repos_relpath,
1404 root_node_revision,
1405 presence_map, status, /* 8 */
1406 svn_token__to_word(depth_map,
1407 root_node_depth),
1408 kind_map, svn_node_dir /* 10 */));
1409

--- 19 unchanged lines hidden (view full) ---

1429 const char *dir_abspath,
1430 const char *repos_root_url,
1431 const char *repos_uuid,
1432 const char *sdb_fname,
1433 const char *root_node_repos_relpath,
1434 svn_revnum_t root_node_revision,
1435 svn_depth_t root_node_depth,
1436 svn_boolean_t exclusive,
1437 apr_int32_t timeout,
1547 apr_pool_t *result_pool,
1548 apr_pool_t *scratch_pool)
1549{
1550 SVN_ERR(svn_wc__db_util_open_db(sdb, dir_abspath, sdb_fname,
1551 svn_sqlite__mode_rwcreate, exclusive,
1438 apr_pool_t *result_pool,
1439 apr_pool_t *scratch_pool)
1440{
1441 SVN_ERR(svn_wc__db_util_open_db(sdb, dir_abspath, sdb_fname,
1442 svn_sqlite__mode_rwcreate, exclusive,
1443 timeout,
1552 NULL /* my_statements */,
1553 result_pool, scratch_pool));
1554
1555 SVN_SQLITE__WITH_LOCK(init_db(repos_id, wc_id,
1556 *sdb, repos_root_url, repos_uuid,
1557 root_node_repos_relpath, root_node_revision,
1558 root_node_depth, scratch_pool),
1559 *sdb);

--- 12 unchanged lines hidden (view full) ---

1572 svn_depth_t depth,
1573 apr_pool_t *scratch_pool)
1574{
1575 svn_sqlite__db_t *sdb;
1576 apr_int64_t repos_id;
1577 apr_int64_t wc_id;
1578 svn_wc__db_wcroot_t *wcroot;
1579 svn_boolean_t sqlite_exclusive = FALSE;
1444 NULL /* my_statements */,
1445 result_pool, scratch_pool));
1446
1447 SVN_SQLITE__WITH_LOCK(init_db(repos_id, wc_id,
1448 *sdb, repos_root_url, repos_uuid,
1449 root_node_repos_relpath, root_node_revision,
1450 root_node_depth, scratch_pool),
1451 *sdb);

--- 12 unchanged lines hidden (view full) ---

1464 svn_depth_t depth,
1465 apr_pool_t *scratch_pool)
1466{
1467 svn_sqlite__db_t *sdb;
1468 apr_int64_t repos_id;
1469 apr_int64_t wc_id;
1470 svn_wc__db_wcroot_t *wcroot;
1471 svn_boolean_t sqlite_exclusive = FALSE;
1472 apr_int32_t sqlite_timeout = 0; /* default timeout */
1473 apr_hash_index_t *hi;
1580
1581 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
1582 SVN_ERR_ASSERT(repos_relpath != NULL);
1583 SVN_ERR_ASSERT(depth == svn_depth_empty
1584 || depth == svn_depth_files
1585 || depth == svn_depth_immediates
1586 || depth == svn_depth_infinity);
1587
1588 /* ### REPOS_ROOT_URL and REPOS_UUID may be NULL. ... more doc: tbd */
1589
1474
1475 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
1476 SVN_ERR_ASSERT(repos_relpath != NULL);
1477 SVN_ERR_ASSERT(depth == svn_depth_empty
1478 || depth == svn_depth_files
1479 || depth == svn_depth_immediates
1480 || depth == svn_depth_infinity);
1481
1482 /* ### REPOS_ROOT_URL and REPOS_UUID may be NULL. ... more doc: tbd */
1483
1590 SVN_ERR(svn_config_get_bool((svn_config_t *)db->config, &sqlite_exclusive,
1484 SVN_ERR(svn_config_get_bool(db->config, &sqlite_exclusive,
1591 SVN_CONFIG_SECTION_WORKING_COPY,
1592 SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
1593 FALSE));
1594
1595 /* Create the SDB and insert the basic rows. */
1596 SVN_ERR(create_db(&sdb, &repos_id, &wc_id, local_abspath, repos_root_url,
1597 repos_uuid, SDB_FILE,
1598 repos_relpath, initial_rev, depth, sqlite_exclusive,
1485 SVN_CONFIG_SECTION_WORKING_COPY,
1486 SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
1487 FALSE));
1488
1489 /* Create the SDB and insert the basic rows. */
1490 SVN_ERR(create_db(&sdb, &repos_id, &wc_id, local_abspath, repos_root_url,
1491 repos_uuid, SDB_FILE,
1492 repos_relpath, initial_rev, depth, sqlite_exclusive,
1493 sqlite_timeout,
1599 db->state_pool, scratch_pool));
1600
1601 /* Create the WCROOT for this directory. */
1602 SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot,
1603 apr_pstrdup(db->state_pool, local_abspath),
1604 sdb, wc_id, FORMAT_FROM_SDB,
1605 FALSE /* auto-upgrade */,
1494 db->state_pool, scratch_pool));
1495
1496 /* Create the WCROOT for this directory. */
1497 SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot,
1498 apr_pstrdup(db->state_pool, local_abspath),
1499 sdb, wc_id, FORMAT_FROM_SDB,
1500 FALSE /* auto-upgrade */,
1606 FALSE /* enforce_empty_wq */,
1607 db->state_pool, scratch_pool));
1608
1501 db->state_pool, scratch_pool));
1502
1503 /* Any previously cached children may now have a new WCROOT, most likely that
1504 of the new WCROOT, but there might be descendant directories that are their
1505 own working copy, in which case setting WCROOT to our new WCROOT might
1506 actually break things for those.
1507
1508 Clearing is the safest thing we can do in this case, as a test would lead
1509 to unnecessary probing, while the standard code probes later anyway. So we
1510 only lose a bit of memory
1511
1512 ### Perhaps we could check wcroot->abspath to detect which case we have
1513 where, but currently it is already very hard to trigger this from
1514 the short living 'svn' client. (GUI clients like TortoiseSVN are far
1515 more likely to get in these cases)
1516 */
1517 for (hi = apr_hash_first(scratch_pool, db->dir_data);
1518 hi;
1519 hi = apr_hash_next(hi))
1520 {
1521 const char *abspath = apr_hash_this_key(hi);
1522 if (svn_dirent_is_ancestor(wcroot->abspath, abspath))
1523 svn_hash_sets(db->dir_data, abspath, NULL);
1524 }
1525
1609 /* The WCROOT is complete. Stash it into DB. */
1610 svn_hash_sets(db->dir_data, wcroot->abspath, wcroot);
1611
1612 return SVN_NO_ERROR;
1613}
1614
1615
1616svn_error_t *

--- 92 unchanged lines hidden (view full) ---

1709 svn_revnum_t revision,
1710 const apr_hash_t *props,
1711 svn_revnum_t changed_rev,
1712 apr_time_t changed_date,
1713 const char *changed_author,
1714 const apr_array_header_t *children,
1715 svn_depth_t depth,
1716 apr_hash_t *dav_cache,
1526 /* The WCROOT is complete. Stash it into DB. */
1527 svn_hash_sets(db->dir_data, wcroot->abspath, wcroot);
1528
1529 return SVN_NO_ERROR;
1530}
1531
1532
1533svn_error_t *

--- 92 unchanged lines hidden (view full) ---

1626 svn_revnum_t revision,
1627 const apr_hash_t *props,
1628 svn_revnum_t changed_rev,
1629 apr_time_t changed_date,
1630 const char *changed_author,
1631 const apr_array_header_t *children,
1632 svn_depth_t depth,
1633 apr_hash_t *dav_cache,
1717 const svn_skel_t *conflict,
1718 svn_boolean_t update_actual_props,
1719 apr_hash_t *new_actual_props,
1720 apr_array_header_t *new_iprops,
1634 svn_boolean_t update_actual_props,
1635 apr_hash_t *new_actual_props,
1636 apr_array_header_t *new_iprops,
1637 const svn_skel_t *conflict,
1721 const svn_skel_t *work_items,
1722 apr_pool_t *scratch_pool)
1723{
1724 svn_wc__db_wcroot_t *wcroot;
1725 const char *local_relpath;
1726 insert_base_baton_t ibb;
1727
1728 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

--- 392 unchanged lines hidden (view full) ---

2121 apr_pool_t *scratch_pool)
2122{
2123 return add_excluded_or_not_present_node(
2124 db, local_abspath, repos_relpath, repos_root_url, repos_uuid, revision,
2125 kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
2126}
2127
2128/* Recursively clear moved-here information at the copy-half of the move
1638 const svn_skel_t *work_items,
1639 apr_pool_t *scratch_pool)
1640{
1641 svn_wc__db_wcroot_t *wcroot;
1642 const char *local_relpath;
1643 insert_base_baton_t ibb;
1644
1645 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

--- 392 unchanged lines hidden (view full) ---

2038 apr_pool_t *scratch_pool)
2039{
2040 return add_excluded_or_not_present_node(
2041 db, local_abspath, repos_relpath, repos_root_url, repos_uuid, revision,
2042 kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
2043}
2044
2045/* Recursively clear moved-here information at the copy-half of the move
2129 * which moved the node at SRC_RELPATH away. This transforms the move into
2130 * a simple copy. */
2046 * which moved a node to MOVED_TO_RELPATH. This transforms this side of the
2047 * move into a simple copy.
2048 */
2131static svn_error_t *
2049static svn_error_t *
2132clear_moved_here(const char *src_relpath,
2133 svn_wc__db_wcroot_t *wcroot,
2050clear_moved_here(svn_wc__db_wcroot_t *wcroot,
2051 const char *moved_to_relpath,
2134 apr_pool_t *scratch_pool)
2135{
2136 svn_sqlite__stmt_t *stmt;
2052 apr_pool_t *scratch_pool)
2053{
2054 svn_sqlite__stmt_t *stmt;
2137 const char *dst_relpath;
2055 int affected_rows;
2138
2056
2139 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_MOVED_TO));
2140 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
2141 src_relpath, relpath_depth(src_relpath)));
2142 SVN_ERR(svn_sqlite__step_row(stmt));
2143 dst_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
2144 SVN_ERR(svn_sqlite__reset(stmt));
2145
2146 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2147 STMT_CLEAR_MOVED_HERE_RECURSIVE));
2057 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2058 STMT_CLEAR_MOVED_HERE_RECURSIVE));
2148 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
2149 dst_relpath, relpath_depth(dst_relpath)));
2150 SVN_ERR(svn_sqlite__step_done(stmt));
2059 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, moved_to_relpath,
2060 relpath_depth(moved_to_relpath)));
2151
2061
2062 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
2063
2064 if (affected_rows == 0)
2065 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
2066 _("The node '%s' was not found."),
2067 path_for_error_message(wcroot, moved_to_relpath,
2068 scratch_pool));
2069
2152 return SVN_NO_ERROR;
2153}
2154
2070 return SVN_NO_ERROR;
2071}
2072
2073svn_error_t *
2074svn_wc__db_op_break_move_internal(svn_wc__db_wcroot_t *wcroot,
2075 const char *src_relpath,
2076 int delete_op_depth,
2077 const char *dst_relpath,
2078 const svn_skel_t *work_items,
2079 apr_pool_t *scratch_pool)
2080{
2081 svn_sqlite__stmt_t *stmt;
2082 int affected;
2083
2084 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2085 STMT_CLEAR_MOVED_TO_RELPATH));
2086 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, src_relpath,
2087 delete_op_depth));
2088 SVN_ERR(svn_sqlite__update(&affected, stmt));
2089
2090 if (affected != 1)
2091 return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
2092 _("Path '%s' is not moved"),
2093 path_for_error_message(wcroot, src_relpath,
2094 scratch_pool));
2095
2096 SVN_ERR(clear_moved_here(wcroot, dst_relpath, scratch_pool));
2097
2098 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
2099 return SVN_NO_ERROR;
2100}
2101
2102
2155/* The body of svn_wc__db_base_remove().
2156 */
2157static svn_error_t *
2158db_base_remove(svn_wc__db_wcroot_t *wcroot,
2159 const char *local_relpath,
2160 svn_wc__db_t *db, /* For checking conflicts */
2161 svn_boolean_t keep_as_working,
2103/* The body of svn_wc__db_base_remove().
2104 */
2105static svn_error_t *
2106db_base_remove(svn_wc__db_wcroot_t *wcroot,
2107 const char *local_relpath,
2108 svn_wc__db_t *db, /* For checking conflicts */
2109 svn_boolean_t keep_as_working,
2162 svn_boolean_t queue_deletes,
2163 svn_boolean_t remove_locks,
2164 svn_revnum_t not_present_revision,
2110 svn_boolean_t mark_not_present,
2111 svn_boolean_t mark_excluded,
2112 svn_revnum_t marker_revision,
2165 svn_skel_t *conflict,
2166 svn_skel_t *work_items,
2167 apr_pool_t *scratch_pool)
2168{
2169 svn_sqlite__stmt_t *stmt;
2170 svn_boolean_t have_row;
2171 svn_wc__db_status_t status;
2113 svn_skel_t *conflict,
2114 svn_skel_t *work_items,
2115 apr_pool_t *scratch_pool)
2116{
2117 svn_sqlite__stmt_t *stmt;
2118 svn_boolean_t have_row;
2119 svn_wc__db_status_t status;
2120 svn_revnum_t revision;
2172 apr_int64_t repos_id;
2173 const char *repos_relpath;
2174 svn_node_kind_t kind;
2175 svn_boolean_t keep_working;
2121 apr_int64_t repos_id;
2122 const char *repos_relpath;
2123 svn_node_kind_t kind;
2124 svn_boolean_t keep_working;
2125 int op_depth;
2126 svn_node_kind_t wrk_kind;
2127 svn_boolean_t no_delete_wc = FALSE;
2128 svn_boolean_t file_external;
2176
2129
2177 SVN_ERR(svn_wc__db_base_get_info_internal(&status, &kind, NULL,
2130 SVN_ERR(svn_wc__db_base_get_info_internal(&status, &kind, &revision,
2178 &repos_relpath, &repos_id,
2179 NULL, NULL, NULL, NULL, NULL,
2131 &repos_relpath, &repos_id,
2132 NULL, NULL, NULL, NULL, NULL,
2180 NULL, NULL, NULL, NULL, NULL,
2133 NULL, NULL, NULL, NULL,
2134 &file_external,
2181 wcroot, local_relpath,
2182 scratch_pool, scratch_pool));
2183
2135 wcroot, local_relpath,
2136 scratch_pool, scratch_pool));
2137
2184 if (remove_locks)
2138 /* Check if there is already a working node */
2139 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2140 STMT_SELECT_NODE_INFO));
2141 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2142 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2143
2144 if (!have_row)
2145 return svn_error_trace(svn_sqlite__reset(stmt)); /* No BASE */
2146
2147 op_depth = svn_sqlite__column_int(stmt, 0);
2148 wrk_kind = svn_sqlite__column_token(stmt, 4, kind_map);
2149
2150 if (op_depth > 0
2151 && op_depth == relpath_depth(local_relpath))
2185 {
2152 {
2186 svn_sqlite__stmt_t *lock_stmt;
2153 svn_wc__db_status_t presence;
2154 presence = svn_sqlite__column_token(stmt, 3, presence_map);
2187
2155
2188 SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
2189 STMT_DELETE_LOCK_RECURSIVELY));
2190 SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
2191 SVN_ERR(svn_sqlite__step_done(lock_stmt));
2156 if (presence == svn_wc__db_status_base_deleted)
2157 {
2158 keep_working = FALSE;
2159 no_delete_wc = TRUE;
2160 }
2161 else
2162 {
2163 keep_working = TRUE;
2164 }
2192 }
2165 }
2166 else
2167 keep_working = FALSE;
2168 SVN_ERR(svn_sqlite__reset(stmt));
2193
2169
2194 if (status == svn_wc__db_status_normal
2195 && keep_as_working)
2170 if (keep_as_working && op_depth == 0)
2196 {
2171 {
2197 SVN_ERR(svn_wc__db_op_make_copy(db,
2198 svn_dirent_join(wcroot->abspath,
2199 local_relpath,
2200 scratch_pool),
2201 NULL, NULL,
2202 scratch_pool));
2172 if (status == svn_wc__db_status_normal
2173 || status == svn_wc__db_status_incomplete)
2174 {
2175 SVN_ERR(svn_wc__db_op_make_copy_internal(wcroot, local_relpath, TRUE,
2176 NULL, NULL,
2177 scratch_pool));
2178 }
2203 keep_working = TRUE;
2204 }
2179 keep_working = TRUE;
2180 }
2205 else
2206 {
2207 /* Check if there is already a working node */
2208 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2209 STMT_SELECT_WORKING_NODE));
2210 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2211 SVN_ERR(svn_sqlite__step(&keep_working, stmt));
2212 SVN_ERR(svn_sqlite__reset(stmt));
2213 }
2214
2215 /* Step 1: Create workqueue operations to remove files and dirs in the
2216 local-wc */
2181
2182 /* Step 1: Create workqueue operations to remove files and dirs in the
2183 local-wc */
2217 if (!keep_working
2218 && queue_deletes
2219 && (status == svn_wc__db_status_normal
2220 || status == svn_wc__db_status_incomplete))
2184 if (!keep_working && !no_delete_wc)
2221 {
2222 svn_skel_t *work_item;
2223 const char *local_abspath;
2224
2225 local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
2226 scratch_pool);
2185 {
2186 svn_skel_t *work_item;
2187 const char *local_abspath;
2188
2189 local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
2190 scratch_pool);
2227 if (kind == svn_node_dir)
2191 if (wrk_kind == svn_node_dir)
2228 {
2229 apr_pool_t *iterpool;
2230 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2192 {
2193 apr_pool_t *iterpool;
2194 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2231 STMT_SELECT_BASE_PRESENT));
2195 STMT_SELECT_WORKING_PRESENT));
2232 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2233
2234 iterpool = svn_pool_create(scratch_pool);
2235
2236 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2237
2238 while (have_row)
2239 {

--- 62 unchanged lines hidden (view full) ---

2302 STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE));
2303 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2304 SVN_ERR(svn_sqlite__step_done(stmt));
2305 }
2306 /* Else: Everything has been turned into a copy, so we want to keep all
2307 ACTUAL_NODE records */
2308
2309 /* Step 3: Delete WORKING nodes */
2196 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2197
2198 iterpool = svn_pool_create(scratch_pool);
2199
2200 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2201
2202 while (have_row)
2203 {

--- 62 unchanged lines hidden (view full) ---

2266 STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE));
2267 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2268 SVN_ERR(svn_sqlite__step_done(stmt));
2269 }
2270 /* Else: Everything has been turned into a copy, so we want to keep all
2271 ACTUAL_NODE records */
2272
2273 /* Step 3: Delete WORKING nodes */
2310 if (conflict)
2274 if (!keep_working)
2311 {
2312 apr_pool_t *iterpool;
2313
2275 {
2276 apr_pool_t *iterpool;
2277
2314 /*
2315 * When deleting a conflicted node, moves of any moved-outside children
2316 * of the node must be broken. Else, the destination will still be marked
2317 * moved-here after the move source disappears from the working copy.
2318 *
2319 * ### FIXME: It would be nicer to have the conflict resolver
2320 * break the move instead. It might also be a good idea to
2321 * flag a tree conflict on each moved-away child. But doing so
2322 * might introduce actual-only nodes without direct parents,
2323 * and we're not yet sure if other existing code is prepared
2324 * to handle such nodes. To be revisited post-1.8.
2325 *
2326 * ### In case of a conflict we are most likely creating WORKING nodes
2327 * describing a copy of what was in BASE. The move information
2328 * should be updated to describe a move from the WORKING layer.
2329 * When stored that way the resolver of the tree conflict still has
2330 * the knowledge of what was moved.
2278 /* When deleting everything in working we should break moves from
2279 here and to here.
2331 */
2332 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2333 STMT_SELECT_MOVED_OUTSIDE));
2334 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
2335 local_relpath,
2336 relpath_depth(local_relpath)));
2337 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2338 iterpool = svn_pool_create(scratch_pool);
2339 while (have_row)
2340 {
2280 */
2281 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2282 STMT_SELECT_MOVED_OUTSIDE));
2283 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
2284 local_relpath,
2285 relpath_depth(local_relpath)));
2286 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2287 iterpool = svn_pool_create(scratch_pool);
2288 while (have_row)
2289 {
2341 const char *child_relpath;
2290 const char *moved_to_relpath;
2342 svn_error_t *err;
2343
2344 svn_pool_clear(iterpool);
2291 svn_error_t *err;
2292
2293 svn_pool_clear(iterpool);
2345 child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
2346 err = clear_moved_here(child_relpath, wcroot, iterpool);
2294 moved_to_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
2295 err = clear_moved_here(wcroot, moved_to_relpath, iterpool);
2347 if (err)
2348 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
2349 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2350 }
2351 svn_pool_destroy(iterpool);
2352 SVN_ERR(svn_sqlite__reset(stmt));
2353 }
2296 if (err)
2297 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
2298 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2299 }
2300 svn_pool_destroy(iterpool);
2301 SVN_ERR(svn_sqlite__reset(stmt));
2302 }
2354 if (keep_working)
2303 else
2355 {
2304 {
2305 /* We are keeping things that are in WORKING, but we should still
2306 break moves of things in BASE. (Mixed revisions make it
2307 impossible to guarantee that we can keep everything moved) */
2308
2309 apr_pool_t *iterpool;
2310
2356 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2311 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2357 STMT_DELETE_WORKING_BASE_DELETE));
2358 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2312 STMT_SELECT_MOVED_DESCENDANTS_SRC));
2313 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
2314 local_relpath, 0));
2315 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2316 iterpool = svn_pool_create(scratch_pool);
2317 while (have_row)
2318 {
2319 int delete_op_depth = svn_sqlite__column_int(stmt, 0);
2320 const char *src_relpath;
2321 const char *dst_relpath;
2322 svn_error_t *err;
2323
2324 svn_pool_clear(iterpool);
2325
2326 src_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
2327 dst_relpath = svn_sqlite__column_text(stmt, 4, iterpool);
2328
2329 err = svn_wc__db_op_break_move_internal(wcroot, src_relpath,
2330 delete_op_depth,
2331 dst_relpath,
2332 NULL,
2333 iterpool);
2334
2335 if (err)
2336 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
2337
2338 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2339 }
2340 svn_pool_destroy(iterpool);
2341 SVN_ERR(svn_sqlite__reset(stmt));
2342 }
2343 if (keep_working)
2344 {
2345 SVN_ERR(svn_sqlite__get_statement(
2346 &stmt, wcroot->sdb,
2347 STMT_DELETE_WORKING_BASE_DELETE_RECURSIVE));
2348 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath, 0));
2359 SVN_ERR(svn_sqlite__step_done(stmt));
2360 }
2361 else
2362 {
2363 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2364 STMT_DELETE_WORKING_RECURSIVE));
2365 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2366 SVN_ERR(svn_sqlite__step_done(stmt));
2367 }
2368
2369 /* Step 4: Delete the BASE node descendants */
2370 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2371 STMT_DELETE_BASE_RECURSIVE));
2372 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2373 SVN_ERR(svn_sqlite__step_done(stmt));
2374
2349 SVN_ERR(svn_sqlite__step_done(stmt));
2350 }
2351 else
2352 {
2353 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2354 STMT_DELETE_WORKING_RECURSIVE));
2355 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2356 SVN_ERR(svn_sqlite__step_done(stmt));
2357 }
2358
2359 /* Step 4: Delete the BASE node descendants */
2360 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2361 STMT_DELETE_BASE_RECURSIVE));
2362 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2363 SVN_ERR(svn_sqlite__step_done(stmt));
2364
2375 /* Step 5: handle the BASE node itself */
2376 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2377 STMT_DELETE_BASE_NODE));
2378 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2379 SVN_ERR(svn_sqlite__step_done(stmt));
2365 SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0, scratch_pool));
2380
2366
2381 SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
2382 scratch_pool));
2383
2384 /* Step 6: Delete actual node if we don't keep working */
2385 if (! keep_working)
2367 if (mark_not_present || mark_excluded)
2386 {
2368 {
2387 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2388 STMT_DELETE_ACTUAL_NODE));
2389 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2390 SVN_ERR(svn_sqlite__step_done(stmt));
2391 }
2392
2393 if (SVN_IS_VALID_REVNUM(not_present_revision))
2394 {
2395 struct insert_base_baton_t ibb;
2369 struct insert_base_baton_t ibb;
2396 blank_ibb(&ibb);
2370 svn_boolean_t no_marker = FALSE;
2397
2371
2398 ibb.repos_id = repos_id;
2399 ibb.status = svn_wc__db_status_not_present;
2400 ibb.kind = kind;
2401 ibb.repos_relpath = repos_relpath;
2402 ibb.revision = not_present_revision;
2372 if (file_external)
2373 {
2374 const char *parent_local_relpath;
2375 const char *name;
2376 svn_error_t *err;
2403
2377
2404 /* Depending upon KIND, any of these might get used. */
2405 ibb.children = NULL;
2406 ibb.depth = svn_depth_unknown;
2407 ibb.checksum = NULL;
2408 ibb.target = NULL;
2378 /* For file externals we only want to place a not present marker
2379 if there is a BASE parent */
2380
2381 svn_relpath_split(&parent_local_relpath, &name, local_relpath,
2382 scratch_pool);
2409
2383
2410 SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
2384 err = svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
2385 &repos_relpath, &repos_id,
2386 NULL, NULL, NULL, NULL, NULL,
2387 NULL, NULL, NULL, NULL, NULL,
2388 wcroot, parent_local_relpath,
2389 scratch_pool, scratch_pool);
2390
2391 if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
2392 return svn_error_trace(err);
2393 else if (err)
2394 {
2395 svn_error_clear(err);
2396 no_marker = TRUE;
2397 }
2398 else
2399 {
2400 /* Replace the repos_relpath with something more expected than
2401 the unrelated old file external repository relpath, which
2402 one day may come from a different repository */
2403 repos_relpath = svn_relpath_join(repos_relpath, name, scratch_pool);
2404 }
2405 }
2406
2407 if (!no_marker)
2408 {
2409 blank_ibb(&ibb);
2410
2411 ibb.repos_id = repos_id;
2412 ibb.status = mark_excluded ? svn_wc__db_status_excluded
2413 : svn_wc__db_status_not_present;
2414 ibb.kind = kind;
2415 ibb.repos_relpath = repos_relpath;
2416 ibb.revision = SVN_IS_VALID_REVNUM(marker_revision)
2417 ? marker_revision
2418 : revision;
2419
2420 /* Depending upon KIND, any of these might get used. */
2421 ibb.children = NULL;
2422 ibb.depth = svn_depth_unknown;
2423 ibb.checksum = NULL;
2424 ibb.target = NULL;
2425
2426 SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
2427 }
2411 }
2412
2413 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
2414 if (conflict)
2415 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
2416 conflict, scratch_pool));
2417
2418 return SVN_NO_ERROR;
2419}
2420
2421
2422svn_error_t *
2423svn_wc__db_base_remove(svn_wc__db_t *db,
2424 const char *local_abspath,
2425 svn_boolean_t keep_as_working,
2428 }
2429
2430 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
2431 if (conflict)
2432 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
2433 conflict, scratch_pool));
2434
2435 return SVN_NO_ERROR;
2436}
2437
2438
2439svn_error_t *
2440svn_wc__db_base_remove(svn_wc__db_t *db,
2441 const char *local_abspath,
2442 svn_boolean_t keep_as_working,
2426 svn_boolean_t queue_deletes,
2427 svn_boolean_t remove_locks,
2428 svn_revnum_t not_present_revision,
2443 svn_boolean_t mark_not_present,
2444 svn_boolean_t mark_excluded,
2445 svn_revnum_t marker_revision,
2429 svn_skel_t *conflict,
2430 svn_skel_t *work_items,
2431 apr_pool_t *scratch_pool)
2432{
2433 svn_wc__db_wcroot_t *wcroot;
2434 const char *local_relpath;
2435
2436 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2437
2438 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2439 local_abspath, scratch_pool, scratch_pool));
2440 VERIFY_USABLE_WCROOT(wcroot);
2441
2442 SVN_WC__DB_WITH_TXN(db_base_remove(wcroot, local_relpath,
2446 svn_skel_t *conflict,
2447 svn_skel_t *work_items,
2448 apr_pool_t *scratch_pool)
2449{
2450 svn_wc__db_wcroot_t *wcroot;
2451 const char *local_relpath;
2452
2453 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2454
2455 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2456 local_abspath, scratch_pool, scratch_pool));
2457 VERIFY_USABLE_WCROOT(wcroot);
2458
2459 SVN_WC__DB_WITH_TXN(db_base_remove(wcroot, local_relpath,
2443 db, keep_as_working, queue_deletes,
2444 remove_locks, not_present_revision,
2460 db, keep_as_working,
2461 mark_not_present, mark_excluded,
2462 marker_revision,
2445 conflict, work_items, scratch_pool),
2446 wcroot);
2447
2448 /* If this used to be a directory we should remove children so pass
2449 * depth infinity. */
2450 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
2451 scratch_pool));
2452

--- 180 unchanged lines hidden (view full) ---

2633 repos_relpath, &repos_id,
2634 changed_rev, changed_date,
2635 changed_author, depth,
2636 checksum, target, lock,
2637 had_props, props, update_root,
2638 wcroot, local_relpath,
2639 result_pool, scratch_pool),
2640 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
2463 conflict, work_items, scratch_pool),
2464 wcroot);
2465
2466 /* If this used to be a directory we should remove children so pass
2467 * depth infinity. */
2468 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
2469 scratch_pool));
2470

--- 180 unchanged lines hidden (view full) ---

2651 repos_relpath, &repos_id,
2652 changed_rev, changed_date,
2653 changed_author, depth,
2654 checksum, target, lock,
2655 had_props, props, update_root,
2656 wcroot, local_relpath,
2657 result_pool, scratch_pool),
2658 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
2641 wcroot->sdb, repos_id, result_pool),
2659 wcroot, repos_id, result_pool),
2642 SVN_NO_ERROR,
2643 SVN_NO_ERROR,
2644 wcroot);
2645 SVN_ERR_ASSERT(repos_id != INVALID_REPOS_ID);
2646
2647 return SVN_NO_ERROR;
2648}
2649
2660 SVN_NO_ERROR,
2661 SVN_NO_ERROR,
2662 wcroot);
2663 SVN_ERR_ASSERT(repos_id != INVALID_REPOS_ID);
2664
2665 return SVN_NO_ERROR;
2666}
2667
2650svn_error_t *
2651svn_wc__db_base_get_children_info(apr_hash_t **nodes,
2652 svn_wc__db_t *db,
2653 const char *dir_abspath,
2654 apr_pool_t *result_pool,
2655 apr_pool_t *scratch_pool)
2668/* The implementation of svn_wc__db_base_get_children_info */
2669static svn_error_t *
2670base_get_children_info(apr_hash_t **nodes,
2671 svn_wc__db_wcroot_t *wcroot,
2672 const char *local_relpath,
2673 svn_boolean_t obtain_locks,
2674 apr_pool_t *result_pool,
2675 apr_pool_t *scratch_pool)
2656{
2676{
2657 svn_wc__db_wcroot_t *wcroot;
2658 const char *local_relpath;
2659 svn_sqlite__stmt_t *stmt;
2660 svn_boolean_t have_row;
2677 svn_sqlite__stmt_t *stmt;
2678 svn_boolean_t have_row;
2679 apr_int64_t last_repos_id = INVALID_REPOS_ID;
2680 const char *last_repos_root_url = NULL;
2661
2681
2662 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
2663
2664 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2665 dir_abspath, scratch_pool, scratch_pool));
2666 VERIFY_USABLE_WCROOT(wcroot);
2667
2668 *nodes = apr_hash_make(result_pool);
2669
2670 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2682 *nodes = apr_hash_make(result_pool);
2683
2684 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2671 STMT_SELECT_BASE_CHILDREN_INFO));
2685 obtain_locks
2686 ? STMT_SELECT_BASE_CHILDREN_INFO_LOCK
2687 : STMT_SELECT_BASE_CHILDREN_INFO));
2672 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2673
2674 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2675
2676 while (have_row)
2677 {
2678 struct svn_wc__db_base_info_t *info;
2688 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2689
2690 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2691
2692 while (have_row)
2693 {
2694 struct svn_wc__db_base_info_t *info;
2679 svn_error_t *err;
2680 apr_int64_t repos_id;
2681 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
2682 const char *name = svn_relpath_basename(child_relpath, result_pool);
2683
2684 info = apr_pcalloc(result_pool, sizeof(*info));
2685
2686 repos_id = svn_sqlite__column_int64(stmt, 1);
2687 info->repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
2688 info->status = svn_sqlite__column_token(stmt, 3, presence_map);
2689 info->kind = svn_sqlite__column_token(stmt, 4, kind_map);
2690 info->revnum = svn_sqlite__column_revnum(stmt, 5);
2691
2692 info->depth = svn_sqlite__column_token_null(stmt, 6, depth_map,
2693 svn_depth_unknown);
2694
2695 info->update_root = svn_sqlite__column_boolean(stmt, 7);
2696
2695 apr_int64_t repos_id;
2696 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
2697 const char *name = svn_relpath_basename(child_relpath, result_pool);
2698
2699 info = apr_pcalloc(result_pool, sizeof(*info));
2700
2701 repos_id = svn_sqlite__column_int64(stmt, 1);
2702 info->repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
2703 info->status = svn_sqlite__column_token(stmt, 3, presence_map);
2704 info->kind = svn_sqlite__column_token(stmt, 4, kind_map);
2705 info->revnum = svn_sqlite__column_revnum(stmt, 5);
2706
2707 info->depth = svn_sqlite__column_token_null(stmt, 6, depth_map,
2708 svn_depth_unknown);
2709
2710 info->update_root = svn_sqlite__column_boolean(stmt, 7);
2711
2697 info->lock = lock_from_columns(stmt, 8, 9, 10, 11, result_pool);
2712 if (obtain_locks)
2713 info->lock = lock_from_columns(stmt, 8, 9, 10, 11, result_pool);
2698
2714
2699 err = svn_wc__db_fetch_repos_info(&info->repos_root_url, NULL,
2700 wcroot->sdb, repos_id, result_pool);
2715 if (repos_id != last_repos_id)
2716 {
2717 svn_error_t *err;
2701
2718
2702 if (err)
2703 return svn_error_trace(
2704 svn_error_compose_create(err,
2705 svn_sqlite__reset(stmt)));
2719 err = svn_wc__db_fetch_repos_info(&last_repos_root_url, NULL,
2720 wcroot, repos_id,
2721 result_pool);
2706
2722
2723 if (err)
2724 return svn_error_trace(
2725 svn_error_compose_create(err,
2726 svn_sqlite__reset(stmt)));
2707
2727
2728 last_repos_id = repos_id;
2729 }
2730
2731 info->repos_root_url = last_repos_root_url;
2732
2708 svn_hash_sets(*nodes, name, info);
2709
2710 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2711 }
2712
2713 SVN_ERR(svn_sqlite__reset(stmt));
2714
2715 return SVN_NO_ERROR;
2716}
2717
2733 svn_hash_sets(*nodes, name, info);
2734
2735 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2736 }
2737
2738 SVN_ERR(svn_sqlite__reset(stmt));
2739
2740 return SVN_NO_ERROR;
2741}
2742
2743svn_error_t *
2744svn_wc__db_base_get_children_info(apr_hash_t **nodes,
2745 svn_wc__db_t *db,
2746 const char *dir_abspath,
2747 apr_pool_t *result_pool,
2748 apr_pool_t *scratch_pool)
2749{
2750 svn_wc__db_wcroot_t *wcroot;
2751 const char *local_relpath;
2718
2752
2753 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
2754
2755 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2756 dir_abspath, scratch_pool, scratch_pool));
2757 VERIFY_USABLE_WCROOT(wcroot);
2758
2759 return svn_error_trace(base_get_children_info(nodes,
2760 wcroot,
2761 local_relpath,
2762 TRUE /* obtain_locks */,
2763 result_pool,
2764 scratch_pool));
2765}
2766
2767
2719svn_error_t *
2720svn_wc__db_base_get_props(apr_hash_t **props,
2721 svn_wc__db_t *db,
2722 const char *local_abspath,
2723 apr_pool_t *result_pool,
2724 apr_pool_t *scratch_pool)
2725{
2726 svn_wc__db_status_t presence;

--- 29 unchanged lines hidden (view full) ---

2756
2757 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2758
2759 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2760 local_abspath,
2761 scratch_pool, scratch_pool));
2762 VERIFY_USABLE_WCROOT(wcroot);
2763
2768svn_error_t *
2769svn_wc__db_base_get_props(apr_hash_t **props,
2770 svn_wc__db_t *db,
2771 const char *local_abspath,
2772 apr_pool_t *result_pool,
2773 apr_pool_t *scratch_pool)
2774{
2775 svn_wc__db_status_t presence;

--- 29 unchanged lines hidden (view full) ---

2805
2806 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2807
2808 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2809 local_abspath,
2810 scratch_pool, scratch_pool));
2811 VERIFY_USABLE_WCROOT(wcroot);
2812
2764 return gather_repo_children(children, wcroot, local_relpath, 0,
2765 result_pool, scratch_pool);
2813 return svn_error_trace(
2814 gather_children(children, wcroot, local_relpath,
2815 STMT_SELECT_OP_DEPTH_CHILDREN, 0,
2816 result_pool, scratch_pool));
2766}
2767
2768
2769svn_error_t *
2770svn_wc__db_base_set_dav_cache(svn_wc__db_t *db,
2771 const char *local_abspath,
2772 const apr_hash_t *props,
2773 apr_pool_t *scratch_pool)
2774{
2817}
2818
2819
2820svn_error_t *
2821svn_wc__db_base_set_dav_cache(svn_wc__db_t *db,
2822 const char *local_abspath,
2823 const apr_hash_t *props,
2824 apr_pool_t *scratch_pool)
2825{
2826 svn_wc__db_wcroot_t *wcroot;
2827 const char *local_relpath;
2775 svn_sqlite__stmt_t *stmt;
2776 int affected_rows;
2777
2828 svn_sqlite__stmt_t *stmt;
2829 int affected_rows;
2830
2778 SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
2779 STMT_UPDATE_BASE_NODE_DAV_CACHE,
2780 scratch_pool));
2831 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2832
2833 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2834 local_abspath, scratch_pool, scratch_pool));
2835 VERIFY_USABLE_WCROOT(wcroot);
2836
2837 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2838 STMT_UPDATE_BASE_NODE_DAV_CACHE));
2839 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
2781 SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
2782
2783 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
2784
2785 if (affected_rows != 1)
2786 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
2787 _("The node '%s' was not found."),
2788 svn_dirent_local_style(local_abspath,

--- 5 unchanged lines hidden (view full) ---

2794
2795svn_error_t *
2796svn_wc__db_base_get_dav_cache(apr_hash_t **props,
2797 svn_wc__db_t *db,
2798 const char *local_abspath,
2799 apr_pool_t *result_pool,
2800 apr_pool_t *scratch_pool)
2801{
2840 SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
2841
2842 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
2843
2844 if (affected_rows != 1)
2845 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
2846 _("The node '%s' was not found."),
2847 svn_dirent_local_style(local_abspath,

--- 5 unchanged lines hidden (view full) ---

2853
2854svn_error_t *
2855svn_wc__db_base_get_dav_cache(apr_hash_t **props,
2856 svn_wc__db_t *db,
2857 const char *local_abspath,
2858 apr_pool_t *result_pool,
2859 apr_pool_t *scratch_pool)
2860{
2861 svn_wc__db_wcroot_t *wcroot;
2862 const char *local_relpath;
2802 svn_sqlite__stmt_t *stmt;
2803 svn_boolean_t have_row;
2804
2863 svn_sqlite__stmt_t *stmt;
2864 svn_boolean_t have_row;
2865
2805 SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
2806 STMT_SELECT_BASE_DAV_CACHE, scratch_pool));
2866 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
2867
2868 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
2869 local_abspath, scratch_pool, scratch_pool));
2870 VERIFY_USABLE_WCROOT(wcroot);
2871
2872 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
2873 STMT_SELECT_BASE_DAV_CACHE));
2874
2807 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2808 if (!have_row)
2809 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
2810 svn_sqlite__reset(stmt),
2811 _("The node '%s' was not found."),
2812 svn_dirent_local_style(local_abspath,
2813 scratch_pool));
2814

--- 124 unchanged lines hidden (view full) ---

2939 {
2940 if (node_kind != svn_node_symlink)
2941 *target = NULL;
2942 else
2943 *target = svn_sqlite__column_text(stmt, 11, result_pool);
2944 }
2945 if (had_props)
2946 {
2875 SVN_ERR(svn_sqlite__step(&have_row, stmt));
2876 if (!have_row)
2877 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
2878 svn_sqlite__reset(stmt),
2879 _("The node '%s' was not found."),
2880 svn_dirent_local_style(local_abspath,
2881 scratch_pool));
2882

--- 124 unchanged lines hidden (view full) ---

3007 {
3008 if (node_kind != svn_node_symlink)
3009 *target = NULL;
3010 else
3011 *target = svn_sqlite__column_text(stmt, 11, result_pool);
3012 }
3013 if (had_props)
3014 {
2947 *had_props = SQLITE_PROPERTIES_AVAILABLE(stmt, 13);
3015 *had_props = SQLITE_PROPERTIES_AVAILABLE(stmt, 12);
2948 }
2949 if (props)
2950 {
2951 if (node_status == svn_wc__db_status_normal
2952 || node_status == svn_wc__db_status_incomplete)
2953 {
3016 }
3017 if (props)
3018 {
3019 if (node_status == svn_wc__db_status_normal
3020 || node_status == svn_wc__db_status_incomplete)
3021 {
2954 SVN_ERR(svn_sqlite__column_properties(props, stmt, 13,
3022 SVN_ERR(svn_sqlite__column_properties(props, stmt, 12,
2955 result_pool, scratch_pool));
2956 if (*props == NULL)
2957 *props = apr_hash_make(result_pool);
2958 }
2959 else
2960 {
3023 result_pool, scratch_pool));
3024 if (*props == NULL)
3025 *props = apr_hash_make(result_pool);
3026 }
3027 else
3028 {
2961 assert(svn_sqlite__column_is_null(stmt, 13));
3029 assert(svn_sqlite__column_is_null(stmt, 12));
2962 *props = NULL;
2963 }
2964 }
2965 }
2966 else
2967 {
2968 err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
2969 _("The node '%s' was not found."),
2970 path_for_error_message(wcroot, local_relpath,
2971 scratch_pool));
2972 }
2973
2974 /* Note: given the composition, no need to wrap for tracing. */
2975 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
2976}
2977
3030 *props = NULL;
3031 }
3032 }
3033 }
3034 else
3035 {
3036 err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
3037 _("The node '%s' was not found."),
3038 path_for_error_message(wcroot, local_relpath,
3039 scratch_pool));
3040 }
3041
3042 /* Note: given the composition, no need to wrap for tracing. */
3043 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
3044}
3045
3046/* A callback which supplies WCROOTs and LOCAL_RELPATHs. */
3047typedef svn_error_t *(*svn_wc__db_txn_callback_t)(void *baton,
3048 svn_wc__db_wcroot_t *wcroot,
3049 const char *local_relpath,
3050 apr_pool_t *scratch_pool);
2978
2979/* Baton for passing args to with_triggers(). */
2980struct with_triggers_baton_t {
2981 int create_trigger;
2982 int drop_trigger;
2983 svn_wc__db_txn_callback_t cb_func;
2984 void *cb_baton;
2985};

--- 60 unchanged lines hidden (view full) ---

3046 svn_wc_notify_func2_t notify_func,
3047 void *notify_baton,
3048 int finalize_stmt_idx,
3049 apr_pool_t *scratch_pool)
3050{
3051 svn_error_t *err1;
3052 svn_error_t *err2;
3053
3051
3052/* Baton for passing args to with_triggers(). */
3053struct with_triggers_baton_t {
3054 int create_trigger;
3055 int drop_trigger;
3056 svn_wc__db_txn_callback_t cb_func;
3057 void *cb_baton;
3058};

--- 60 unchanged lines hidden (view full) ---

3119 svn_wc_notify_func2_t notify_func,
3120 void *notify_baton,
3121 int finalize_stmt_idx,
3122 apr_pool_t *scratch_pool)
3123{
3124 svn_error_t *err1;
3125 svn_error_t *err2;
3126
3054 err1 = svn_wc__db_with_txn(wcroot, local_relpath, txn_cb, txn_baton,
3055 scratch_pool);
3127 err1 = svn_sqlite__begin_savepoint(wcroot->sdb);
3128 if (!err1)
3129 {
3130 err1 = txn_cb(txn_baton, wcroot, local_relpath, scratch_pool);
3056
3131
3132 err1 = svn_sqlite__finish_savepoint(wcroot->sdb, err1);
3133 }
3134
3057 if (err1 == NULL && notify_func != NULL)
3058 {
3059 err2 = work_cb(work_baton, wcroot,
3060 cancel_func, cancel_baton,
3061 notify_func, notify_baton,
3062 scratch_pool);
3063 err1 = svn_error_compose_create(err1, err2);
3064 }

--- 368 unchanged lines hidden (view full) ---

3433/* The body of svn_wc__db_external_remove(). */
3434static svn_error_t *
3435db_external_remove(const svn_skel_t *work_items,
3436 svn_wc__db_wcroot_t *wcroot,
3437 const char *local_relpath,
3438 apr_pool_t *scratch_pool)
3439{
3440 svn_sqlite__stmt_t *stmt;
3135 if (err1 == NULL && notify_func != NULL)
3136 {
3137 err2 = work_cb(work_baton, wcroot,
3138 cancel_func, cancel_baton,
3139 notify_func, notify_baton,
3140 scratch_pool);
3141 err1 = svn_error_compose_create(err1, err2);
3142 }

--- 368 unchanged lines hidden (view full) ---

3511/* The body of svn_wc__db_external_remove(). */
3512static svn_error_t *
3513db_external_remove(const svn_skel_t *work_items,
3514 svn_wc__db_wcroot_t *wcroot,
3515 const char *local_relpath,
3516 apr_pool_t *scratch_pool)
3517{
3518 svn_sqlite__stmt_t *stmt;
3519 int affected_rows;
3441
3442 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
3443 STMT_DELETE_EXTERNAL));
3444 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
3520
3521 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
3522 STMT_DELETE_EXTERNAL));
3523 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
3445 SVN_ERR(svn_sqlite__step_done(stmt));
3524 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
3446
3525
3526 if (!affected_rows)
3527 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
3528 _("The node '%s' is not an external."),
3529 path_for_error_message(wcroot, local_relpath,
3530 scratch_pool));
3531
3447 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
3448
3449 /* ### What about actual? */
3450 return SVN_NO_ERROR;
3451}
3452
3453svn_error_t *
3454svn_wc__db_external_remove(svn_wc__db_t *db,

--- 83 unchanged lines hidden (view full) ---

3538 {
3539 apr_int64_t repos_id;
3540
3541 repos_id = svn_sqlite__column_int64(stmt, 3);
3542
3543 err = svn_error_compose_create(
3544 err,
3545 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
3532 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
3533
3534 /* ### What about actual? */
3535 return SVN_NO_ERROR;
3536}
3537
3538svn_error_t *
3539svn_wc__db_external_remove(svn_wc__db_t *db,

--- 83 unchanged lines hidden (view full) ---

3623 {
3624 apr_int64_t repos_id;
3625
3626 repos_id = svn_sqlite__column_int64(stmt, 3);
3627
3628 err = svn_error_compose_create(
3629 err,
3630 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
3546 wcroot->sdb, repos_id,
3631 wcroot, repos_id,
3547 result_pool));
3548 }
3549
3550 if (recorded_repos_relpath)
3551 *recorded_repos_relpath = svn_sqlite__column_text(stmt, 4,
3552 result_pool);
3553
3554 if (recorded_peg_revision)

--- 365 unchanged lines hidden (view full) ---

3920
3921 return SVN_NO_ERROR;
3922}
3923
3924
3925/* The body of svn_wc__db_scan_deletion().
3926 */
3927static svn_error_t *
3632 result_pool));
3633 }
3634
3635 if (recorded_repos_relpath)
3636 *recorded_repos_relpath = svn_sqlite__column_text(stmt, 4,
3637 result_pool);
3638
3639 if (recorded_peg_revision)

--- 365 unchanged lines hidden (view full) ---

4005
4006 return SVN_NO_ERROR;
4007}
4008
4009
4010/* The body of svn_wc__db_scan_deletion().
4011 */
4012static svn_error_t *
3928scan_deletion_txn(const char **base_del_relpath,
3929 const char **moved_to_relpath,
3930 const char **work_del_relpath,
3931 const char **moved_to_op_root_relpath,
3932 svn_wc__db_wcroot_t *wcroot,
3933 const char *local_relpath,
3934 apr_pool_t *result_pool,
3935 apr_pool_t *scratch_pool)
4013scan_deletion(const char **base_del_relpath,
4014 const char **moved_to_relpath,
4015 const char **work_del_relpath,
4016 const char **moved_to_op_root_relpath,
4017 svn_wc__db_wcroot_t *wcroot,
4018 const char *local_relpath,
4019 apr_pool_t *result_pool,
4020 apr_pool_t *scratch_pool)
3936{
3937 const char *current_relpath = local_relpath;
3938 svn_sqlite__stmt_t *stmt;
3939 svn_wc__db_status_t work_presence;
3940 svn_boolean_t have_row, scan, have_base;
3941 int op_depth;
3942
3943 /* Initialize all the OUT parameters. */

--- 7 unchanged lines hidden (view full) ---

3951 *moved_to_op_root_relpath = NULL;
3952
3953 /* If looking for moved-to info then we need to scan every path
3954 until we find it. If not looking for moved-to we only need to
3955 check op-roots and parents of op-roots. */
3956 scan = (moved_to_op_root_relpath || moved_to_relpath);
3957
3958 SVN_ERR(svn_sqlite__get_statement(
4021{
4022 const char *current_relpath = local_relpath;
4023 svn_sqlite__stmt_t *stmt;
4024 svn_wc__db_status_t work_presence;
4025 svn_boolean_t have_row, scan, have_base;
4026 int op_depth;
4027
4028 /* Initialize all the OUT parameters. */

--- 7 unchanged lines hidden (view full) ---

4036 *moved_to_op_root_relpath = NULL;
4037
4038 /* If looking for moved-to info then we need to scan every path
4039 until we find it. If not looking for moved-to we only need to
4040 check op-roots and parents of op-roots. */
4041 scan = (moved_to_op_root_relpath || moved_to_relpath);
4042
4043 SVN_ERR(svn_sqlite__get_statement(
3959 &stmt, wcroot->sdb,
3960 scan ? STMT_SELECT_DELETION_INFO_SCAN
3961 : STMT_SELECT_DELETION_INFO));
4044 &stmt, wcroot->sdb, STMT_SELECT_DELETION_INFO));
3962
3963 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
3964 SVN_ERR(svn_sqlite__step(&have_row, stmt));
3965 if (!have_row)
3966 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, svn_sqlite__reset(stmt),
3967 _("The node '%s' was not found."),
3968 path_for_error_message(wcroot, local_relpath,
3969 scratch_pool));

--- 104 unchanged lines hidden (view full) ---

4074 }
4075
4076 SVN_ERR(svn_sqlite__reset(stmt));
4077
4078 return SVN_NO_ERROR;
4079}
4080
4081svn_error_t *
4045
4046 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
4047 SVN_ERR(svn_sqlite__step(&have_row, stmt));
4048 if (!have_row)
4049 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, svn_sqlite__reset(stmt),
4050 _("The node '%s' was not found."),
4051 path_for_error_message(wcroot, local_relpath,
4052 scratch_pool));

--- 104 unchanged lines hidden (view full) ---

4157 }
4158
4159 SVN_ERR(svn_sqlite__reset(stmt));
4160
4161 return SVN_NO_ERROR;
4162}
4163
4164svn_error_t *
4165svn_wc__db_scan_deletion_internal(
4166 const char **base_del_relpath,
4167 const char **moved_to_relpath,
4168 const char **work_del_relpath,
4169 const char **moved_to_op_root_relpath,
4170 svn_wc__db_wcroot_t *wcroot,
4171 const char *local_relpath,
4172 apr_pool_t *result_pool,
4173 apr_pool_t *scratch_pool)
4174{
4175 return svn_error_trace(
4176 scan_deletion(base_del_relpath, moved_to_relpath, work_del_relpath,
4177 moved_to_op_root_relpath,
4178 wcroot, local_relpath,
4179 result_pool, scratch_pool));
4180}
4181
4182
4183svn_error_t *
4082svn_wc__db_scan_deletion(const char **base_del_abspath,
4083 const char **moved_to_abspath,
4084 const char **work_del_abspath,
4085 const char **moved_to_op_root_abspath,
4086 svn_wc__db_t *db,
4087 const char *local_abspath,
4088 apr_pool_t *result_pool,
4089 apr_pool_t *scratch_pool)

--- 5 unchanged lines hidden (view full) ---

4095
4096 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
4097
4098 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
4099 local_abspath, scratch_pool, scratch_pool));
4100 VERIFY_USABLE_WCROOT(wcroot);
4101
4102 SVN_WC__DB_WITH_TXN(
4184svn_wc__db_scan_deletion(const char **base_del_abspath,
4185 const char **moved_to_abspath,
4186 const char **work_del_abspath,
4187 const char **moved_to_op_root_abspath,
4188 svn_wc__db_t *db,
4189 const char *local_abspath,
4190 apr_pool_t *result_pool,
4191 apr_pool_t *scratch_pool)

--- 5 unchanged lines hidden (view full) ---

4197
4198 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
4199
4200 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
4201 local_abspath, scratch_pool, scratch_pool));
4202 VERIFY_USABLE_WCROOT(wcroot);
4203
4204 SVN_WC__DB_WITH_TXN(
4103 scan_deletion_txn(&base_del_relpath, &moved_to_relpath,
4104 &work_del_relpath, &moved_to_op_root_relpath,
4105 wcroot, local_relpath, result_pool, scratch_pool),
4205 scan_deletion(&base_del_relpath, &moved_to_relpath,
4206 &work_del_relpath, &moved_to_op_root_relpath,
4207 wcroot, local_relpath, result_pool, scratch_pool),
4106 wcroot);
4107
4108 if (base_del_abspath)
4109 {
4110 *base_del_abspath = (base_del_relpath
4111 ? svn_dirent_join(wcroot->abspath,
4112 base_del_relpath, result_pool)
4113 : NULL);

--- 81 unchanged lines hidden (view full) ---

4195 SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
4196 NULL, NULL, NULL, src_wcroot, local_relpath,
4197 scratch_pool, scratch_pool));
4198 }
4199 else if (node_status == svn_wc__db_status_deleted && is_op_root)
4200 {
4201 const char *base_del_relpath, *work_del_relpath;
4202
4208 wcroot);
4209
4210 if (base_del_abspath)
4211 {
4212 *base_del_abspath = (base_del_relpath
4213 ? svn_dirent_join(wcroot->abspath,
4214 base_del_relpath, result_pool)
4215 : NULL);

--- 81 unchanged lines hidden (view full) ---

4297 SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
4298 NULL, NULL, NULL, src_wcroot, local_relpath,
4299 scratch_pool, scratch_pool));
4300 }
4301 else if (node_status == svn_wc__db_status_deleted && is_op_root)
4302 {
4303 const char *base_del_relpath, *work_del_relpath;
4304
4203 SVN_ERR(scan_deletion_txn(&base_del_relpath, NULL,
4204 &work_del_relpath,
4205 NULL, src_wcroot, local_relpath,
4206 scratch_pool, scratch_pool));
4305 SVN_ERR(scan_deletion(&base_del_relpath, NULL,
4306 &work_del_relpath,
4307 NULL, src_wcroot, local_relpath,
4308 scratch_pool, scratch_pool));
4207 if (work_del_relpath)
4208 {
4209 const char *op_root_relpath;
4210 const char *parent_del_relpath = svn_relpath_dirname(work_del_relpath,
4211 scratch_pool);
4212
4213 /* Similar to, but not the same as, the _scan_addition and
4214 _join above. Can we use get_copyfrom here? */

--- 44 unchanged lines hidden (view full) ---

4259 const char *repos_uuid;
4260
4261 /* Pass the right repos-id for the destination db. We can't just use
4262 the id of the source database, as this value can change after
4263 relocation (and perhaps also when we start storing multiple
4264 working copies in a single db)! */
4265
4266 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
4309 if (work_del_relpath)
4310 {
4311 const char *op_root_relpath;
4312 const char *parent_del_relpath = svn_relpath_dirname(work_del_relpath,
4313 scratch_pool);
4314
4315 /* Similar to, but not the same as, the _scan_addition and
4316 _join above. Can we use get_copyfrom here? */

--- 44 unchanged lines hidden (view full) ---

4361 const char *repos_uuid;
4362
4363 /* Pass the right repos-id for the destination db. We can't just use
4364 the id of the source database, as this value can change after
4365 relocation (and perhaps also when we start storing multiple
4366 working copies in a single db)! */
4367
4368 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
4267 src_wcroot->sdb, *copyfrom_id,
4369 src_wcroot, *copyfrom_id,
4268 scratch_pool));
4269
4270 SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
4271 dst_wcroot->sdb, scratch_pool));
4272 }
4273
4274 return SVN_NO_ERROR;
4275}

--- 251 unchanged lines hidden (view full) ---

4527 scratch_pool));
4528 }
4529
4530 if (kind == svn_node_dir)
4531 {
4532 int src_op_depth;
4533
4534 SVN_ERR(op_depth_of(&src_op_depth, src_wcroot, src_relpath));
4370 scratch_pool));
4371
4372 SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
4373 dst_wcroot->sdb, scratch_pool));
4374 }
4375
4376 return SVN_NO_ERROR;
4377}

--- 251 unchanged lines hidden (view full) ---

4629 scratch_pool));
4630 }
4631
4632 if (kind == svn_node_dir)
4633 {
4634 int src_op_depth;
4635
4636 SVN_ERR(op_depth_of(&src_op_depth, src_wcroot, src_relpath));
4535 SVN_ERR(gather_repo_children(&children, src_wcroot, src_relpath,
4536 src_op_depth, scratch_pool, scratch_pool));
4637 SVN_ERR(gather_children(&children, src_wcroot, src_relpath,
4638 STMT_SELECT_OP_DEPTH_CHILDREN, src_op_depth,
4639 scratch_pool, scratch_pool));
4537 }
4538 else
4539 children = NULL;
4540
4541 if (src_wcroot == dst_wcroot)
4542 {
4543 svn_sqlite__stmt_t *stmt;
4544 const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,

--- 134 unchanged lines hidden (view full) ---

4679 const char *dst_relpath;
4680
4681 const svn_skel_t *work_items;
4682
4683 svn_boolean_t is_move;
4684 const char *dst_op_root_relpath;
4685};
4686
4640 }
4641 else
4642 children = NULL;
4643
4644 if (src_wcroot == dst_wcroot)
4645 {
4646 svn_sqlite__stmt_t *stmt;
4647 const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,

--- 134 unchanged lines hidden (view full) ---

4782 const char *dst_relpath;
4783
4784 const svn_skel_t *work_items;
4785
4786 svn_boolean_t is_move;
4787 const char *dst_op_root_relpath;
4788};
4789
4687/* Helper for svn_wc__db_op_copy().
4688 *
4689 * Implements svn_sqlite__transaction_callback_t. */
4790/* Helper for svn_wc__db_op_copy(). */
4690static svn_error_t *
4791static svn_error_t *
4691op_copy_txn(void * baton,
4692 svn_sqlite__db_t *sdb,
4792op_copy_txn(svn_wc__db_wcroot_t *wcroot,
4793 struct op_copy_baton *ocb,
4693 apr_pool_t *scratch_pool)
4694{
4794 apr_pool_t *scratch_pool)
4795{
4695 struct op_copy_baton *ocb = baton;
4696 int move_op_depth;
4697
4796 int move_op_depth;
4797
4698 if (sdb != ocb->dst_wcroot->sdb)
4798 if (wcroot != ocb->dst_wcroot)
4699 {
4700 /* Source and destination databases differ; so also start a lock
4799 {
4800 /* Source and destination databases differ; so also start a lock
4701 in the destination database, by calling ourself in a lock. */
4801 in the destination database, by calling ourself in an extra lock. */
4702
4802
4703 return svn_error_trace(
4704 svn_sqlite__with_lock(ocb->dst_wcroot->sdb,
4705 op_copy_txn, ocb, scratch_pool));
4803 SVN_WC__DB_WITH_TXN(op_copy_txn(ocb->dst_wcroot, ocb, scratch_pool),
4804 ocb->dst_wcroot);
4805
4806 return SVN_NO_ERROR;
4706 }
4707
4708 /* From this point we can assume a lock in the src and dst databases */
4709
4710 if (ocb->is_move)
4711 move_op_depth = relpath_depth(ocb->dst_op_root_relpath);
4712 else
4713 move_op_depth = 0;

--- 34 unchanged lines hidden (view full) ---

4748
4749 ocb.work_items = work_items;
4750 ocb.is_move = is_move;
4751 ocb.dst_op_root_relpath = svn_dirent_skip_ancestor(ocb.dst_wcroot->abspath,
4752 dst_op_root_abspath);
4753
4754 /* Call with the sdb in src_wcroot. It might call itself again to
4755 also obtain a lock in dst_wcroot */
4807 }
4808
4809 /* From this point we can assume a lock in the src and dst databases */
4810
4811 if (ocb->is_move)
4812 move_op_depth = relpath_depth(ocb->dst_op_root_relpath);
4813 else
4814 move_op_depth = 0;

--- 34 unchanged lines hidden (view full) ---

4849
4850 ocb.work_items = work_items;
4851 ocb.is_move = is_move;
4852 ocb.dst_op_root_relpath = svn_dirent_skip_ancestor(ocb.dst_wcroot->abspath,
4853 dst_op_root_abspath);
4854
4855 /* Call with the sdb in src_wcroot. It might call itself again to
4856 also obtain a lock in dst_wcroot */
4756 SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, op_copy_txn, &ocb,
4757 scratch_pool));
4857 SVN_WC__DB_WITH_TXN(op_copy_txn(ocb.src_wcroot, &ocb, scratch_pool),
4858 ocb.src_wcroot);
4758
4759 return SVN_NO_ERROR;
4760}
4761
4859
4860 return SVN_NO_ERROR;
4861}
4862
4863/* Remove unneeded actual nodes for svn_wc__db_op_copy_layer_internal */
4864static svn_error_t *
4865clear_or_remove_actual(svn_wc__db_wcroot_t *wcroot,
4866 const char *local_relpath,
4867 int op_depth,
4868 apr_pool_t *scratch_pool)
4869{
4870 svn_sqlite__stmt_t *stmt;
4871 svn_boolean_t have_row, shadowed;
4872 svn_boolean_t keep_conflict = FALSE;
4873
4874 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
4875 STMT_SELECT_NODE_INFO));
4876
4877 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
4878 SVN_ERR(svn_sqlite__step(&have_row, stmt));
4879
4880 if (have_row)
4881 {
4882 svn_wc__db_status_t presence;
4883
4884 shadowed = (svn_sqlite__column_int(stmt, 0) > op_depth);
4885 presence = svn_sqlite__column_token(stmt, 3, presence_map);
4886
4887 if (shadowed && presence == svn_wc__db_status_base_deleted)
4888 {
4889 keep_conflict = TRUE;
4890 SVN_ERR(svn_sqlite__step(&have_row, stmt));
4891
4892 if (have_row)
4893 shadowed = (svn_sqlite__column_int(stmt, 0) > op_depth);
4894 else
4895 shadowed = FALSE;
4896 }
4897 }
4898 else
4899 shadowed = FALSE;
4900
4901 SVN_ERR(svn_sqlite__reset(stmt));
4902 if (shadowed)
4903 return SVN_NO_ERROR;
4904
4905 if (keep_conflict)
4906 {
4907 /* We don't want to accidentally remove delete-delete conflicts */
4908 SVN_ERR(svn_sqlite__get_statement(
4909 &stmt, wcroot->sdb,
4910 STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT));
4911 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
4912 SVN_ERR(svn_sqlite__step_done(stmt));
4913 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
4914 STMT_DELETE_ACTUAL_EMPTY));
4915 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
4916 SVN_ERR(svn_sqlite__step_done(stmt));
4917 }
4918 else
4919 {
4920 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
4921 STMT_DELETE_ACTUAL_NODE));
4922 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
4923 SVN_ERR(svn_sqlite__step_done(stmt));
4924 }
4925
4926 return SVN_NO_ERROR;
4927}
4928
4929svn_error_t *
4930svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
4931 const char *src_op_relpath,
4932 int src_op_depth,
4933 const char *dst_op_relpath,
4934 svn_skel_t *conflict,
4935 svn_skel_t *work_items,
4936 apr_pool_t *scratch_pool)
4937{
4938 svn_sqlite__stmt_t *stmt, *stmt2;
4939 svn_boolean_t have_row;
4940 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
4941 int dst_op_depth = relpath_depth(dst_op_relpath);
4942 svn_boolean_t locked;
4943 svn_error_t *err = NULL;
4944
4945 SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, dst_op_relpath,
4946 FALSE, scratch_pool));
4947
4948 if (!locked)
4949 return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
4950 _("No write-lock in '%s'"),
4951 path_for_error_message(wcroot, dst_op_relpath,
4952 scratch_pool));
4953
4954 SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
4955 STMT_COPY_NODE_MOVE));
4956
4957 /* Replace entire subtree at one op-depth. */
4958 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
4959 STMT_SELECT_LAYER_FOR_REPLACE));
4960 SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
4961 src_op_relpath, src_op_depth,
4962 dst_op_relpath, dst_op_depth));
4963 SVN_ERR(svn_sqlite__step(&have_row, stmt));
4964 while (have_row)
4965 {
4966 const char *src_relpath;
4967 const char *dst_relpath;
4968
4969 svn_pool_clear(iterpool);
4970
4971 src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
4972 dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
4973
4974 err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
4975 src_relpath, src_op_depth,
4976 dst_relpath, dst_op_depth,
4977 svn_relpath_dirname(dst_relpath, iterpool));
4978 if (!err)
4979 err = svn_sqlite__step_done(stmt2);
4980
4981 /* stmt2 is reset (never modified or by step_done) */
4982
4983 if (err)
4984 break;
4985
4986 /* The node can't be deleted where it is added, so extension of
4987 an existing shadowing is only interesting 2 levels deep. */
4988 if (relpath_depth(dst_relpath) > (dst_op_depth+1))
4989 {
4990 svn_boolean_t exists = !svn_sqlite__column_is_null(stmt, 3);
4991
4992 if (exists)
4993 {
4994 svn_wc__db_status_t presence;
4995
4996 presence = svn_sqlite__column_token(stmt, 3, presence_map);
4997
4998 if (presence != svn_wc__db_status_normal)
4999 exists = FALSE;
5000 }
5001
5002 if (!exists)
5003 {
5004 svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
5005
5006 err = db_extend_parent_delete(wcroot, dst_relpath,
5007 kind, dst_op_depth, iterpool);
5008
5009 if (err)
5010 break;
5011 }
5012 }
5013
5014 SVN_ERR(svn_sqlite__step(&have_row, stmt));
5015 }
5016
5017 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
5018
5019 /* And now remove the records that are no longer needed */
5020 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
5021 STMT_SELECT_NO_LONGER_MOVED_RV));
5022 SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
5023 dst_op_relpath, dst_op_depth,
5024 src_op_relpath, src_op_depth));
5025 SVN_ERR(svn_sqlite__step(&have_row, stmt));
5026 while (have_row)
5027 {
5028 const char *dst_relpath;
5029 svn_wc__db_status_t shadowed_presence;
5030
5031 svn_pool_clear(iterpool);
5032
5033 dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
5034
5035 if (!svn_sqlite__column_is_null(stmt, 2))
5036 shadowed_presence = svn_sqlite__column_token(stmt, 2, presence_map);
5037 else
5038 shadowed_presence = svn_wc__db_status_not_present;
5039
5040 if (shadowed_presence != svn_wc__db_status_normal
5041 && shadowed_presence != svn_wc__db_status_incomplete)
5042 {
5043 err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
5044 STMT_DELETE_NODE);
5045 }
5046 else
5047 {
5048 err =svn_sqlite__get_statement(&stmt2, wcroot->sdb,
5049 STMT_REPLACE_WITH_BASE_DELETED);
5050 }
5051
5052 if (!err)
5053 err = svn_sqlite__bindf(stmt2, "isd", wcroot->wc_id, dst_relpath,
5054 dst_op_depth);
5055
5056 if (!err)
5057 err = svn_sqlite__step_done(stmt2);
5058
5059 /* stmt2 is reset (never modified or by step_done) */
5060 if (err)
5061 break;
5062
5063 /* Delete ACTUAL information about this node that we just deleted */
5064 err = clear_or_remove_actual(wcroot, dst_relpath, dst_op_depth,
5065 scratch_pool);
5066
5067 if (err)
5068 break;
5069
5070 /* Retract base-delete for the node itself */
5071 err = db_retract_parent_delete(wcroot, dst_relpath, dst_op_depth,
5072 scratch_pool);
5073
5074 if (err)
5075 break;
5076
5077 SVN_ERR(svn_sqlite__step(&have_row, stmt));
5078 }
5079 svn_pool_destroy(iterpool);
5080
5081 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
5082
5083 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
5084
5085 if (conflict)
5086 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, dst_op_relpath /* ## */,
5087 conflict, scratch_pool));
5088
5089 return SVN_NO_ERROR;
5090}
5091
4762/* The txn body of svn_wc__db_op_handle_move_back */
4763static svn_error_t *
4764handle_move_back(svn_boolean_t *moved_back,
4765 svn_wc__db_wcroot_t *wcroot,
4766 const char *local_relpath,
4767 const char *moved_from_relpath,
4768 const svn_skel_t *work_items,
4769 apr_pool_t *scratch_pool)

--- 144 unchanged lines hidden (view full) ---

4914 /* Ok, we can now safely remove this complete move, because we
4915 determined that it 100% matches the layer below it. */
4916
4917 /* ### We could copy the recorded timestamps from the higher to the
4918 lower layer in an attempt to improve status performance, but
4919 generally these values should be the same anyway as it was
4920 a no-op move. */
4921 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
5092/* The txn body of svn_wc__db_op_handle_move_back */
5093static svn_error_t *
5094handle_move_back(svn_boolean_t *moved_back,
5095 svn_wc__db_wcroot_t *wcroot,
5096 const char *local_relpath,
5097 const char *moved_from_relpath,
5098 const svn_skel_t *work_items,
5099 apr_pool_t *scratch_pool)

--- 144 unchanged lines hidden (view full) ---

5244 /* Ok, we can now safely remove this complete move, because we
5245 determined that it 100% matches the layer below it. */
5246
5247 /* ### We could copy the recorded timestamps from the higher to the
5248 lower layer in an attempt to improve status performance, but
5249 generally these values should be the same anyway as it was
5250 a no-op move. */
5251 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
4922 STMT_DELETE_MOVED_BACK));
5252 STMT_DELETE_WORKING_OP_DEPTH));
4923
4924 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
4925 local_relpath,
4926 relpath_depth(local_relpath)));
4927
4928 SVN_ERR(svn_sqlite__step_done(stmt));
4929
4930 if (moved_back)

--- 108 unchanged lines hidden (view full) ---

5039 || strcmp(node_repos_relpath, repos_relpath))
5040 {
5041 /* Add a not-present node in the destination wcroot */
5042 struct insert_working_baton_t iwb;
5043 const char *repos_root_url;
5044 const char *repos_uuid;
5045
5046 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
5253
5254 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
5255 local_relpath,
5256 relpath_depth(local_relpath)));
5257
5258 SVN_ERR(svn_sqlite__step_done(stmt));
5259
5260 if (moved_back)

--- 108 unchanged lines hidden (view full) ---

5369 || strcmp(node_repos_relpath, repos_relpath))
5370 {
5371 /* Add a not-present node in the destination wcroot */
5372 struct insert_working_baton_t iwb;
5373 const char *repos_root_url;
5374 const char *repos_uuid;
5375
5376 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
5047 src_wcroot->sdb, node_repos_id,
5377 src_wcroot, node_repos_id,
5048 scratch_pool));
5049
5050 SVN_ERR(create_repos_id(&node_repos_id, repos_root_url, repos_uuid,
5051 dst_wcroot->sdb, scratch_pool));
5052
5053 blank_iwb(&iwb);
5054
5055 iwb.op_depth = dst_op_depth;

--- 105 unchanged lines hidden (view full) ---

5161
5162 /* This code is currently still triggered by copying deleted nodes
5163 between separate working copies. See ### comment above. */
5164
5165 svn_pool_destroy(iterpool);
5166 return SVN_NO_ERROR;
5167 }
5168
5378 scratch_pool));
5379
5380 SVN_ERR(create_repos_id(&node_repos_id, repos_root_url, repos_uuid,
5381 dst_wcroot->sdb, scratch_pool));
5382
5383 blank_iwb(&iwb);
5384
5385 iwb.op_depth = dst_op_depth;

--- 105 unchanged lines hidden (view full) ---

5491
5492 /* This code is currently still triggered by copying deleted nodes
5493 between separate working copies. See ### comment above. */
5494
5495 svn_pool_destroy(iterpool);
5496 return SVN_NO_ERROR;
5497 }
5498
5169 SVN_ERR(gather_repo_children(&children, src_wcroot, src_relpath,
5170 src_op_depth, scratch_pool, iterpool));
5499 SVN_ERR(gather_children(&children, src_wcroot, src_relpath,
5500 STMT_SELECT_OP_DEPTH_CHILDREN, src_op_depth,
5501 scratch_pool, iterpool));
5171
5172 for (i = 0; i < children->nelts; i++)
5173 {
5174 const char *name = APR_ARRAY_IDX(children, i, const char *);
5175 const char *child_src_relpath;
5176 const char *child_dst_relpath;
5177 const char *child_repos_relpath = NULL;
5178

--- 12 unchanged lines hidden (view full) ---

5191 move_op_depth, scratch_pool));
5192 }
5193
5194 svn_pool_destroy(iterpool);
5195
5196 return SVN_NO_ERROR;
5197}
5198
5502
5503 for (i = 0; i < children->nelts; i++)
5504 {
5505 const char *name = APR_ARRAY_IDX(children, i, const char *);
5506 const char *child_src_relpath;
5507 const char *child_dst_relpath;
5508 const char *child_repos_relpath = NULL;
5509

--- 12 unchanged lines hidden (view full) ---

5522 move_op_depth, scratch_pool));
5523 }
5524
5525 svn_pool_destroy(iterpool);
5526
5527 return SVN_NO_ERROR;
5528}
5529
5199/* Helper for svn_wc__db_op_copy_shadowed_layer().
5200 *
5201 * Implements svn_sqlite__transaction_callback_t. */
5530/* Helper for svn_wc__db_op_copy_shadowed_layer(). */
5202static svn_error_t *
5531static svn_error_t *
5203op_copy_shadowed_layer_txn(void *baton,
5204 svn_sqlite__db_t *sdb,
5532op_copy_shadowed_layer_txn(svn_wc__db_wcroot_t *wcroot,
5533 struct op_copy_baton *ocb,
5205 apr_pool_t *scratch_pool)
5206{
5534 apr_pool_t *scratch_pool)
5535{
5207 struct op_copy_baton *ocb = baton;
5208 const char *src_parent_relpath;
5209 const char *dst_parent_relpath;
5210 int src_op_depth;
5211 int dst_op_depth;
5212 int del_op_depth;
5213 const char *repos_relpath = NULL;
5214 apr_int64_t repos_id = INVALID_REPOS_ID;
5215 svn_revnum_t revision = SVN_INVALID_REVNUM;
5216
5536 const char *src_parent_relpath;
5537 const char *dst_parent_relpath;
5538 int src_op_depth;
5539 int dst_op_depth;
5540 int del_op_depth;
5541 const char *repos_relpath = NULL;
5542 apr_int64_t repos_id = INVALID_REPOS_ID;
5543 svn_revnum_t revision = SVN_INVALID_REVNUM;
5544
5217 if (sdb != ocb->dst_wcroot->sdb)
5545 if (wcroot != ocb->dst_wcroot)
5218 {
5546 {
5219 /* Source and destination databases differ; so also start a lock
5220 in the destination database, by calling ourself in a lock. */
5547 /* Source and destination databases differ; so also start a lock
5548 in the destination database, by calling ourself in an extra lock. */
5221
5549
5222 return svn_error_trace(
5223 svn_sqlite__with_lock(ocb->dst_wcroot->sdb,
5224 op_copy_shadowed_layer_txn,
5225 ocb, scratch_pool));
5550 SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb->dst_wcroot, ocb,
5551 scratch_pool),
5552 ocb->dst_wcroot);
5553
5554 return SVN_NO_ERROR;
5226 }
5227
5228 /* From this point we can assume a lock in the src and dst databases */
5229
5230
5231 /* src_relpath and dst_relpath can't be wcroot as we need their parents */
5232 SVN_ERR_ASSERT(*ocb->src_relpath && *ocb->dst_relpath);
5233

--- 65 unchanged lines hidden (view full) ---

5299
5300 ocb.is_move = is_move;
5301 ocb.dst_op_root_relpath = NULL; /* not used by op_copy_shadowed_layer_txn */
5302
5303 ocb.work_items = NULL;
5304
5305 /* Call with the sdb in src_wcroot. It might call itself again to
5306 also obtain a lock in dst_wcroot */
5555 }
5556
5557 /* From this point we can assume a lock in the src and dst databases */
5558
5559
5560 /* src_relpath and dst_relpath can't be wcroot as we need their parents */
5561 SVN_ERR_ASSERT(*ocb->src_relpath && *ocb->dst_relpath);
5562

--- 65 unchanged lines hidden (view full) ---

5628
5629 ocb.is_move = is_move;
5630 ocb.dst_op_root_relpath = NULL; /* not used by op_copy_shadowed_layer_txn */
5631
5632 ocb.work_items = NULL;
5633
5634 /* Call with the sdb in src_wcroot. It might call itself again to
5635 also obtain a lock in dst_wcroot */
5307 SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb,
5308 op_copy_shadowed_layer_txn,
5309 &ocb, scratch_pool));
5636 SVN_WC__DB_WITH_TXN(op_copy_shadowed_layer_txn(ocb.src_wcroot, &ocb,
5637 scratch_pool),
5638 ocb.src_wcroot);
5310
5311 return SVN_NO_ERROR;
5312}
5313
5314
5315/* If there are any server-excluded base nodes then the copy must fail
5316 as it's not possible to commit such a copy.
5317 Return an error if there are any server-excluded nodes. */

--- 453 unchanged lines hidden (view full) ---

5771
5772/* Set the ACTUAL_NODE properties column for (WC_ID, LOCAL_RELPATH) to
5773 * PROPS.
5774 *
5775 * Note: PROPS=NULL means the actual props are the same as the pristine
5776 * props; to indicate no properties when the pristine has some props,
5777 * PROPS must be an empty hash. */
5778static svn_error_t *
5639
5640 return SVN_NO_ERROR;
5641}
5642
5643
5644/* If there are any server-excluded base nodes then the copy must fail
5645 as it's not possible to commit such a copy.
5646 Return an error if there are any server-excluded nodes. */

--- 453 unchanged lines hidden (view full) ---

6100
6101/* Set the ACTUAL_NODE properties column for (WC_ID, LOCAL_RELPATH) to
6102 * PROPS.
6103 *
6104 * Note: PROPS=NULL means the actual props are the same as the pristine
6105 * props; to indicate no properties when the pristine has some props,
6106 * PROPS must be an empty hash. */
6107static svn_error_t *
5779set_actual_props(apr_int64_t wc_id,
6108set_actual_props(svn_wc__db_wcroot_t *wcroot,
5780 const char *local_relpath,
5781 apr_hash_t *props,
6109 const char *local_relpath,
6110 apr_hash_t *props,
5782 svn_sqlite__db_t *db,
5783 apr_pool_t *scratch_pool)
5784{
5785 svn_sqlite__stmt_t *stmt;
5786 int affected_rows;
5787
6111 apr_pool_t *scratch_pool)
6112{
6113 svn_sqlite__stmt_t *stmt;
6114 int affected_rows;
6115
5788 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_UPDATE_ACTUAL_PROPS));
5789 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
6116 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6117 STMT_UPDATE_ACTUAL_PROPS));
6118 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
5790 SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
5791 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
5792
5793 if (affected_rows == 1 || !props)
6119 SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
6120 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
6121
6122 if (affected_rows == 1 || !props)
5794 return SVN_NO_ERROR; /* We are done */
6123 {
6124 /* Perhaps the entire ACTUAL record is unneeded now? */
6125 if (!props && affected_rows)
6126 {
6127 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6128 STMT_DELETE_ACTUAL_EMPTY));
6129 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6130 SVN_ERR(svn_sqlite__step_done(stmt));
6131 }
5795
6132
6133 return SVN_NO_ERROR; /* We are done */
6134 }
6135
5796 /* We have to insert a row in ACTUAL */
5797
6136 /* We have to insert a row in ACTUAL */
6137
5798 SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_ACTUAL_PROPS));
5799 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
6138 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6139 STMT_INSERT_ACTUAL_PROPS));
6140 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
5800 if (*local_relpath != '\0')
5801 SVN_ERR(svn_sqlite__bind_text(stmt, 3,
5802 svn_relpath_dirname(local_relpath,
5803 scratch_pool)));
5804 SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
5805 return svn_error_trace(svn_sqlite__step_done(stmt));
5806}
5807
6141 if (*local_relpath != '\0')
6142 SVN_ERR(svn_sqlite__bind_text(stmt, 3,
6143 svn_relpath_dirname(local_relpath,
6144 scratch_pool)));
6145 SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
6146 return svn_error_trace(svn_sqlite__step_done(stmt));
6147}
6148
6149svn_error_t *
6150svn_wc__db_op_set_props_internal(svn_wc__db_wcroot_t *wcroot,
6151 const char *local_relpath,
6152 apr_hash_t *props,
6153 svn_boolean_t clear_recorded_info,
6154 apr_pool_t *scratch_pool)
6155{
6156 SVN_ERR(set_actual_props(wcroot, local_relpath, props, scratch_pool));
5808
6157
6158 if (clear_recorded_info)
6159 {
6160 SVN_ERR(db_record_fileinfo(wcroot, local_relpath,
6161 SVN_INVALID_FILESIZE, 0,
6162 scratch_pool));
6163 }
6164
6165 return SVN_NO_ERROR;
6166}
6167
5809/* The body of svn_wc__db_op_set_props().
5810
5811 Set the 'properties' column in the 'ACTUAL_NODE' table to BATON->props.
5812 Create an entry in the ACTUAL table for the node if it does not yet
5813 have one.
5814 To specify no properties, BATON->props must be an empty hash, not NULL.
5815 BATON is of type 'struct set_props_baton_t'.
5816*/

--- 18 unchanged lines hidden (view full) ---

5835 apr_array_header_t *prop_diffs;
5836
5837 SVN_ERR(svn_prop_diffs(&prop_diffs, props, pristine_props,
5838 scratch_pool));
5839 if (prop_diffs->nelts == 0)
5840 props = NULL;
5841 }
5842
6168/* The body of svn_wc__db_op_set_props().
6169
6170 Set the 'properties' column in the 'ACTUAL_NODE' table to BATON->props.
6171 Create an entry in the ACTUAL table for the node if it does not yet
6172 have one.
6173 To specify no properties, BATON->props must be an empty hash, not NULL.
6174 BATON is of type 'struct set_props_baton_t'.
6175*/

--- 18 unchanged lines hidden (view full) ---

6194 apr_array_header_t *prop_diffs;
6195
6196 SVN_ERR(svn_prop_diffs(&prop_diffs, props, pristine_props,
6197 scratch_pool));
6198 if (prop_diffs->nelts == 0)
6199 props = NULL;
6200 }
6201
5843 SVN_ERR(set_actual_props(wcroot->wc_id, local_relpath,
5844 props, wcroot->sdb, scratch_pool));
6202 SVN_ERR(svn_wc__db_op_set_props_internal(wcroot, local_relpath, props,
6203 clear_recorded_info, scratch_pool));
5845
6204
5846 if (clear_recorded_info)
5847 {
5848 SVN_ERR(db_record_fileinfo(wcroot, local_relpath,
5849 SVN_INVALID_FILESIZE, 0,
5850 scratch_pool));
5851 }
5852
5853 /* And finally. */
5854 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
5855 if (conflict)
5856 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
5857 conflict, scratch_pool));
5858
5859 return SVN_NO_ERROR;
5860}

--- 214 unchanged lines hidden (view full) ---

6075
6076 SVN_ERR(populate_targets_tree(wcroot, local_relpath, scb->depth,
6077 scb->changelist_filter, scratch_pool));
6078
6079 /* Ensure we have actual nodes for our targets. */
6080 if (scb->new_changelist)
6081 {
6082 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6205 /* And finally. */
6206 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
6207 if (conflict)
6208 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
6209 conflict, scratch_pool));
6210
6211 return SVN_NO_ERROR;
6212}

--- 214 unchanged lines hidden (view full) ---

6427
6428 SVN_ERR(populate_targets_tree(wcroot, local_relpath, scb->depth,
6429 scb->changelist_filter, scratch_pool));
6430
6431 /* Ensure we have actual nodes for our targets. */
6432 if (scb->new_changelist)
6433 {
6434 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6083 STMT_INSERT_ACTUAL_EMPTIES));
6435 STMT_INSERT_ACTUAL_EMPTIES_FILES));
6084 SVN_ERR(svn_sqlite__step_done(stmt));
6085 }
6086
6087 /* Now create our notification table. */
6088 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
6089 STMT_CREATE_CHANGELIST_LIST));
6090 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
6091 STMT_CREATE_CHANGELIST_TRIGGER));

--- 200 unchanged lines hidden (view full) ---

6292 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
6293
6294 return SVN_NO_ERROR;
6295
6296}
6297
6298/* The body of svn_wc__db_op_mark_resolved().
6299 */
6436 SVN_ERR(svn_sqlite__step_done(stmt));
6437 }
6438
6439 /* Now create our notification table. */
6440 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
6441 STMT_CREATE_CHANGELIST_LIST));
6442 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
6443 STMT_CREATE_CHANGELIST_TRIGGER));

--- 200 unchanged lines hidden (view full) ---

6644 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
6645
6646 return SVN_NO_ERROR;
6647
6648}
6649
6650/* The body of svn_wc__db_op_mark_resolved().
6651 */
6300static svn_error_t *
6301db_op_mark_resolved(svn_wc__db_wcroot_t *wcroot,
6302 const char *local_relpath,
6303 svn_wc__db_t *db,
6304 svn_boolean_t resolved_text,
6305 svn_boolean_t resolved_props,
6306 svn_boolean_t resolved_tree,
6307 const svn_skel_t *work_items,
6308 apr_pool_t *scratch_pool)
6652svn_error_t *
6653svn_wc__db_op_mark_resolved_internal(svn_wc__db_wcroot_t *wcroot,
6654 const char *local_relpath,
6655 svn_wc__db_t *db,
6656 svn_boolean_t resolved_text,
6657 svn_boolean_t resolved_props,
6658 svn_boolean_t resolved_tree,
6659 const svn_skel_t *work_items,
6660 apr_pool_t *scratch_pool)
6309{
6310 svn_sqlite__stmt_t *stmt;
6311 svn_boolean_t have_row;
6312 int total_affected_rows = 0;
6313 svn_boolean_t resolved_all;
6314 apr_size_t conflict_len;
6315 const void *conflict_data;
6316 svn_skel_t *conflicts;

--- 81 unchanged lines hidden (view full) ---

6398
6399 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
6400
6401 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
6402 local_abspath, scratch_pool, scratch_pool));
6403 VERIFY_USABLE_WCROOT(wcroot);
6404
6405 SVN_WC__DB_WITH_TXN(
6661{
6662 svn_sqlite__stmt_t *stmt;
6663 svn_boolean_t have_row;
6664 int total_affected_rows = 0;
6665 svn_boolean_t resolved_all;
6666 apr_size_t conflict_len;
6667 const void *conflict_data;
6668 svn_skel_t *conflicts;

--- 81 unchanged lines hidden (view full) ---

6750
6751 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
6752
6753 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
6754 local_abspath, scratch_pool, scratch_pool));
6755 VERIFY_USABLE_WCROOT(wcroot);
6756
6757 SVN_WC__DB_WITH_TXN(
6406 db_op_mark_resolved(wcroot, local_relpath, db,
6758 svn_wc__db_op_mark_resolved_internal(
6759 wcroot, local_relpath, db,
6407 resolved_text, resolved_props, resolved_tree,
6408 work_items, scratch_pool),
6409 wcroot);
6410
6411 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
6412 return SVN_NO_ERROR;
6413}
6414
6760 resolved_text, resolved_props, resolved_tree,
6761 work_items, scratch_pool),
6762 wcroot);
6763
6764 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
6765 return SVN_NO_ERROR;
6766}
6767
6415/* Clear moved-to information at the delete-half of the move which
6416 * moved LOCAL_RELPATH here. This transforms the move into a simple delete. */
6768/* Clear moved-to information at the delete-half of the move which moved
6769 * MOVED_TO_RELPATH here. This transforms the delete part of the move into a
6770 * normal delete.
6771 *
6772 * Note that the moved-to location is always an op-root, while this is not the
6773 * case for a moved-from location.
6774 */
6417static svn_error_t *
6775static svn_error_t *
6418clear_moved_to(const char *local_relpath,
6419 svn_wc__db_wcroot_t *wcroot,
6776clear_moved_to(svn_wc__db_wcroot_t *wcroot,
6777 const char *moved_to_relpath,
6420 apr_pool_t *scratch_pool)
6421{
6422 svn_sqlite__stmt_t *stmt;
6778 apr_pool_t *scratch_pool)
6779{
6780 svn_sqlite__stmt_t *stmt;
6423 svn_boolean_t have_row;
6424 const char *moved_from_relpath;
6781 const char *moved_from_relpath;
6782 int moved_from_op_depth;
6425
6426 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6427 STMT_SELECT_MOVED_FROM_RELPATH));
6783
6784 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6785 STMT_SELECT_MOVED_FROM_RELPATH));
6428 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6429 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6430 if (!have_row)
6431 {
6432 SVN_ERR(svn_sqlite__reset(stmt));
6433 return SVN_NO_ERROR;
6434 }
6786 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, moved_to_relpath));
6787 SVN_ERR(svn_sqlite__step_row(stmt));
6435
6436 moved_from_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
6788
6789 moved_from_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
6790 moved_from_op_depth = svn_sqlite__column_int(stmt, 1);
6437 SVN_ERR(svn_sqlite__reset(stmt));
6438
6439 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6440 STMT_CLEAR_MOVED_TO_RELPATH));
6441 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6791 SVN_ERR(svn_sqlite__reset(stmt));
6792
6793 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6794 STMT_CLEAR_MOVED_TO_RELPATH));
6795 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6442 moved_from_relpath,
6443 relpath_depth(moved_from_relpath)));
6444 SVN_ERR(svn_sqlite__step_done(stmt));
6796 moved_from_relpath, moved_from_op_depth));
6797 SVN_ERR(svn_sqlite__update(NULL, stmt));
6445
6446 return SVN_NO_ERROR;
6447}
6448
6798
6799 return SVN_NO_ERROR;
6800}
6801
6802/* Helper function for op_revert_txn. Raises move tree conflicts on
6803 descendants to ensure database stability on a non recursive revert
6804 of an ancestor that contains a possible move related tree conflict.
6805 */
6806static svn_error_t *
6807revert_maybe_raise_moved_away(svn_wc__db_wcroot_t * wcroot,
6808 svn_wc__db_t *db,
6809 const char *local_relpath,
6810 int op_depth_below,
6811 apr_pool_t *scratch_pool)
6812{
6813 svn_skel_t *conflict;
6814 svn_wc_operation_t operation;
6815 svn_boolean_t tree_conflicted;
6816 const apr_array_header_t *locations;
6817 svn_wc_conflict_reason_t reason;
6818 svn_wc_conflict_action_t action;
6819
6820 SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL, wcroot,
6821 local_relpath,
6822 scratch_pool, scratch_pool));
6823
6824 if (!conflict)
6825 return SVN_NO_ERROR;
6826
6827 SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, NULL, NULL,
6828 &tree_conflicted,
6829 db, wcroot->abspath,
6830 conflict,
6831 scratch_pool, scratch_pool));
6832
6833 if (!tree_conflicted
6834 || (operation != svn_wc_operation_update
6835 && operation != svn_wc_operation_switch))
6836 {
6837 return SVN_NO_ERROR;
6838 }
6839
6840 SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
6841 NULL,
6842 db, wcroot->abspath,
6843 conflict,
6844 scratch_pool,
6845 scratch_pool));
6846
6847 if (reason == svn_wc_conflict_reason_deleted
6848 || reason == svn_wc_conflict_reason_replaced)
6849 {
6850 SVN_ERR(svn_wc__db_op_raise_moved_away_internal(
6851 wcroot, local_relpath, op_depth_below, db,
6852 operation, action,
6853 (locations && locations->nelts > 0)
6854 ? APR_ARRAY_IDX(locations, 0,
6855 const svn_wc_conflict_version_t *)
6856 : NULL,
6857 (locations && locations->nelts > 1)
6858 ? APR_ARRAY_IDX(locations, 1,
6859 const svn_wc_conflict_version_t *)
6860 : NULL,
6861 scratch_pool));
6862
6863 /* Transform the move information into revert information */
6864 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
6865 STMT_MOVE_NOTIFY_TO_REVERT));
6866 }
6867
6868 return SVN_NO_ERROR;
6869}
6870
6871/* Baton for op_revert_txn and op_revert_recursive_txn */
6872struct revert_baton_t
6873{
6874 svn_wc__db_t *db;
6875 svn_boolean_t clear_changelists;
6876};
6877
6449/* One of the two alternative bodies of svn_wc__db_op_revert().
6450 *
6451 * Implements svn_wc__db_txn_callback_t. */
6452static svn_error_t *
6453op_revert_txn(void *baton,
6454 svn_wc__db_wcroot_t *wcroot,
6455 const char *local_relpath,
6456 apr_pool_t *scratch_pool)
6457{
6878/* One of the two alternative bodies of svn_wc__db_op_revert().
6879 *
6880 * Implements svn_wc__db_txn_callback_t. */
6881static svn_error_t *
6882op_revert_txn(void *baton,
6883 svn_wc__db_wcroot_t *wcroot,
6884 const char *local_relpath,
6885 apr_pool_t *scratch_pool)
6886{
6458 svn_wc__db_t *db = baton;
6887 struct revert_baton_t *rvb = baton;
6888 svn_wc__db_t *db = rvb->db;
6459 svn_sqlite__stmt_t *stmt;
6460 svn_boolean_t have_row;
6461 int op_depth;
6462 svn_boolean_t moved_here;
6463 int affected_rows;
6464 const char *moved_to;
6889 svn_sqlite__stmt_t *stmt;
6890 svn_boolean_t have_row;
6891 int op_depth;
6892 svn_boolean_t moved_here;
6893 int affected_rows;
6894 const char *moved_to;
6895 int op_depth_below;
6465
6466 /* ### Similar structure to op_revert_recursive_txn, should they be
6467 combined? */
6468
6469 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6470 STMT_SELECT_NODE_INFO));
6471 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6472 SVN_ERR(svn_sqlite__step(&have_row, stmt));

--- 30 unchanged lines hidden (view full) ---

6503 path_for_error_message(wcroot,
6504 local_relpath,
6505 scratch_pool));
6506 }
6507
6508 op_depth = svn_sqlite__column_int(stmt, 0);
6509 moved_here = svn_sqlite__column_boolean(stmt, 15);
6510 moved_to = svn_sqlite__column_text(stmt, 17, scratch_pool);
6896
6897 /* ### Similar structure to op_revert_recursive_txn, should they be
6898 combined? */
6899
6900 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6901 STMT_SELECT_NODE_INFO));
6902 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6903 SVN_ERR(svn_sqlite__step(&have_row, stmt));

--- 30 unchanged lines hidden (view full) ---

6934 path_for_error_message(wcroot,
6935 local_relpath,
6936 scratch_pool));
6937 }
6938
6939 op_depth = svn_sqlite__column_int(stmt, 0);
6940 moved_here = svn_sqlite__column_boolean(stmt, 15);
6941 moved_to = svn_sqlite__column_text(stmt, 17, scratch_pool);
6942
6943 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6944 if (have_row)
6945 op_depth_below = svn_sqlite__column_int(stmt, 0);
6946 else
6947 op_depth_below = -1;
6948
6511 SVN_ERR(svn_sqlite__reset(stmt));
6512
6513 if (moved_to)
6514 {
6949 SVN_ERR(svn_sqlite__reset(stmt));
6950
6951 if (moved_to)
6952 {
6515 SVN_ERR(svn_wc__db_resolve_break_moved_away_internal(wcroot,
6516 local_relpath,
6517 op_depth,
6518 scratch_pool));
6953 SVN_ERR(svn_wc__db_op_break_move_internal(wcroot,
6954 local_relpath, op_depth,
6955 moved_to, NULL, scratch_pool));
6519 }
6956 }
6520 else
6521 {
6522 svn_skel_t *conflict;
6523
6957
6524 SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, wcroot,
6525 local_relpath,
6526 scratch_pool, scratch_pool));
6527 if (conflict)
6528 {
6529 svn_wc_operation_t operation;
6530 svn_boolean_t tree_conflicted;
6531
6532 SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
6533 &tree_conflicted,
6534 db, wcroot->abspath,
6535 conflict,
6536 scratch_pool, scratch_pool));
6537 if (tree_conflicted
6538 && (operation == svn_wc_operation_update
6539 || operation == svn_wc_operation_switch))
6540 {
6541 svn_wc_conflict_reason_t reason;
6542 svn_wc_conflict_action_t action;
6543
6544 SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
6545 NULL,
6546 db, wcroot->abspath,
6547 conflict,
6548 scratch_pool,
6549 scratch_pool));
6550
6551 if (reason == svn_wc_conflict_reason_deleted)
6552 SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(
6553 db, svn_dirent_join(wcroot->abspath, local_relpath,
6554 scratch_pool),
6555 NULL, NULL /* ### How do we notify this? */,
6556 scratch_pool));
6557 }
6558 }
6559 }
6560
6561 if (op_depth > 0 && op_depth == relpath_depth(local_relpath))
6562 {
6958 if (op_depth > 0 && op_depth == relpath_depth(local_relpath))
6959 {
6960 int op_depth_increased;
6961
6563 /* Can't do non-recursive revert if children exist */
6564 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6565 STMT_SELECT_GE_OP_DEPTH_CHILDREN));
6566 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6567 local_relpath, op_depth));
6568 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6569 SVN_ERR(svn_sqlite__reset(stmt));
6570 if (have_row)

--- 6 unchanged lines hidden (view full) ---

6577
6578 /* Rewrite the op-depth of all deleted children making the
6579 direct children into roots of deletes. */
6580 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6581 STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE));
6582 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6583 local_relpath,
6584 op_depth));
6962 /* Can't do non-recursive revert if children exist */
6963 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6964 STMT_SELECT_GE_OP_DEPTH_CHILDREN));
6965 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6966 local_relpath, op_depth));
6967 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6968 SVN_ERR(svn_sqlite__reset(stmt));
6969 if (have_row)

--- 6 unchanged lines hidden (view full) ---

6976
6977 /* Rewrite the op-depth of all deleted children making the
6978 direct children into roots of deletes. */
6979 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6980 STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE));
6981 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6982 local_relpath,
6983 op_depth));
6585 SVN_ERR(svn_sqlite__step_done(stmt));
6984 SVN_ERR(svn_sqlite__update(&op_depth_increased, stmt));
6586
6587 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6588 STMT_DELETE_WORKING_NODE));
6589 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6590 SVN_ERR(svn_sqlite__step_done(stmt));
6591
6592 /* ### This removes the lock, but what about the access baton? */
6593 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6594 STMT_DELETE_WC_LOCK_ORPHAN));
6595 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6596 SVN_ERR(svn_sqlite__step_done(stmt));
6597
6598 /* If this node was moved-here, clear moved-to at the move source. */
6599 if (moved_here)
6985
6986 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6987 STMT_DELETE_WORKING_NODE));
6988 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6989 SVN_ERR(svn_sqlite__step_done(stmt));
6990
6991 /* ### This removes the lock, but what about the access baton? */
6992 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6993 STMT_DELETE_WC_LOCK_ORPHAN));
6994 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6995 SVN_ERR(svn_sqlite__step_done(stmt));
6996
6997 /* If this node was moved-here, clear moved-to at the move source. */
6998 if (moved_here)
6600 SVN_ERR(clear_moved_to(local_relpath, wcroot, scratch_pool));
6999 SVN_ERR(clear_moved_to(wcroot, local_relpath, scratch_pool));
7000
7001 /* If the node was moved itself, we don't have interesting moved
7002 children (and the move itself was already broken) */
7003 if (op_depth_increased && !moved_to)
7004 SVN_ERR(revert_maybe_raise_moved_away(wcroot, db, local_relpath,
7005 op_depth_below, scratch_pool));
6601 }
6602
7006 }
7007
6603 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6604 STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST));
6605 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6606 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
6607 if (!affected_rows)
7008 if (rvb->clear_changelists)
6608 {
6609 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7009 {
7010 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6610 STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST));
7011 STMT_DELETE_ACTUAL_NODE));
6611 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6612 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
6613 }
7012 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7013 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
7014 }
7015 else
7016 {
7017 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7018 STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST));
7019 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7020 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
7021 if (!affected_rows)
7022 {
7023 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7024 STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST));
7025 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7026 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
7027 }
7028 }
6614
6615 return SVN_NO_ERROR;
6616}
6617
6618
6619/* One of the two alternative bodies of svn_wc__db_op_revert().
6620 *
6621 * Implements svn_wc__db_txn_callback_t. */
6622static svn_error_t *
6623op_revert_recursive_txn(void *baton,
6624 svn_wc__db_wcroot_t *wcroot,
6625 const char *local_relpath,
6626 apr_pool_t *scratch_pool)
6627{
7029
7030 return SVN_NO_ERROR;
7031}
7032
7033
7034/* One of the two alternative bodies of svn_wc__db_op_revert().
7035 *
7036 * Implements svn_wc__db_txn_callback_t. */
7037static svn_error_t *
7038op_revert_recursive_txn(void *baton,
7039 svn_wc__db_wcroot_t *wcroot,
7040 const char *local_relpath,
7041 apr_pool_t *scratch_pool)
7042{
7043 struct revert_baton_t *rvb = baton;
6628 svn_sqlite__stmt_t *stmt;
6629 svn_boolean_t have_row;
6630 int op_depth;
6631 int select_op_depth;
6632 svn_boolean_t moved_here;
6633 int affected_rows;
6634 apr_pool_t *iterpool;
6635

--- 39 unchanged lines hidden (view full) ---

6675 /* Remove moved-here from move destinations outside the tree. */
6676 SVN_ERR(svn_sqlite__get_statement(
6677 &stmt, wcroot->sdb, STMT_SELECT_MOVED_OUTSIDE));
6678 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
6679 op_depth));
6680 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6681 while (have_row)
6682 {
7044 svn_sqlite__stmt_t *stmt;
7045 svn_boolean_t have_row;
7046 int op_depth;
7047 int select_op_depth;
7048 svn_boolean_t moved_here;
7049 int affected_rows;
7050 apr_pool_t *iterpool;
7051

--- 39 unchanged lines hidden (view full) ---

7091 /* Remove moved-here from move destinations outside the tree. */
7092 SVN_ERR(svn_sqlite__get_statement(
7093 &stmt, wcroot->sdb, STMT_SELECT_MOVED_OUTSIDE));
7094 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
7095 op_depth));
7096 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7097 while (have_row)
7098 {
6683 const char *move_src_relpath = svn_sqlite__column_text(stmt, 0, NULL);
7099 const char *src_relpath = svn_sqlite__column_text(stmt, 0, NULL);
7100 const char *dst_relpath = svn_sqlite__column_text(stmt, 1, NULL);
6684 int move_op_depth = svn_sqlite__column_int(stmt, 2);
6685 svn_error_t *err;
6686
7101 int move_op_depth = svn_sqlite__column_int(stmt, 2);
7102 svn_error_t *err;
7103
6687 err = svn_wc__db_resolve_break_moved_away_internal(wcroot,
6688 move_src_relpath,
6689 move_op_depth,
6690 scratch_pool);
7104 err = svn_wc__db_op_break_move_internal(wcroot,
7105 src_relpath, move_op_depth,
7106 dst_relpath, NULL, scratch_pool);
6691 if (err)
6692 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
6693
6694 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6695 }
6696 SVN_ERR(svn_sqlite__reset(stmt));
6697
6698 /* Don't delete BASE nodes */
6699 select_op_depth = op_depth ? op_depth : 1;
6700
6701 /* Reverting any non wc-root node */
6702 SVN_ERR(svn_sqlite__get_statement(
6703 &stmt, wcroot->sdb,
6704 STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE));
6705 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
6706 local_relpath, select_op_depth));
6707 SVN_ERR(svn_sqlite__step_done(stmt));
6708
7107 if (err)
7108 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
7109
7110 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7111 }
7112 SVN_ERR(svn_sqlite__reset(stmt));
7113
7114 /* Don't delete BASE nodes */
7115 select_op_depth = op_depth ? op_depth : 1;
7116
7117 /* Reverting any non wc-root node */
7118 SVN_ERR(svn_sqlite__get_statement(
7119 &stmt, wcroot->sdb,
7120 STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE));
7121 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
7122 local_relpath, select_op_depth));
7123 SVN_ERR(svn_sqlite__step_done(stmt));
7124
6709 SVN_ERR(svn_sqlite__get_statement(
6710 &stmt, wcroot->sdb,
6711 STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
6712 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6713 SVN_ERR(svn_sqlite__step_done(stmt));
7125 if (rvb->clear_changelists)
7126 {
7127 SVN_ERR(svn_sqlite__get_statement(
7128 &stmt, wcroot->sdb,
7129 STMT_DELETE_ACTUAL_NODE_RECURSIVE));
7130 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7131 SVN_ERR(svn_sqlite__step_done(stmt));
7132 }
7133 else
7134 {
7135 SVN_ERR(svn_sqlite__get_statement(
7136 &stmt, wcroot->sdb,
7137 STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
7138 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7139 SVN_ERR(svn_sqlite__step_done(stmt));
6714
7140
6715 SVN_ERR(svn_sqlite__get_statement(
6716 &stmt, wcroot->sdb,
6717 STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
6718 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
6719 SVN_ERR(svn_sqlite__step_done(stmt));
7141 SVN_ERR(svn_sqlite__get_statement(
7142 &stmt, wcroot->sdb,
7143 STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
7144 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
7145 SVN_ERR(svn_sqlite__step_done(stmt));
7146 }
6720
6721 /* ### This removes the locks, but what about the access batons? */
6722 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
6723 STMT_DELETE_WC_LOCK_ORPHAN_RECURSIVE));
6724 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
6725 local_relpath));
6726 SVN_ERR(svn_sqlite__step_done(stmt));
6727

--- 7 unchanged lines hidden (view full) ---

6735 while (have_row)
6736 {
6737 const char *moved_here_child_relpath;
6738 svn_error_t *err;
6739
6740 svn_pool_clear(iterpool);
6741
6742 moved_here_child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
7147
7148 /* ### This removes the locks, but what about the access batons? */
7149 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7150 STMT_DELETE_WC_LOCK_ORPHAN_RECURSIVE));
7151 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
7152 local_relpath));
7153 SVN_ERR(svn_sqlite__step_done(stmt));
7154

--- 7 unchanged lines hidden (view full) ---

7162 while (have_row)
7163 {
7164 const char *moved_here_child_relpath;
7165 svn_error_t *err;
7166
7167 svn_pool_clear(iterpool);
7168
7169 moved_here_child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
6743 err = clear_moved_to(moved_here_child_relpath, wcroot, iterpool);
7170 err = clear_moved_to(wcroot, moved_here_child_relpath, iterpool);
6744 if (err)
6745 return svn_error_trace(svn_error_compose_create(
6746 err,
6747 svn_sqlite__reset(stmt)));
6748
6749 SVN_ERR(svn_sqlite__step(&have_row, stmt));
6750 }
6751 SVN_ERR(svn_sqlite__reset(stmt));
6752 svn_pool_destroy(iterpool);
6753
6754 /* Clear potential moved-to pointing at the target node itself. */
6755 if (op_depth > 0 && op_depth == relpath_depth(local_relpath)
6756 && moved_here)
7171 if (err)
7172 return svn_error_trace(svn_error_compose_create(
7173 err,
7174 svn_sqlite__reset(stmt)));
7175
7176 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7177 }
7178 SVN_ERR(svn_sqlite__reset(stmt));
7179 svn_pool_destroy(iterpool);
7180
7181 /* Clear potential moved-to pointing at the target node itself. */
7182 if (op_depth > 0 && op_depth == relpath_depth(local_relpath)
7183 && moved_here)
6757 SVN_ERR(clear_moved_to(local_relpath, wcroot, scratch_pool));
7184 SVN_ERR(clear_moved_to(wcroot, local_relpath, scratch_pool));
6758
6759 return SVN_NO_ERROR;
6760}
6761
6762svn_error_t *
6763svn_wc__db_op_revert(svn_wc__db_t *db,
6764 const char *local_abspath,
6765 svn_depth_t depth,
7185
7186 return SVN_NO_ERROR;
7187}
7188
7189svn_error_t *
7190svn_wc__db_op_revert(svn_wc__db_t *db,
7191 const char *local_abspath,
7192 svn_depth_t depth,
7193 svn_boolean_t clear_changelists,
6766 apr_pool_t *result_pool,
6767 apr_pool_t *scratch_pool)
6768{
6769 svn_wc__db_wcroot_t *wcroot;
6770 const char *local_relpath;
7194 apr_pool_t *result_pool,
7195 apr_pool_t *scratch_pool)
7196{
7197 svn_wc__db_wcroot_t *wcroot;
7198 const char *local_relpath;
7199 struct revert_baton_t rvb;
6771 struct with_triggers_baton_t wtb = { STMT_CREATE_REVERT_LIST,
6772 STMT_DROP_REVERT_LIST_TRIGGERS,
6773 NULL, NULL};
6774
6775 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
6776
7200 struct with_triggers_baton_t wtb = { STMT_CREATE_REVERT_LIST,
7201 STMT_DROP_REVERT_LIST_TRIGGERS,
7202 NULL, NULL};
7203
7204 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
7205
7206 rvb.db = db;
7207 rvb.clear_changelists = clear_changelists;
7208 wtb.cb_baton = &rvb;
7209
6777 switch (depth)
6778 {
6779 case svn_depth_empty:
6780 wtb.cb_func = op_revert_txn;
7210 switch (depth)
7211 {
7212 case svn_depth_empty:
7213 wtb.cb_func = op_revert_txn;
6781 wtb.cb_baton = db;
6782 break;
6783 case svn_depth_infinity:
6784 wtb.cb_func = op_revert_recursive_txn;
6785 break;
6786 default:
6787 return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
6788 _("Unsupported depth for revert of '%s'"),
6789 svn_dirent_local_style(local_abspath,

--- 119 unchanged lines hidden (view full) ---

6909}
6910
6911
6912/* The body of svn_wc__db_revert_list_read_copied_children().
6913 */
6914static svn_error_t *
6915revert_list_read_copied_children(svn_wc__db_wcroot_t *wcroot,
6916 const char *local_relpath,
7214 break;
7215 case svn_depth_infinity:
7216 wtb.cb_func = op_revert_recursive_txn;
7217 break;
7218 default:
7219 return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
7220 _("Unsupported depth for revert of '%s'"),
7221 svn_dirent_local_style(local_abspath,

--- 119 unchanged lines hidden (view full) ---

7341}
7342
7343
7344/* The body of svn_wc__db_revert_list_read_copied_children().
7345 */
7346static svn_error_t *
7347revert_list_read_copied_children(svn_wc__db_wcroot_t *wcroot,
7348 const char *local_relpath,
6917 const apr_array_header_t **children_p,
7349 apr_array_header_t **children_p,
6918 apr_pool_t *result_pool,
6919 apr_pool_t *scratch_pool)
6920{
6921 svn_sqlite__stmt_t *stmt;
6922 svn_boolean_t have_row;
6923 apr_array_header_t *children;
6924
6925 children =

--- 26 unchanged lines hidden (view full) ---

6952
6953 *children_p = children;
6954
6955 return SVN_NO_ERROR;
6956}
6957
6958
6959svn_error_t *
7350 apr_pool_t *result_pool,
7351 apr_pool_t *scratch_pool)
7352{
7353 svn_sqlite__stmt_t *stmt;
7354 svn_boolean_t have_row;
7355 apr_array_header_t *children;
7356
7357 children =

--- 26 unchanged lines hidden (view full) ---

7384
7385 *children_p = children;
7386
7387 return SVN_NO_ERROR;
7388}
7389
7390
7391svn_error_t *
6960svn_wc__db_revert_list_read_copied_children(const apr_array_header_t **children,
7392svn_wc__db_revert_list_read_copied_children(apr_array_header_t **children,
6961 svn_wc__db_t *db,
6962 const char *local_abspath,
6963 apr_pool_t *result_pool,
6964 apr_pool_t *scratch_pool)
6965{
6966 svn_wc__db_wcroot_t *wcroot;
6967 const char *local_relpath;
6968

--- 30 unchanged lines hidden (view full) ---

6999 STMT_SELECT_REVERT_LIST_RECURSIVE));
7000 SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
7001 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7002 if (!have_row)
7003 return svn_error_trace(svn_sqlite__reset(stmt)); /* optimise for no row */
7004 while (have_row)
7005 {
7006 const char *notify_relpath = svn_sqlite__column_text(stmt, 0, NULL);
7393 svn_wc__db_t *db,
7394 const char *local_abspath,
7395 apr_pool_t *result_pool,
7396 apr_pool_t *scratch_pool)
7397{
7398 svn_wc__db_wcroot_t *wcroot;
7399 const char *local_relpath;
7400

--- 30 unchanged lines hidden (view full) ---

7431 STMT_SELECT_REVERT_LIST_RECURSIVE));
7432 SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
7433 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7434 if (!have_row)
7435 return svn_error_trace(svn_sqlite__reset(stmt)); /* optimise for no row */
7436 while (have_row)
7437 {
7438 const char *notify_relpath = svn_sqlite__column_text(stmt, 0, NULL);
7439 svn_wc_notify_t *notify;
7007
7008 svn_pool_clear(iterpool);
7009
7440
7441 svn_pool_clear(iterpool);
7442
7010 notify_func(notify_baton,
7011 svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
7012 notify_relpath,
7013 iterpool),
7014 svn_wc_notify_revert,
7015 iterpool),
7016 iterpool);
7443 notify = svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
7444 notify_relpath,
7445 iterpool),
7446 svn_wc_notify_revert,
7447 iterpool);
7017
7448
7449 if (!svn_sqlite__column_is_null(stmt, 1))
7450 notify->kind = svn_sqlite__column_token(stmt, 1, kind_map);
7451 else
7452 {
7453 if (!svn_sqlite__column_is_null(stmt, 3))
7454 notify->kind = svn_sqlite__column_token(stmt, 3, kind_map_none);
7455
7456 switch (svn_sqlite__column_int(stmt, 2))
7457 {
7458 case 0:
7459 continue;
7460 case 1:
7461 /* standard revert */
7462 break;
7463 case 2:
7464 notify->action = svn_wc_notify_tree_conflict;
7465 break;
7466 default:
7467 SVN_ERR_MALFUNCTION();
7468 }
7469 }
7470
7471 notify_func(notify_baton, notify, iterpool);
7472
7018 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7019 }
7020 SVN_ERR(svn_sqlite__reset(stmt));
7021
7022 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7023 STMT_DELETE_REVERT_LIST_RECURSIVE));
7024 SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
7025 SVN_ERR(svn_sqlite__step_done(stmt));

--- 24 unchanged lines hidden (view full) ---

7050 */
7051static svn_error_t *
7052remove_node_txn(svn_boolean_t *left_changes,
7053 svn_wc__db_wcroot_t *wcroot,
7054 const char *local_relpath,
7055 svn_wc__db_t *db,
7056 svn_boolean_t destroy_wc,
7057 svn_boolean_t destroy_changes,
7473 SVN_ERR(svn_sqlite__step(&have_row, stmt));
7474 }
7475 SVN_ERR(svn_sqlite__reset(stmt));
7476
7477 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7478 STMT_DELETE_REVERT_LIST_RECURSIVE));
7479 SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
7480 SVN_ERR(svn_sqlite__step_done(stmt));

--- 24 unchanged lines hidden (view full) ---

7505 */
7506static svn_error_t *
7507remove_node_txn(svn_boolean_t *left_changes,
7508 svn_wc__db_wcroot_t *wcroot,
7509 const char *local_relpath,
7510 svn_wc__db_t *db,
7511 svn_boolean_t destroy_wc,
7512 svn_boolean_t destroy_changes,
7058 svn_revnum_t not_present_rev,
7059 svn_wc__db_status_t not_present_status,
7060 svn_node_kind_t not_present_kind,
7061 const svn_skel_t *conflict,
7062 const svn_skel_t *work_items,
7063 svn_cancel_func_t cancel_func,
7064 void *cancel_baton,
7065 apr_pool_t *scratch_pool)
7066{
7067 svn_sqlite__stmt_t *stmt;
7068
7513 const svn_skel_t *conflict,
7514 const svn_skel_t *work_items,
7515 svn_cancel_func_t cancel_func,
7516 void *cancel_baton,
7517 apr_pool_t *scratch_pool)
7518{
7519 svn_sqlite__stmt_t *stmt;
7520
7069 apr_int64_t repos_id;
7070 const char *repos_relpath;
7071
7072 /* Note that unlike many similar functions it is a valid scenario for this
7073 function to be called on a wcroot! */
7074
7075 /* db set when destroying wc */
7076 SVN_ERR_ASSERT(!destroy_wc || db != NULL);
7077
7078 if (left_changes)
7079 *left_changes = FALSE;
7080
7521 /* Note that unlike many similar functions it is a valid scenario for this
7522 function to be called on a wcroot! */
7523
7524 /* db set when destroying wc */
7525 SVN_ERR_ASSERT(!destroy_wc || db != NULL);
7526
7527 if (left_changes)
7528 *left_changes = FALSE;
7529
7081 /* Need info for not_present node? */
7082 if (SVN_IS_VALID_REVNUM(not_present_rev))
7083 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
7084 &repos_relpath, &repos_id,
7085 NULL, NULL, NULL, NULL, NULL,
7086 NULL, NULL, NULL, NULL, NULL,
7087 wcroot, local_relpath,
7088 scratch_pool, scratch_pool));
7089
7090 if (destroy_wc
7091 && (!destroy_changes || *local_relpath == '\0'))
7092 {
7093 svn_boolean_t have_row;
7094 apr_pool_t *iterpool;
7095 svn_error_t *err = NULL;
7096
7097 /* Install WQ items for deleting the unmodified files and all dirs */

--- 180 unchanged lines hidden (view full) ---

7278 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7279 STMT_DELETE_ACTUAL_NODE_RECURSIVE));
7280
7281 /* Delete all actual nodes at or below local_relpath */
7282 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
7283 local_relpath));
7284 SVN_ERR(svn_sqlite__step_done(stmt));
7285
7530 if (destroy_wc
7531 && (!destroy_changes || *local_relpath == '\0'))
7532 {
7533 svn_boolean_t have_row;
7534 apr_pool_t *iterpool;
7535 svn_error_t *err = NULL;
7536
7537 /* Install WQ items for deleting the unmodified files and all dirs */

--- 180 unchanged lines hidden (view full) ---

7718 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7719 STMT_DELETE_ACTUAL_NODE_RECURSIVE));
7720
7721 /* Delete all actual nodes at or below local_relpath */
7722 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
7723 local_relpath));
7724 SVN_ERR(svn_sqlite__step_done(stmt));
7725
7286 /* Should we leave a not-present node? */
7287 if (SVN_IS_VALID_REVNUM(not_present_rev))
7288 {
7289 insert_base_baton_t ibb;
7290 blank_ibb(&ibb);
7291
7292 ibb.repos_id = repos_id;
7293
7294 SVN_ERR_ASSERT(not_present_status == svn_wc__db_status_not_present
7295 || not_present_status == svn_wc__db_status_excluded);
7296
7297 ibb.status = not_present_status;
7298 ibb.kind = not_present_kind;
7299
7300 ibb.repos_relpath = repos_relpath;
7301 ibb.revision = not_present_rev;
7302
7303 SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
7304 }
7305
7306 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
7307 if (conflict)
7308 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
7309 conflict, scratch_pool));
7310
7311 return SVN_NO_ERROR;
7312}
7313
7314svn_error_t *
7315svn_wc__db_op_remove_node(svn_boolean_t *left_changes,
7316 svn_wc__db_t *db,
7317 const char *local_abspath,
7318 svn_boolean_t destroy_wc,
7319 svn_boolean_t destroy_changes,
7726 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
7727 if (conflict)
7728 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
7729 conflict, scratch_pool));
7730
7731 return SVN_NO_ERROR;
7732}
7733
7734svn_error_t *
7735svn_wc__db_op_remove_node(svn_boolean_t *left_changes,
7736 svn_wc__db_t *db,
7737 const char *local_abspath,
7738 svn_boolean_t destroy_wc,
7739 svn_boolean_t destroy_changes,
7320 svn_revnum_t not_present_revision,
7321 svn_wc__db_status_t not_present_status,
7322 svn_node_kind_t not_present_kind,
7323 const svn_skel_t *conflict,
7324 const svn_skel_t *work_items,
7325 svn_cancel_func_t cancel_func,
7326 void *cancel_baton,
7327 apr_pool_t *scratch_pool)
7328{
7329 svn_wc__db_wcroot_t *wcroot;
7330 const char *local_relpath;
7331
7332 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
7333
7334 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
7335 local_abspath, scratch_pool, scratch_pool));
7336 VERIFY_USABLE_WCROOT(wcroot);
7337
7338 SVN_WC__DB_WITH_TXN(remove_node_txn(left_changes,
7339 wcroot, local_relpath, db,
7340 destroy_wc, destroy_changes,
7740 const svn_skel_t *conflict,
7741 const svn_skel_t *work_items,
7742 svn_cancel_func_t cancel_func,
7743 void *cancel_baton,
7744 apr_pool_t *scratch_pool)
7745{
7746 svn_wc__db_wcroot_t *wcroot;
7747 const char *local_relpath;
7748
7749 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
7750
7751 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
7752 local_abspath, scratch_pool, scratch_pool));
7753 VERIFY_USABLE_WCROOT(wcroot);
7754
7755 SVN_WC__DB_WITH_TXN(remove_node_txn(left_changes,
7756 wcroot, local_relpath, db,
7757 destroy_wc, destroy_changes,
7341 not_present_revision, not_present_status,
7342 not_present_kind, conflict, work_items,
7758 conflict, work_items,
7343 cancel_func, cancel_baton, scratch_pool),
7344 wcroot);
7345
7346 /* Flush everything below this node in all ways */
7347 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
7348 scratch_pool));
7349
7350 return SVN_NO_ERROR;

--- 15 unchanged lines hidden (view full) ---

7366 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7367 STMT_UPDATE_NODE_BASE_DEPTH));
7368 SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
7369 svn_token__to_word(depth_map, depth)));
7370 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
7371
7372 if (affected_rows == 0)
7373 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
7759 cancel_func, cancel_baton, scratch_pool),
7760 wcroot);
7761
7762 /* Flush everything below this node in all ways */
7763 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
7764 scratch_pool));
7765
7766 return SVN_NO_ERROR;

--- 15 unchanged lines hidden (view full) ---

7782 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
7783 STMT_UPDATE_NODE_BASE_DEPTH));
7784 SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
7785 svn_token__to_word(depth_map, depth)));
7786 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
7787
7788 if (affected_rows == 0)
7789 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
7374 "The node '%s' is not a committed directory",
7790 _("The node '%s' is not a committed directory"),
7375 path_for_error_message(wcroot, local_relpath,
7376 scratch_pool));
7377
7378 return SVN_NO_ERROR;
7379}
7380
7381
7382svn_error_t *

--- 721 unchanged lines hidden (view full) ---

8104 return SVN_NO_ERROR;
8105}
8106
8107
8108struct op_delete_many_baton_t {
8109 apr_array_header_t *rel_targets;
8110 svn_boolean_t delete_dir_externals;
8111 const svn_skel_t *work_items;
7791 path_for_error_message(wcroot, local_relpath,
7792 scratch_pool));
7793
7794 return SVN_NO_ERROR;
7795}
7796
7797
7798svn_error_t *

--- 721 unchanged lines hidden (view full) ---

8520 return SVN_NO_ERROR;
8521}
8522
8523
8524struct op_delete_many_baton_t {
8525 apr_array_header_t *rel_targets;
8526 svn_boolean_t delete_dir_externals;
8527 const svn_skel_t *work_items;
8112} op_delete_many_baton_t;
8528};
8113
8114static svn_error_t *
8115op_delete_many_txn(void *baton,
8116 svn_wc__db_wcroot_t *wcroot,
8117 const char *local_relpath,
8118 apr_pool_t *scratch_pool)
8119{
8120 struct op_delete_many_baton_t *odmb = baton;

--- 218 unchanged lines hidden (view full) ---

8339 op_delete_many_txn, &odmb,
8340 do_delete_notify, NULL,
8341 cancel_func, cancel_baton,
8342 notify_func, notify_baton,
8343 STMT_FINALIZE_DELETE,
8344 scratch_pool));
8345}
8346
8529
8530static svn_error_t *
8531op_delete_many_txn(void *baton,
8532 svn_wc__db_wcroot_t *wcroot,
8533 const char *local_relpath,
8534 apr_pool_t *scratch_pool)
8535{
8536 struct op_delete_many_baton_t *odmb = baton;

--- 218 unchanged lines hidden (view full) ---

8755 op_delete_many_txn, &odmb,
8756 do_delete_notify, NULL,
8757 cancel_func, cancel_baton,
8758 notify_func, notify_baton,
8759 STMT_FINALIZE_DELETE,
8760 scratch_pool));
8761}
8762
8763/* Helper function for read_info() to provide better diagnostics than just
8764 asserting.
8347
8765
8766 ### BH: Yes this code is ugly, and that is why I only introduce it in
8767 ### read_info(). But we really need something to determine the root cause
8768 ### of this problem to diagnose why TortoiseSVN users were seeing all those
8769 ### assertions.
8770
8771 Adds an error to the *err chain if invalid values are encountered. In that
8772 case the value is set to the first value in the map, assuming that caller
8773 will just return the combined error.
8774 */
8775static int
8776column_token_err(svn_error_t **err,
8777 svn_sqlite__stmt_t *stmt,
8778 int column,
8779 const svn_token_map_t *map)
8780{
8781 svn_error_t *err2;
8782 const char *word = svn_sqlite__column_text(stmt, column, NULL);
8783 int value;
8784
8785 /* svn_token__from_word_err() handles NULL for us */
8786 err2 = svn_token__from_word_err(&value, map, word);
8787
8788 if (err2)
8789 {
8790 *err = svn_error_compose_create(
8791 *err,
8792 svn_error_createf(
8793 SVN_ERR_WC_CORRUPT, err2,
8794 _("Encountered invalid node state in column %d of "
8795 "info query to working copy database"),
8796 column));
8797 value = map[0].val;
8798 }
8799
8800 return value;
8801}
8802
8348/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
8349 DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
8350static svn_error_t *
8351read_info(svn_wc__db_status_t *status,
8352 svn_node_kind_t *kind,
8353 svn_revnum_t *revision,
8354 const char **repos_relpath,
8355 apr_int64_t *repos_id,

--- 50 unchanged lines hidden (view full) ---

8406 }
8407
8408 if (have_info)
8409 {
8410 int op_depth;
8411 svn_node_kind_t node_kind;
8412
8413 op_depth = svn_sqlite__column_int(stmt_info, 0);
8803/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
8804 DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
8805static svn_error_t *
8806read_info(svn_wc__db_status_t *status,
8807 svn_node_kind_t *kind,
8808 svn_revnum_t *revision,
8809 const char **repos_relpath,
8810 apr_int64_t *repos_id,

--- 50 unchanged lines hidden (view full) ---

8861 }
8862
8863 if (have_info)
8864 {
8865 int op_depth;
8866 svn_node_kind_t node_kind;
8867
8868 op_depth = svn_sqlite__column_int(stmt_info, 0);
8414 node_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
8869 node_kind = column_token_err(&err, stmt_info, 4, kind_map);
8415
8416 if (status)
8417 {
8870
8871 if (status)
8872 {
8418 *status = svn_sqlite__column_token(stmt_info, 3, presence_map);
8873 *status = column_token_err(&err, stmt_info, 3, presence_map);
8419
8420 if (op_depth != 0) /* WORKING */
8421 err = svn_error_compose_create(err,
8422 convert_to_working_status(status,
8423 *status));
8424 }
8425 if (kind)
8426 {

--- 35 unchanged lines hidden (view full) ---

8462 }
8463 if (recorded_time)
8464 {
8465 *recorded_time = svn_sqlite__column_int64(stmt_info, 13);
8466 }
8467 if (depth)
8468 {
8469 if (node_kind != svn_node_dir)
8874
8875 if (op_depth != 0) /* WORKING */
8876 err = svn_error_compose_create(err,
8877 convert_to_working_status(status,
8878 *status));
8879 }
8880 if (kind)
8881 {

--- 35 unchanged lines hidden (view full) ---

8917 }
8918 if (recorded_time)
8919 {
8920 *recorded_time = svn_sqlite__column_int64(stmt_info, 13);
8921 }
8922 if (depth)
8923 {
8924 if (node_kind != svn_node_dir)
8470 {
8471 *depth = svn_depth_unknown;
8472 }
8925 *depth = svn_depth_unknown;
8926 else if (svn_sqlite__column_is_null(stmt_info, 11))
8927 *depth = svn_depth_unknown;
8473 else
8928 else
8474 {
8475 *depth = svn_sqlite__column_token_null(stmt_info, 11, depth_map,
8476 svn_depth_unknown);
8477 }
8929 *depth = column_token_err(&err, stmt_info, 11, depth_map);
8478 }
8479 if (checksum)
8480 {
8481 if (node_kind != svn_node_file)
8482 {
8483 *checksum = NULL;
8484 }
8485 else

--- 175 unchanged lines hidden (view full) ---

8661 path_for_error_message(wcroot, local_relpath,
8662 scratch_pool));
8663 }
8664
8665 if (stmt_act != NULL)
8666 err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
8667
8668 if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
8930 }
8931 if (checksum)
8932 {
8933 if (node_kind != svn_node_file)
8934 {
8935 *checksum = NULL;
8936 }
8937 else

--- 175 unchanged lines hidden (view full) ---

9113 path_for_error_message(wcroot, local_relpath,
9114 scratch_pool));
9115 }
9116
9117 if (stmt_act != NULL)
9118 err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
9119
9120 if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
8669 err = svn_error_quick_wrap(err,
8670 apr_psprintf(scratch_pool,
8671 "Error reading node '%s'",
8672 local_relpath));
9121 err = svn_error_quick_wrapf(err, _("Error reading node '%s'"),
9122 local_relpath);
8673
8674 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_info)));
8675
8676 return SVN_NO_ERROR;
8677}
8678
8679
8680svn_error_t *

--- 87 unchanged lines hidden (view full) ---

8768 changed_rev, changed_date, changed_author,
8769 depth, checksum, target, original_repos_relpath,
8770 &original_repos_id, original_revision, lock,
8771 recorded_size, recorded_time, changelist, conflicted,
8772 op_root, have_props, props_mod,
8773 have_base, have_more_work, have_work,
8774 wcroot, local_relpath, result_pool, scratch_pool),
8775 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
9123
9124 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_info)));
9125
9126 return SVN_NO_ERROR;
9127}
9128
9129
9130svn_error_t *

--- 87 unchanged lines hidden (view full) ---

9218 changed_rev, changed_date, changed_author,
9219 depth, checksum, target, original_repos_relpath,
9220 &original_repos_id, original_revision, lock,
9221 recorded_size, recorded_time, changelist, conflicted,
9222 op_root, have_props, props_mod,
9223 have_base, have_more_work, have_work,
9224 wcroot, local_relpath, result_pool, scratch_pool),
9225 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid,
8776 wcroot->sdb, repos_id, result_pool),
9226 wcroot, repos_id, result_pool),
8777 svn_wc__db_fetch_repos_info(original_root_url, original_uuid,
9227 svn_wc__db_fetch_repos_info(original_root_url, original_uuid,
8778 wcroot->sdb, original_repos_id,
9228 wcroot, original_repos_id,
8779 result_pool),
8780 SVN_NO_ERROR,
8781 wcroot);
8782
8783 return SVN_NO_ERROR;
8784}
8785
8786static svn_error_t *
8787is_wclocked(svn_boolean_t *locked,
8788 svn_wc__db_wcroot_t *wcroot,
8789 const char *dir_relpath,
8790 apr_pool_t *scratch_pool);
8791
9229 result_pool),
9230 SVN_NO_ERROR,
9231 wcroot);
9232
9233 return SVN_NO_ERROR;
9234}
9235
9236static svn_error_t *
9237is_wclocked(svn_boolean_t *locked,
9238 svn_wc__db_wcroot_t *wcroot,
9239 const char *dir_relpath,
9240 apr_pool_t *scratch_pool);
9241
9242/* Helper for read_children_info and single variant */
9243static svn_error_t *
9244find_conflict_descendants(svn_boolean_t *conflict_exists,
9245 svn_wc__db_wcroot_t *wcroot,
9246 const char *local_relpath,
9247 apr_pool_t *scratch_pool)
9248{
9249 svn_sqlite__stmt_t *stmt;
9250
9251 /* Only used on files, so certainly not wcroot*/
9252 assert(local_relpath[0] != '\0');
9253
9254 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9255 STMT_FIND_CONFLICT_DESCENDANT));
9256
9257 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
9258 SVN_ERR(svn_sqlite__step(conflict_exists, stmt));
9259
9260 return svn_error_trace(svn_sqlite__reset(stmt));
9261}
9262
8792/* What we really want to store about a node. This relies on the
8793 offset of svn_wc__db_info_t being zero. */
8794struct read_children_info_item_t
8795{
8796 struct svn_wc__db_info_t info;
8797 int op_depth;
8798 int nr_layers;
9263/* What we really want to store about a node. This relies on the
9264 offset of svn_wc__db_info_t being zero. */
9265struct read_children_info_item_t
9266{
9267 struct svn_wc__db_info_t info;
9268 int op_depth;
9269 int nr_layers;
9270 svn_boolean_t was_dir;
8799};
8800
9271};
9272
9273/* Implementation of svn_wc__db_read_children_info */
8801static svn_error_t *
8802read_children_info(svn_wc__db_wcroot_t *wcroot,
8803 const char *dir_relpath,
8804 apr_hash_t *conflicts,
8805 apr_hash_t *nodes,
9274static svn_error_t *
9275read_children_info(svn_wc__db_wcroot_t *wcroot,
9276 const char *dir_relpath,
9277 apr_hash_t *conflicts,
9278 apr_hash_t *nodes,
9279 svn_boolean_t base_tree_only,
8806 apr_pool_t *result_pool,
8807 apr_pool_t *scratch_pool)
8808{
8809 svn_sqlite__stmt_t *stmt;
8810 svn_boolean_t have_row;
8811 const char *repos_root_url = NULL;
8812 const char *repos_uuid = NULL;
8813 apr_int64_t last_repos_id = INVALID_REPOS_ID;
9280 apr_pool_t *result_pool,
9281 apr_pool_t *scratch_pool)
9282{
9283 svn_sqlite__stmt_t *stmt;
9284 svn_boolean_t have_row;
9285 const char *repos_root_url = NULL;
9286 const char *repos_uuid = NULL;
9287 apr_int64_t last_repos_id = INVALID_REPOS_ID;
9288 const char *last_repos_root_url = NULL;
8814
8815 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9289
9290 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
8816 STMT_SELECT_NODE_CHILDREN_INFO));
9291 (base_tree_only
9292 ? STMT_SELECT_BASE_NODE_CHILDREN_INFO
9293 : STMT_SELECT_NODE_CHILDREN_INFO)));
8817 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
8818 SVN_ERR(svn_sqlite__step(&have_row, stmt));
8819
8820 while (have_row)
8821 {
8822 /* CHILD item points to what we have about the node. We only provide
8823 CHILD->item to our caller. */
8824 struct read_children_info_item_t *child_item;
8825 const char *child_relpath = svn_sqlite__column_text(stmt, 19, NULL);
8826 const char *name = svn_relpath_basename(child_relpath, NULL);
8827 svn_error_t *err;
8828 int op_depth;
8829 svn_boolean_t new_child;
8830
9294 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
9295 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9296
9297 while (have_row)
9298 {
9299 /* CHILD item points to what we have about the node. We only provide
9300 CHILD->item to our caller. */
9301 struct read_children_info_item_t *child_item;
9302 const char *child_relpath = svn_sqlite__column_text(stmt, 19, NULL);
9303 const char *name = svn_relpath_basename(child_relpath, NULL);
9304 svn_error_t *err;
9305 int op_depth;
9306 svn_boolean_t new_child;
9307
8831 child_item = svn_hash_gets(nodes, name);
9308 child_item = (base_tree_only ? NULL : svn_hash_gets(nodes, name));
8832 if (child_item)
8833 new_child = FALSE;
8834 else
8835 {
8836 child_item = apr_pcalloc(result_pool, sizeof(*child_item));
8837 new_child = TRUE;
8838 }
8839
8840 op_depth = svn_sqlite__column_int(stmt, 0);
8841
8842 /* Do we have new or better information? */
9309 if (child_item)
9310 new_child = FALSE;
9311 else
9312 {
9313 child_item = apr_pcalloc(result_pool, sizeof(*child_item));
9314 new_child = TRUE;
9315 }
9316
9317 op_depth = svn_sqlite__column_int(stmt, 0);
9318
9319 /* Do we have new or better information? */
8843 if (new_child || op_depth > child_item->op_depth)
9320 if (new_child)
8844 {
8845 struct svn_wc__db_info_t *child = &child_item->info;
8846 child_item->op_depth = op_depth;
8847
8848 child->kind = svn_sqlite__column_token(stmt, 4, kind_map);
8849
8850 child->status = svn_sqlite__column_token(stmt, 3, presence_map);
8851 if (op_depth != 0)

--- 18 unchanged lines hidden (view full) ---

8870
8871 if (op_depth != 0 || svn_sqlite__column_is_null(stmt, 1))
8872 {
8873 child->repos_root_url = NULL;
8874 child->repos_uuid = NULL;
8875 }
8876 else
8877 {
9321 {
9322 struct svn_wc__db_info_t *child = &child_item->info;
9323 child_item->op_depth = op_depth;
9324
9325 child->kind = svn_sqlite__column_token(stmt, 4, kind_map);
9326
9327 child->status = svn_sqlite__column_token(stmt, 3, presence_map);
9328 if (op_depth != 0)

--- 18 unchanged lines hidden (view full) ---

9347
9348 if (op_depth != 0 || svn_sqlite__column_is_null(stmt, 1))
9349 {
9350 child->repos_root_url = NULL;
9351 child->repos_uuid = NULL;
9352 }
9353 else
9354 {
8878 const char *last_repos_root_url = NULL;
8879
8880 apr_int64_t repos_id = svn_sqlite__column_int64(stmt, 1);
8881 if (!repos_root_url ||
8882 (last_repos_id != INVALID_REPOS_ID &&
8883 repos_id != last_repos_id))
8884 {
8885 last_repos_root_url = repos_root_url;
8886 err = svn_wc__db_fetch_repos_info(&repos_root_url,
8887 &repos_uuid,
9355 apr_int64_t repos_id = svn_sqlite__column_int64(stmt, 1);
9356 if (!repos_root_url ||
9357 (last_repos_id != INVALID_REPOS_ID &&
9358 repos_id != last_repos_id))
9359 {
9360 last_repos_root_url = repos_root_url;
9361 err = svn_wc__db_fetch_repos_info(&repos_root_url,
9362 &repos_uuid,
8888 wcroot->sdb, repos_id,
9363 wcroot, repos_id,
8889 result_pool);
8890 if (err)
8891 SVN_ERR(svn_error_compose_create(err,
8892 svn_sqlite__reset(stmt)));
8893 }
8894
8895 if (last_repos_id == INVALID_REPOS_ID)
8896 last_repos_id = repos_id;

--- 21 unchanged lines hidden (view full) ---

8918
8919 child->changed_author = svn_sqlite__column_text(stmt, 10,
8920 result_pool);
8921
8922 if (child->kind != svn_node_dir)
8923 child->depth = svn_depth_unknown;
8924 else
8925 {
9364 result_pool);
9365 if (err)
9366 SVN_ERR(svn_error_compose_create(err,
9367 svn_sqlite__reset(stmt)));
9368 }
9369
9370 if (last_repos_id == INVALID_REPOS_ID)
9371 last_repos_id = repos_id;

--- 21 unchanged lines hidden (view full) ---

9393
9394 child->changed_author = svn_sqlite__column_text(stmt, 10,
9395 result_pool);
9396
9397 if (child->kind != svn_node_dir)
9398 child->depth = svn_depth_unknown;
9399 else
9400 {
9401 child->has_descendants = TRUE;
9402 child_item->was_dir = TRUE;
8926 child->depth = svn_sqlite__column_token_null(stmt, 11, depth_map,
8927 svn_depth_unknown);
8928 if (new_child)
9403 child->depth = svn_sqlite__column_token_null(stmt, 11, depth_map,
9404 svn_depth_unknown);
9405 if (new_child)
8929 SVN_ERR(is_wclocked(&child->locked, wcroot, child_relpath,
8930 scratch_pool));
9406 {
9407 err = is_wclocked(&child->locked, wcroot, child_relpath,
9408 scratch_pool);
9409
9410 if (err)
9411 SVN_ERR(svn_error_compose_create(err,
9412 svn_sqlite__reset(stmt)));
9413 }
8931 }
8932
8933 child->recorded_time = svn_sqlite__column_int64(stmt, 13);
8934 child->recorded_size = get_recorded_size(stmt, 7);
8935 child->has_checksum = !svn_sqlite__column_is_null(stmt, 6);
8936 child->copied = op_depth > 0 && !svn_sqlite__column_is_null(stmt, 2);
8937 child->had_props = SQLITE_PROPERTIES_AVAILABLE(stmt, 14);
8938#ifdef HAVE_SYMLINK

--- 15 unchanged lines hidden (view full) ---

8954 child->op_root = (op_depth == relpath_depth(child_relpath));
8955
8956 if (op_depth && child->op_root)
8957 child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
8958
8959 if (new_child)
8960 svn_hash_sets(nodes, apr_pstrdup(result_pool, name), child);
8961 }
9414 }
9415
9416 child->recorded_time = svn_sqlite__column_int64(stmt, 13);
9417 child->recorded_size = get_recorded_size(stmt, 7);
9418 child->has_checksum = !svn_sqlite__column_is_null(stmt, 6);
9419 child->copied = op_depth > 0 && !svn_sqlite__column_is_null(stmt, 2);
9420 child->had_props = SQLITE_PROPERTIES_AVAILABLE(stmt, 14);
9421#ifdef HAVE_SYMLINK

--- 15 unchanged lines hidden (view full) ---

9437 child->op_root = (op_depth == relpath_depth(child_relpath));
9438
9439 if (op_depth && child->op_root)
9440 child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
9441
9442 if (new_child)
9443 svn_hash_sets(nodes, apr_pstrdup(result_pool, name), child);
9444 }
9445 else if (!child_item->was_dir
9446 && svn_sqlite__column_token(stmt, 4, kind_map) == svn_node_dir)
9447 {
9448 child_item->was_dir = TRUE;
8962
9449
9450 err = find_conflict_descendants(&child_item->info.has_descendants,
9451 wcroot, child_relpath,
9452 scratch_pool);
9453 if (err)
9454 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
9455 }
9456
8963 if (op_depth == 0)
8964 {
8965 child_item->info.have_base = TRUE;
8966
8967 /* Get the lock info, available only at op_depth 0. */
8968 child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
8969 result_pool);
8970

--- 14 unchanged lines hidden (view full) ---

8985 We provide a simple linked list with the moved_from information */
8986
8987 moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
8988 if (moved_to_relpath)
8989 {
8990 struct svn_wc__db_moved_to_info_t *moved_to;
8991 struct svn_wc__db_moved_to_info_t **next;
8992 const char *shadow_op_relpath;
9457 if (op_depth == 0)
9458 {
9459 child_item->info.have_base = TRUE;
9460
9461 /* Get the lock info, available only at op_depth 0. */
9462 child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
9463 result_pool);
9464

--- 14 unchanged lines hidden (view full) ---

9479 We provide a simple linked list with the moved_from information */
9480
9481 moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
9482 if (moved_to_relpath)
9483 {
9484 struct svn_wc__db_moved_to_info_t *moved_to;
9485 struct svn_wc__db_moved_to_info_t **next;
9486 const char *shadow_op_relpath;
8993 int cur_op_depth;
8994
8995 moved_to = apr_pcalloc(result_pool, sizeof(*moved_to));
8996 moved_to->moved_to_abspath = svn_dirent_join(wcroot->abspath,
8997 moved_to_relpath,
8998 result_pool);
8999
9487
9488 moved_to = apr_pcalloc(result_pool, sizeof(*moved_to));
9489 moved_to->moved_to_abspath = svn_dirent_join(wcroot->abspath,
9490 moved_to_relpath,
9491 result_pool);
9492
9000 cur_op_depth = relpath_depth(child_relpath);
9001 shadow_op_relpath = child_relpath;
9493 shadow_op_relpath = svn_relpath_prefix(child_relpath, op_depth,
9494 scratch_pool);
9002
9495
9003 while (cur_op_depth > op_depth)
9004 {
9005 shadow_op_relpath = svn_relpath_dirname(shadow_op_relpath,
9006 scratch_pool);
9007 cur_op_depth--;
9008 }
9009
9010 moved_to->shadow_op_root_abspath =
9011 svn_dirent_join(wcroot->abspath, shadow_op_relpath,
9012 result_pool);
9013
9014 next = &child_item->info.moved_to;
9015
9016 while (*next &&
9017 0 < strcmp((*next)->shadow_op_root_abspath,

--- 5 unchanged lines hidden (view full) ---

9023 }
9024 }
9025
9026 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9027 }
9028
9029 SVN_ERR(svn_sqlite__reset(stmt));
9030
9496 moved_to->shadow_op_root_abspath =
9497 svn_dirent_join(wcroot->abspath, shadow_op_relpath,
9498 result_pool);
9499
9500 next = &child_item->info.moved_to;
9501
9502 while (*next &&
9503 0 < strcmp((*next)->shadow_op_root_abspath,

--- 5 unchanged lines hidden (view full) ---

9509 }
9510 }
9511
9512 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9513 }
9514
9515 SVN_ERR(svn_sqlite__reset(stmt));
9516
9031 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9032 STMT_SELECT_ACTUAL_CHILDREN_INFO));
9033 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
9034 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9035
9036 while (have_row)
9517 if (!base_tree_only)
9037 {
9518 {
9038 struct read_children_info_item_t *child_item;
9039 struct svn_wc__db_info_t *child;
9040 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
9041 const char *name = svn_relpath_basename(child_relpath, NULL);
9519 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9520 STMT_SELECT_ACTUAL_CHILDREN_INFO));
9521 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
9522 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9042
9523
9043 child_item = svn_hash_gets(nodes, name);
9044 if (!child_item)
9524 while (have_row)
9045 {
9525 {
9046 child_item = apr_pcalloc(result_pool, sizeof(*child_item));
9047 child_item->info.status = svn_wc__db_status_not_present;
9048 }
9526 struct read_children_info_item_t *child_item;
9527 struct svn_wc__db_info_t *child;
9528 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
9529 const char *name = svn_relpath_basename(child_relpath, NULL);
9049
9530
9050 child = &child_item->info;
9531 child_item = svn_hash_gets(nodes, name);
9532 if (!child_item)
9533 {
9534 child_item = apr_pcalloc(result_pool, sizeof(*child_item));
9535 child_item->info.status = svn_wc__db_status_not_present;
9536 }
9051
9537
9052 child->changelist = svn_sqlite__column_text(stmt, 1, result_pool);
9538 child = &child_item->info;
9053
9539
9054 child->props_mod = !svn_sqlite__column_is_null(stmt, 2);
9540 child->changelist = svn_sqlite__column_text(stmt, 1, result_pool);
9541
9542 child->props_mod = !svn_sqlite__column_is_null(stmt, 2);
9055#ifdef HAVE_SYMLINK
9543#ifdef HAVE_SYMLINK
9056 if (child->props_mod)
9057 {
9058 svn_error_t *err;
9059 apr_hash_t *properties;
9544 if (child->props_mod)
9545 {
9546 svn_error_t *err;
9547 apr_hash_t *properties;
9060
9548
9061 err = svn_sqlite__column_properties(&properties, stmt, 2,
9062 scratch_pool, scratch_pool);
9063 if (err)
9064 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
9065 child->special = (NULL != svn_hash_gets(properties,
9066 SVN_PROP_SPECIAL));
9067 }
9549 err = svn_sqlite__column_properties(&properties, stmt, 2,
9550 scratch_pool, scratch_pool);
9551 if (err)
9552 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
9553 child->special = (NULL != svn_hash_gets(properties,
9554 SVN_PROP_SPECIAL));
9555 }
9068#endif
9069
9556#endif
9557
9070 child->conflicted = !svn_sqlite__column_is_null(stmt, 3); /* conflict */
9558 /* conflict */
9559 child->conflicted = !svn_sqlite__column_is_null(stmt, 3);
9071
9560
9072 if (child->conflicted)
9073 svn_hash_sets(conflicts, apr_pstrdup(result_pool, name), "");
9561 if (child->conflicted)
9562 svn_hash_sets(conflicts, apr_pstrdup(result_pool, name), "");
9074
9563
9075 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9564 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9565 }
9566
9567 SVN_ERR(svn_sqlite__reset(stmt));
9076 }
9077
9568 }
9569
9078 SVN_ERR(svn_sqlite__reset(stmt));
9079
9080 return SVN_NO_ERROR;
9081}
9082
9083svn_error_t *
9084svn_wc__db_read_children_info(apr_hash_t **nodes,
9085 apr_hash_t **conflicts,
9086 svn_wc__db_t *db,
9087 const char *dir_abspath,
9570 return SVN_NO_ERROR;
9571}
9572
9573svn_error_t *
9574svn_wc__db_read_children_info(apr_hash_t **nodes,
9575 apr_hash_t **conflicts,
9576 svn_wc__db_t *db,
9577 const char *dir_abspath,
9578 svn_boolean_t base_tree_only,
9088 apr_pool_t *result_pool,
9089 apr_pool_t *scratch_pool)
9090{
9091 svn_wc__db_wcroot_t *wcroot;
9092 const char *dir_relpath;
9093
9094 *conflicts = apr_hash_make(result_pool);
9095 *nodes = apr_hash_make(result_pool);
9096 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
9097
9098 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, db,
9099 dir_abspath,
9100 scratch_pool, scratch_pool));
9101 VERIFY_USABLE_WCROOT(wcroot);
9102
9103 SVN_WC__DB_WITH_TXN(
9104 read_children_info(wcroot, dir_relpath, *conflicts, *nodes,
9579 apr_pool_t *result_pool,
9580 apr_pool_t *scratch_pool)
9581{
9582 svn_wc__db_wcroot_t *wcroot;
9583 const char *dir_relpath;
9584
9585 *conflicts = apr_hash_make(result_pool);
9586 *nodes = apr_hash_make(result_pool);
9587 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
9588
9589 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, db,
9590 dir_abspath,
9591 scratch_pool, scratch_pool));
9592 VERIFY_USABLE_WCROOT(wcroot);
9593
9594 SVN_WC__DB_WITH_TXN(
9595 read_children_info(wcroot, dir_relpath, *conflicts, *nodes,
9105 result_pool, scratch_pool),
9596 base_tree_only, result_pool, scratch_pool),
9106 wcroot);
9107
9108 return SVN_NO_ERROR;
9109}
9110
9597 wcroot);
9598
9599 return SVN_NO_ERROR;
9600}
9601
9111static svn_error_t *
9112db_read_props(apr_hash_t **props,
9113 svn_wc__db_wcroot_t *wcroot,
9114 const char *local_relpath,
9115 apr_pool_t *result_pool,
9116 apr_pool_t *scratch_pool);
9602/* Implementation of svn_wc__db_read_single_info.
9117
9603
9604 ### This function is very similar to a lot of code inside
9605 read_children_info, but that performs some tricks to re-use data between
9606 different siblings.
9607
9608 ### We read the same few NODES records a few times via different helper
9609 functions, so this could be optimized bit, but everything is within
9610 a sqlite transaction and all queries are backed by an index, so generally
9611 everything (including the used indexes) should be in the sqlite page cache
9612 after the first query.
9613*/
9118static svn_error_t *
9119read_single_info(const struct svn_wc__db_info_t **info,
9120 svn_wc__db_wcroot_t *wcroot,
9121 const char *local_relpath,
9614static svn_error_t *
9615read_single_info(const struct svn_wc__db_info_t **info,
9616 svn_wc__db_wcroot_t *wcroot,
9617 const char *local_relpath,
9618 svn_boolean_t base_tree_only,
9122 apr_pool_t *result_pool,
9123 apr_pool_t *scratch_pool)
9124{
9125 struct svn_wc__db_info_t *mtb;
9126 apr_int64_t repos_id;
9127 const svn_checksum_t *checksum;
9128 const char *original_repos_relpath;
9129 svn_boolean_t have_work;
9619 apr_pool_t *result_pool,
9620 apr_pool_t *scratch_pool)
9621{
9622 struct svn_wc__db_info_t *mtb;
9623 apr_int64_t repos_id;
9624 const svn_checksum_t *checksum;
9625 const char *original_repos_relpath;
9626 svn_boolean_t have_work;
9627 apr_hash_t *properties;
9130
9131 mtb = apr_pcalloc(result_pool, sizeof(*mtb));
9132
9628
9629 mtb = apr_pcalloc(result_pool, sizeof(*mtb));
9630
9133 SVN_ERR(read_info(&mtb->status, &mtb->kind, &mtb->revnum,
9134 &mtb->repos_relpath, &repos_id, &mtb->changed_rev,
9135 &mtb->changed_date, &mtb->changed_author, &mtb->depth,
9136 &checksum, NULL, &original_repos_relpath, NULL, NULL,
9137 &mtb->lock, &mtb->recorded_size, &mtb->recorded_time,
9138 &mtb->changelist, &mtb->conflicted, &mtb->op_root,
9139 &mtb->had_props, &mtb->props_mod, &mtb->have_base,
9140 &mtb->have_more_work, &have_work,
9141 wcroot, local_relpath,
9142 result_pool, scratch_pool));
9631 if (!base_tree_only)
9632 SVN_ERR(read_info(&mtb->status, &mtb->kind, &mtb->revnum,
9633 &mtb->repos_relpath, &repos_id, &mtb->changed_rev,
9634 &mtb->changed_date, &mtb->changed_author, &mtb->depth,
9635 &checksum, NULL, &original_repos_relpath, NULL, NULL,
9636 &mtb->lock, &mtb->recorded_size, &mtb->recorded_time,
9637 &mtb->changelist, &mtb->conflicted, &mtb->op_root,
9638 &mtb->had_props, &mtb->props_mod, &mtb->have_base,
9639 &mtb->have_more_work, &have_work,
9640 wcroot, local_relpath, result_pool, scratch_pool));
9641 else
9642 {
9643 svn_boolean_t update_root;
9143
9644
9645 have_work = FALSE;
9646 original_repos_relpath = NULL;
9647
9648 SVN_ERR(svn_wc__db_base_get_info_internal(
9649 &mtb->status, &mtb->kind, &mtb->revnum, &mtb->repos_relpath,
9650 &repos_id, &mtb->changed_rev, &mtb->changed_date,
9651 &mtb->changed_author, &mtb->depth, &checksum, NULL,
9652 &mtb->lock, &mtb->had_props, &properties, &update_root,
9653 wcroot, local_relpath, scratch_pool, scratch_pool));
9654
9655 mtb->have_base = TRUE;
9656 mtb->file_external = (update_root && mtb->kind == svn_node_file);
9657 }
9658
9144 /* Query the same rows in the database again for move information */
9145 if (have_work && (mtb->have_base || mtb->have_more_work))
9146 {
9147 svn_sqlite__stmt_t *stmt;
9148 svn_boolean_t have_row;
9659 /* Query the same rows in the database again for move information */
9660 if (have_work && (mtb->have_base || mtb->have_more_work))
9661 {
9662 svn_sqlite__stmt_t *stmt;
9663 svn_boolean_t have_row;
9149 const char *cur_relpath = NULL;
9150 int cur_op_depth;
9151
9152 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9153 STMT_SELECT_MOVED_TO_NODE));
9154 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
9155
9156 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9157
9158 while (have_row)
9159 {
9160 struct svn_wc__db_moved_to_info_t *move;
9161 int op_depth = svn_sqlite__column_int(stmt, 0);
9162 const char *moved_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
9664
9665 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9666 STMT_SELECT_MOVED_TO_NODE));
9667 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
9668
9669 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9670
9671 while (have_row)
9672 {
9673 struct svn_wc__db_moved_to_info_t *move;
9674 int op_depth = svn_sqlite__column_int(stmt, 0);
9675 const char *moved_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
9676 const char *cur_relpath;
9163
9164 move = apr_pcalloc(result_pool, sizeof(*move));
9165 move->moved_to_abspath = svn_dirent_join(wcroot->abspath,
9166 moved_to_relpath,
9167 result_pool);
9168
9677
9678 move = apr_pcalloc(result_pool, sizeof(*move));
9679 move->moved_to_abspath = svn_dirent_join(wcroot->abspath,
9680 moved_to_relpath,
9681 result_pool);
9682
9169 if (!cur_relpath)
9170 {
9171 cur_relpath = local_relpath;
9172 cur_op_depth = relpath_depth(cur_relpath);
9173 }
9174 while (cur_op_depth > op_depth)
9175 {
9176 cur_relpath = svn_relpath_dirname(cur_relpath, scratch_pool);
9177 cur_op_depth--;
9178 }
9683 cur_relpath = svn_relpath_prefix(local_relpath, op_depth,
9684 scratch_pool);
9685
9179 move->shadow_op_root_abspath = svn_dirent_join(wcroot->abspath,
9180 cur_relpath,
9181 result_pool);
9182
9183 move->next = mtb->moved_to;
9184 mtb->moved_to = move;
9185
9186 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9187 }
9188
9189 SVN_ERR(svn_sqlite__reset(stmt));
9190 }
9191
9192 /* Maybe we have to get some shadowed lock from BASE to make our test suite
9193 happy... (It might be completely unrelated, but...)
9194 This queries the same BASE row again, joined to the lock table */
9686 move->shadow_op_root_abspath = svn_dirent_join(wcroot->abspath,
9687 cur_relpath,
9688 result_pool);
9689
9690 move->next = mtb->moved_to;
9691 mtb->moved_to = move;
9692
9693 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9694 }
9695
9696 SVN_ERR(svn_sqlite__reset(stmt));
9697 }
9698
9699 /* Maybe we have to get some shadowed lock from BASE to make our test suite
9700 happy... (It might be completely unrelated, but...)
9701 This queries the same BASE row again, joined to the lock table */
9195 if (mtb->have_base && (have_work || mtb->kind == svn_node_file))
9702 if (!base_tree_only && mtb->have_base
9703 && (have_work || mtb->kind == svn_node_file))
9196 {
9197 svn_boolean_t update_root;
9198 svn_wc__db_lock_t **lock_arg = NULL;
9199
9200 if (have_work)
9201 lock_arg = &mtb->lock;
9202
9203 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, NULL, NULL,

--- 16 unchanged lines hidden (view full) ---

9220 result_pool, scratch_pool));
9221
9222 mtb->moved_here = (status == svn_wc__db_status_moved_here);
9223 mtb->incomplete = (status == svn_wc__db_status_incomplete);
9224 }
9225
9226#ifdef HAVE_SYMLINK
9227 if (mtb->kind == svn_node_file
9704 {
9705 svn_boolean_t update_root;
9706 svn_wc__db_lock_t **lock_arg = NULL;
9707
9708 if (have_work)
9709 lock_arg = &mtb->lock;
9710
9711 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, NULL, NULL,

--- 16 unchanged lines hidden (view full) ---

9728 result_pool, scratch_pool));
9729
9730 mtb->moved_here = (status == svn_wc__db_status_moved_here);
9731 mtb->incomplete = (status == svn_wc__db_status_incomplete);
9732 }
9733
9734#ifdef HAVE_SYMLINK
9735 if (mtb->kind == svn_node_file
9228 && (mtb->had_props || mtb->props_mod))
9736 && (mtb->had_props || mtb->props_mod
9737 || (base_tree_only && properties)))
9229 {
9738 {
9230 apr_hash_t *properties;
9739 if (!base_tree_only)
9740 {
9741 if (mtb->props_mod)
9742 SVN_ERR(svn_wc__db_read_props_internal(&properties,
9743 wcroot, local_relpath,
9744 scratch_pool, scratch_pool));
9745 else
9746 SVN_ERR(db_read_pristine_props(&properties, wcroot, local_relpath,
9747 TRUE /* deleted_ok */,
9748 scratch_pool, scratch_pool));
9749 }
9231
9750
9232 if (mtb->props_mod)
9233 SVN_ERR(db_read_props(&properties,
9234 wcroot, local_relpath,
9235 scratch_pool, scratch_pool));
9236 else
9237 SVN_ERR(db_read_pristine_props(&properties, wcroot, local_relpath,
9238 TRUE /* deleted_ok */,
9239 scratch_pool, scratch_pool));
9240
9241 mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL));
9242 }
9243#endif
9244
9245 mtb->has_checksum = (checksum != NULL);
9246 mtb->copied = (original_repos_relpath != NULL);
9247
9248 SVN_ERR(svn_wc__db_fetch_repos_info(&mtb->repos_root_url, &mtb->repos_uuid,
9751 mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL));
9752 }
9753#endif
9754
9755 mtb->has_checksum = (checksum != NULL);
9756 mtb->copied = (original_repos_relpath != NULL);
9757
9758 SVN_ERR(svn_wc__db_fetch_repos_info(&mtb->repos_root_url, &mtb->repos_uuid,
9249 wcroot->sdb, repos_id, result_pool));
9759 wcroot, repos_id, result_pool));
9250
9760
9251 if (mtb->kind == svn_node_dir)
9761 if (!base_tree_only && mtb->kind == svn_node_dir)
9252 SVN_ERR(is_wclocked(&mtb->locked, wcroot, local_relpath, scratch_pool));
9253
9762 SVN_ERR(is_wclocked(&mtb->locked, wcroot, local_relpath, scratch_pool));
9763
9764 if (mtb->kind == svn_node_dir)
9765 mtb->has_descendants = TRUE;
9766 else
9767 SVN_ERR(find_conflict_descendants(&mtb->has_descendants,
9768 wcroot, local_relpath, scratch_pool));
9769
9254 *info = mtb;
9255
9256 return SVN_NO_ERROR;
9257}
9258
9259svn_error_t *
9260svn_wc__db_read_single_info(const struct svn_wc__db_info_t **info,
9261 svn_wc__db_t *db,
9262 const char *local_abspath,
9770 *info = mtb;
9771
9772 return SVN_NO_ERROR;
9773}
9774
9775svn_error_t *
9776svn_wc__db_read_single_info(const struct svn_wc__db_info_t **info,
9777 svn_wc__db_t *db,
9778 const char *local_abspath,
9779 svn_boolean_t base_tree_only,
9263 apr_pool_t *result_pool,
9264 apr_pool_t *scratch_pool)
9265{
9266 svn_wc__db_wcroot_t *wcroot;
9267 const char *local_relpath;
9268
9269 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
9270
9271 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
9272 local_abspath,
9273 scratch_pool, scratch_pool));
9274 VERIFY_USABLE_WCROOT(wcroot);
9275
9276 SVN_WC__DB_WITH_TXN(read_single_info(info, wcroot, local_relpath,
9780 apr_pool_t *result_pool,
9781 apr_pool_t *scratch_pool)
9782{
9783 svn_wc__db_wcroot_t *wcroot;
9784 const char *local_relpath;
9785
9786 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
9787
9788 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
9789 local_abspath,
9790 scratch_pool, scratch_pool));
9791 VERIFY_USABLE_WCROOT(wcroot);
9792
9793 SVN_WC__DB_WITH_TXN(read_single_info(info, wcroot, local_relpath,
9794 base_tree_only,
9277 result_pool, scratch_pool),
9278 wcroot);
9279
9280 return SVN_NO_ERROR;
9281}
9282
9283svn_error_t *
9284svn_wc__db_read_pristine_info(svn_wc__db_status_t *status,

--- 153 unchanged lines hidden (view full) ---

9438 }
9439
9440 return svn_error_trace(
9441 svn_error_compose_create(err,
9442 svn_sqlite__reset(stmt)));
9443}
9444
9445svn_error_t *
9795 result_pool, scratch_pool),
9796 wcroot);
9797
9798 return SVN_NO_ERROR;
9799}
9800
9801svn_error_t *
9802svn_wc__db_read_pristine_info(svn_wc__db_status_t *status,

--- 153 unchanged lines hidden (view full) ---

9956 }
9957
9958 return svn_error_trace(
9959 svn_error_compose_create(err,
9960 svn_sqlite__reset(stmt)));
9961}
9962
9963svn_error_t *
9446svn_wc__db_read_children_walker_info(apr_hash_t **nodes,
9964svn_wc__db_read_children_walker_info(const apr_array_header_t **items,
9447 svn_wc__db_t *db,
9448 const char *dir_abspath,
9449 apr_pool_t *result_pool,
9450 apr_pool_t *scratch_pool)
9451{
9452 svn_wc__db_wcroot_t *wcroot;
9453 const char *dir_relpath;
9454 svn_sqlite__stmt_t *stmt;
9455 svn_boolean_t have_row;
9965 svn_wc__db_t *db,
9966 const char *dir_abspath,
9967 apr_pool_t *result_pool,
9968 apr_pool_t *scratch_pool)
9969{
9970 svn_wc__db_wcroot_t *wcroot;
9971 const char *dir_relpath;
9972 svn_sqlite__stmt_t *stmt;
9973 svn_boolean_t have_row;
9974 apr_array_header_t *nodes;
9456
9457 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
9458
9459 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, db,
9460 dir_abspath,
9461 scratch_pool, scratch_pool));
9462 VERIFY_USABLE_WCROOT(wcroot);
9463
9464 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9465 STMT_SELECT_NODE_CHILDREN_WALKER_INFO));
9466 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
9467 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9468
9975
9976 SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
9977
9978 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, db,
9979 dir_abspath,
9980 scratch_pool, scratch_pool));
9981 VERIFY_USABLE_WCROOT(wcroot);
9982
9983 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9984 STMT_SELECT_NODE_CHILDREN_WALKER_INFO));
9985 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, dir_relpath));
9986 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9987
9469 *nodes = apr_hash_make(result_pool);
9988 nodes = apr_array_make(result_pool, 16,
9989 sizeof(struct svn_wc__db_walker_info_t *));
9470 while (have_row)
9471 {
9472 struct svn_wc__db_walker_info_t *child;
9473 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
9990 while (have_row)
9991 {
9992 struct svn_wc__db_walker_info_t *child;
9993 const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
9474 const char *name = svn_relpath_basename(child_relpath, NULL);
9994 const char *name = svn_relpath_basename(child_relpath, result_pool);
9475 int op_depth = svn_sqlite__column_int(stmt, 1);
9476 svn_error_t *err;
9477
9478 child = apr_palloc(result_pool, sizeof(*child));
9995 int op_depth = svn_sqlite__column_int(stmt, 1);
9996 svn_error_t *err;
9997
9998 child = apr_palloc(result_pool, sizeof(*child));
9999 child->name = name;
9479 child->status = svn_sqlite__column_token(stmt, 2, presence_map);
9480 if (op_depth > 0)
9481 {
9482 err = convert_to_working_status(&child->status, child->status);
9483 if (err)
9484 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
9485 }
9486 child->kind = svn_sqlite__column_token(stmt, 3, kind_map);
10000 child->status = svn_sqlite__column_token(stmt, 2, presence_map);
10001 if (op_depth > 0)
10002 {
10003 err = convert_to_working_status(&child->status, child->status);
10004 if (err)
10005 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
10006 }
10007 child->kind = svn_sqlite__column_token(stmt, 3, kind_map);
9487 svn_hash_sets(*nodes, apr_pstrdup(result_pool, name), child);
9488
10008
10009 APR_ARRAY_PUSH(nodes, struct svn_wc__db_walker_info_t *) = child;
10010
9489 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9490 }
9491
9492 SVN_ERR(svn_sqlite__reset(stmt));
9493
10011 SVN_ERR(svn_sqlite__step(&have_row, stmt));
10012 }
10013
10014 SVN_ERR(svn_sqlite__reset(stmt));
10015
10016 *items = nodes;
10017
9494 return SVN_NO_ERROR;
9495}
9496
9497svn_error_t *
9498svn_wc__db_read_node_install_info(const char **wcroot_abspath,
9499 const svn_checksum_t **sha1_checksum,
9500 apr_hash_t **pristine_props,
9501 apr_time_t *changed_date,

--- 38 unchanged lines hidden (view full) ---

9540 STMT_SELECT_NODE_INFO));
9541
9542 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
9543
9544 SVN_ERR(svn_sqlite__step(&have_row, stmt));
9545
9546 if (have_row)
9547 {
10018 return SVN_NO_ERROR;
10019}
10020
10021svn_error_t *
10022svn_wc__db_read_node_install_info(const char **wcroot_abspath,
10023 const svn_checksum_t **sha1_checksum,
10024 apr_hash_t **pristine_props,
10025 apr_time_t *changed_date,

--- 38 unchanged lines hidden (view full) ---

10064 STMT_SELECT_NODE_INFO));
10065
10066 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
10067
10068 SVN_ERR(svn_sqlite__step(&have_row, stmt));
10069
10070 if (have_row)
10071 {
9548 if (!err && sha1_checksum)
10072 if (sha1_checksum)
9549 err = svn_sqlite__column_checksum(sha1_checksum, stmt, 6, result_pool);
9550
9551 if (!err && pristine_props)
9552 {
9553 err = svn_sqlite__column_properties(pristine_props, stmt, 14,
9554 result_pool, scratch_pool);
9555 /* Null means no props (assuming presence normal or incomplete). */
9556 if (*pristine_props == NULL)

--- 12 unchanged lines hidden (view full) ---

9569
9570 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
9571
9572 return SVN_NO_ERROR;
9573}
9574
9575
9576
10073 err = svn_sqlite__column_checksum(sha1_checksum, stmt, 6, result_pool);
10074
10075 if (!err && pristine_props)
10076 {
10077 err = svn_sqlite__column_properties(pristine_props, stmt, 14,
10078 result_pool, scratch_pool);
10079 /* Null means no props (assuming presence normal or incomplete). */
10080 if (*pristine_props == NULL)

--- 12 unchanged lines hidden (view full) ---

10093
10094 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
10095
10096 return SVN_NO_ERROR;
10097}
10098
10099
10100
9577/* The body of svn_wc__db_read_url().
10101/* The body of svn_wc__db_read_repos_info().
9578 */
9579static svn_error_t *
10102 */
10103static svn_error_t *
9580read_url_txn(const char **url,
9581 svn_wc__db_wcroot_t *wcroot,
9582 const char *local_relpath,
9583 apr_pool_t *result_pool,
9584 apr_pool_t *scratch_pool)
10104db_read_repos_info(svn_revnum_t *revision,
10105 const char **repos_relpath,
10106 apr_int64_t *repos_id,
10107 svn_wc__db_wcroot_t *wcroot,
10108 const char *local_relpath,
10109 apr_pool_t *result_pool,
10110 apr_pool_t *scratch_pool)
9585{
9586 svn_wc__db_status_t status;
10111{
10112 svn_wc__db_status_t status;
9587 const char *repos_relpath;
9588 const char *repos_root_url;
9589 apr_int64_t repos_id;
9590 svn_boolean_t have_base;
9591
10113
9592 SVN_ERR(read_info(&status, NULL, NULL, &repos_relpath, &repos_id, NULL,
10114 SVN_ERR(read_info(&status, NULL, revision, repos_relpath, repos_id, NULL,
9593 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9594 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
10115 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
10116 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
9595 &have_base, NULL, NULL,
9596 wcroot, local_relpath, scratch_pool, scratch_pool));
10117 NULL, NULL, NULL,
10118 wcroot, local_relpath, result_pool, scratch_pool));
9597
10119
9598 if (repos_relpath == NULL)
10120 if ((repos_relpath && !*repos_relpath)
10121 || (repos_id && *repos_id == INVALID_REPOS_ID))
9599 {
9600 if (status == svn_wc__db_status_added)
9601 {
10122 {
10123 if (status == svn_wc__db_status_added)
10124 {
9602 SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id, NULL,
10125 SVN_ERR(scan_addition(NULL, NULL, repos_relpath, repos_id, NULL,
9603 NULL, NULL, NULL, NULL, NULL,
9604 wcroot, local_relpath,
10126 NULL, NULL, NULL, NULL, NULL,
10127 wcroot, local_relpath,
9605 scratch_pool, scratch_pool));
10128 result_pool, scratch_pool));
9606 }
9607 else if (status == svn_wc__db_status_deleted)
9608 {
9609 const char *base_del_relpath;
9610 const char *work_del_relpath;
9611
10129 }
10130 else if (status == svn_wc__db_status_deleted)
10131 {
10132 const char *base_del_relpath;
10133 const char *work_del_relpath;
10134
9612 SVN_ERR(scan_deletion_txn(&base_del_relpath, NULL,
9613 &work_del_relpath,
9614 NULL, wcroot,
9615 local_relpath,
9616 scratch_pool,
9617 scratch_pool));
10135 SVN_ERR(scan_deletion(&base_del_relpath, NULL,
10136 &work_del_relpath,
10137 NULL, wcroot,
10138 local_relpath,
10139 scratch_pool,
10140 scratch_pool));
9618
10141
9619 if (base_del_relpath)
10142 if (work_del_relpath)
9620 {
10143 {
9621 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
9622 &repos_relpath,
9623 &repos_id,
9624 NULL, NULL, NULL,
9625 NULL, NULL, NULL,
9626 NULL, NULL, NULL, NULL,
9627 wcroot,
9628 base_del_relpath,
9629 scratch_pool,
9630 scratch_pool));
9631
9632 repos_relpath = svn_relpath_join(
9633 repos_relpath,
9634 svn_dirent_skip_ancestor(base_del_relpath,
9635 local_relpath),
9636 scratch_pool);
9637 }
9638 else
9639 {
9640 /* The parent of the WORKING delete, must be an addition */
9641 const char *work_relpath = NULL;
9642
9643 /* work_del_relpath should not be NULL. However, we have
9644 * observed instances where that assumption was not met.
9645 * Bail out in that case instead of crashing with a segfault.
9646 */
9647 SVN_ERR_ASSERT(work_del_relpath != NULL);
9648 work_relpath = svn_relpath_dirname(work_del_relpath,
9649 scratch_pool);
9650
10144 /* The parent of the WORKING delete, must be an addition */
10145 const char *work_relpath = NULL;
10146
10147 /* work_del_relpath should not be NULL. However, we have
10148 * observed instances where that assumption was not met.
10149 * Bail out in that case instead of crashing with a segfault.
10150 */
10151 SVN_ERR_ASSERT(work_del_relpath != NULL);
10152 work_relpath = svn_relpath_dirname(work_del_relpath,
10153 scratch_pool);
10154
9651 SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id,
10155 SVN_ERR(scan_addition(NULL, NULL, repos_relpath, repos_id,
9652 NULL, NULL, NULL, NULL, NULL, NULL,
9653 wcroot, work_relpath,
9654 scratch_pool, scratch_pool));
9655
10156 NULL, NULL, NULL, NULL, NULL, NULL,
10157 wcroot, work_relpath,
10158 scratch_pool, scratch_pool));
10159
9656 repos_relpath = svn_relpath_join(
9657 repos_relpath,
10160 if (repos_relpath)
10161 *repos_relpath = svn_relpath_join(
10162 *repos_relpath,
9658 svn_dirent_skip_ancestor(work_relpath,
9659 local_relpath),
10163 svn_dirent_skip_ancestor(work_relpath,
10164 local_relpath),
9660 scratch_pool);
10165 result_pool);
9661 }
10166 }
10167 else
10168 {
10169 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, revision,
10170 repos_relpath,
10171 repos_id,
10172 NULL, NULL, NULL,
10173 NULL, NULL, NULL,
10174 NULL, NULL, NULL, NULL,
10175 wcroot,
10176 base_del_relpath,
10177 scratch_pool,
10178 scratch_pool));
10179
10180 if (repos_relpath)
10181 *repos_relpath = svn_relpath_join(
10182 *repos_relpath,
10183 svn_dirent_skip_ancestor(base_del_relpath,
10184 local_relpath),
10185 result_pool);
10186 }
9662 }
9663 else if (status == svn_wc__db_status_excluded)
9664 {
9665 const char *parent_relpath;
9666 const char *name;
10187 }
10188 else if (status == svn_wc__db_status_excluded)
10189 {
10190 const char *parent_relpath;
10191 const char *name;
9667 const char *url2;
9668
10192
9669 /* Set 'url' to the *full URL* of the parent WC dir,
9670 * and 'name' to the *single path component* that is the
9671 * basename of this WC directory, so that joining them will result
9672 * in the correct full URL. */
10193 /* A BASE excluded would have had repository information, so
10194 we have a working exclude, which must be below an addition */
10195
9673 svn_relpath_split(&parent_relpath, &name, local_relpath,
9674 scratch_pool);
10196 svn_relpath_split(&parent_relpath, &name, local_relpath,
10197 scratch_pool);
9675 SVN_ERR(read_url_txn(&url2, wcroot, parent_relpath,
9676 scratch_pool, scratch_pool));
10198 SVN_ERR(scan_addition(NULL, NULL, repos_relpath, repos_id, NULL,
10199 NULL, NULL, NULL, NULL, NULL,
10200 wcroot, parent_relpath,
10201 scratch_pool, scratch_pool));
9677
10202
9678 *url = svn_path_url_add_component2(url2, name, result_pool);
10203 if (repos_relpath)
10204 *repos_relpath = svn_relpath_join(*repos_relpath, name,
10205 result_pool);
9679
9680 return SVN_NO_ERROR;
9681 }
9682 else
9683 {
9684 /* All working statee are explicitly handled and all base statee
9685 have a repos_relpath */
9686 SVN_ERR_MALFUNCTION();
9687 }
9688 }
9689
10206
10207 return SVN_NO_ERROR;
10208 }
10209 else
10210 {
10211 /* All working statee are explicitly handled and all base statee
10212 have a repos_relpath */
10213 SVN_ERR_MALFUNCTION();
10214 }
10215 }
10216
9690 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, NULL, wcroot->sdb,
9691 repos_id, scratch_pool));
9692
9693 SVN_ERR_ASSERT(repos_root_url != NULL && repos_relpath != NULL);
9694 *url = svn_path_url_add_component2(repos_root_url, repos_relpath,
9695 result_pool);
9696
9697 return SVN_NO_ERROR;
9698}
9699
9700
9701svn_error_t *
10217 return SVN_NO_ERROR;
10218}
10219
10220
10221svn_error_t *
9702svn_wc__db_read_url(const char **url,
9703 svn_wc__db_t *db,
9704 const char *local_abspath,
9705 apr_pool_t *result_pool,
9706 apr_pool_t *scratch_pool)
10222svn_wc__db_read_repos_info(svn_revnum_t *revision,
10223 const char **repos_relpath,
10224 const char **repos_root_url,
10225 const char **repos_uuid,
10226 svn_wc__db_t *db,
10227 const char *local_abspath,
10228 apr_pool_t *result_pool,
10229 apr_pool_t *scratch_pool)
9707{
9708 svn_wc__db_wcroot_t *wcroot;
9709 const char *local_relpath;
10230{
10231 svn_wc__db_wcroot_t *wcroot;
10232 const char *local_relpath;
10233 apr_int64_t repos_id = INVALID_REPOS_ID;
9710
9711 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
9712
9713 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
9714 local_abspath,
9715 scratch_pool, scratch_pool));
9716 VERIFY_USABLE_WCROOT(wcroot);
9717
10234
10235 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
10236
10237 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
10238 local_abspath,
10239 scratch_pool, scratch_pool));
10240 VERIFY_USABLE_WCROOT(wcroot);
10241
9718 SVN_WC__DB_WITH_TXN(read_url_txn(url, wcroot, local_relpath,
9719 result_pool, scratch_pool),
9720 wcroot);
10242 SVN_WC__DB_WITH_TXN4(db_read_repos_info(revision, repos_relpath,
10243 (repos_root_url || repos_uuid)
10244 ? &repos_id : NULL,
10245 wcroot, local_relpath,
10246 result_pool, scratch_pool),
10247 svn_wc__db_fetch_repos_info(repos_root_url,
10248 repos_uuid,
10249 wcroot, repos_id,
10250 result_pool),
10251 SVN_NO_ERROR, SVN_NO_ERROR,
10252 wcroot);
9721
9722 return SVN_NO_ERROR;
9723}
9724
9725
9726/* Call RECEIVER_FUNC, passing RECEIVER_BATON, an absolute path, and
9727 a hash table mapping <tt>char *</tt> names onto svn_string_t *
9728 values for any properties of immediate or recursive child nodes of

--- 127 unchanged lines hidden (view full) ---

9856 svn_sqlite__exec_statements(wcroot->sdb,
9857 STMT_DROP_TARGET_PROP_CACHE)));
9858 return SVN_NO_ERROR;
9859}
9860
9861
9862/* Helper for svn_wc__db_read_props().
9863 */
10253
10254 return SVN_NO_ERROR;
10255}
10256
10257
10258/* Call RECEIVER_FUNC, passing RECEIVER_BATON, an absolute path, and
10259 a hash table mapping <tt>char *</tt> names onto svn_string_t *
10260 values for any properties of immediate or recursive child nodes of

--- 127 unchanged lines hidden (view full) ---

10388 svn_sqlite__exec_statements(wcroot->sdb,
10389 STMT_DROP_TARGET_PROP_CACHE)));
10390 return SVN_NO_ERROR;
10391}
10392
10393
10394/* Helper for svn_wc__db_read_props().
10395 */
9864static svn_error_t *
9865db_read_props(apr_hash_t **props,
9866 svn_wc__db_wcroot_t *wcroot,
9867 const char *local_relpath,
9868 apr_pool_t *result_pool,
9869 apr_pool_t *scratch_pool)
10396svn_error_t *
10397svn_wc__db_read_props_internal(apr_hash_t **props,
10398 svn_wc__db_wcroot_t *wcroot,
10399 const char *local_relpath,
10400 apr_pool_t *result_pool,
10401 apr_pool_t *scratch_pool)
9870{
9871 svn_sqlite__stmt_t *stmt;
9872 svn_boolean_t have_row;
9873 svn_error_t *err = NULL;
9874
9875 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
9876 STMT_SELECT_ACTUAL_PROPS));
9877 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));

--- 40 unchanged lines hidden (view full) ---

9918 const char *local_relpath;
9919
9920 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
9921
9922 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
9923 local_abspath, scratch_pool, scratch_pool));
9924 VERIFY_USABLE_WCROOT(wcroot);
9925
10402{
10403 svn_sqlite__stmt_t *stmt;
10404 svn_boolean_t have_row;
10405 svn_error_t *err = NULL;
10406
10407 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
10408 STMT_SELECT_ACTUAL_PROPS));
10409 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));

--- 40 unchanged lines hidden (view full) ---

10450 const char *local_relpath;
10451
10452 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
10453
10454 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
10455 local_abspath, scratch_pool, scratch_pool));
10456 VERIFY_USABLE_WCROOT(wcroot);
10457
9926 SVN_WC__DB_WITH_TXN(db_read_props(props, wcroot, local_relpath,
9927 result_pool, scratch_pool),
10458 SVN_WC__DB_WITH_TXN(svn_wc__db_read_props_internal(props, wcroot,
10459 local_relpath,
10460 result_pool,
10461 scratch_pool),
9928 wcroot);
9929
9930 return SVN_NO_ERROR;
9931}
9932
9933
9934static svn_error_t *
9935db_read_pristine_props(apr_hash_t **props,

--- 214 unchanged lines hidden (view full) ---

10150 apr_pool_t *scratch_pool)
10151{
10152 apr_hash_index_t *hi;
10153
10154 for (hi = apr_hash_first(scratch_pool, prop_hash);
10155 hi;
10156 hi = apr_hash_next(hi))
10157 {
10462 wcroot);
10463
10464 return SVN_NO_ERROR;
10465}
10466
10467
10468static svn_error_t *
10469db_read_pristine_props(apr_hash_t **props,

--- 214 unchanged lines hidden (view full) ---

10684 apr_pool_t *scratch_pool)
10685{
10686 apr_hash_index_t *hi;
10687
10688 for (hi = apr_hash_first(scratch_pool, prop_hash);
10689 hi;
10690 hi = apr_hash_next(hi))
10691 {
10158 const char *ipropname = svn__apr_hash_index_key(hi);
10692 const char *ipropname = apr_hash_this_key(hi);
10159
10160 if (strcmp(ipropname, propname) != 0)
10161 svn_hash_sets(prop_hash, ipropname, NULL);
10162 }
10163 return;
10164}
10165
10166/* Get the changed properties as stored in the ACTUAL table */

--- 157 unchanged lines hidden (view full) ---

10324 apr_pcalloc(result_pool,
10325 sizeof(svn_prop_inherited_item_t));
10326 iprop_elt->path_or_url = svn_dirent_join(wcroot->abspath,
10327 relpath,
10328 result_pool);
10329
10330 iprop_elt->prop_hash = node_props;
10331 /* Build the output array in depth-first order. */
10693
10694 if (strcmp(ipropname, propname) != 0)
10695 svn_hash_sets(prop_hash, ipropname, NULL);
10696 }
10697 return;
10698}
10699
10700/* Get the changed properties as stored in the ACTUAL table */

--- 157 unchanged lines hidden (view full) ---

10858 apr_pcalloc(result_pool,
10859 sizeof(svn_prop_inherited_item_t));
10860 iprop_elt->path_or_url = svn_dirent_join(wcroot->abspath,
10861 relpath,
10862 result_pool);
10863
10864 iprop_elt->prop_hash = node_props;
10865 /* Build the output array in depth-first order. */
10332 svn_sort__array_insert(&iprop_elt, iprops, 0);
10866 svn_sort__array_insert(iprops, &iprop_elt, 0);
10333 }
10334 }
10335 }
10336 else if (actual_props)
10337 {
10338 apr_hash_t *changed_props;
10339
10340 SVN_ERR(db_get_changed_props(&changed_props, wcroot, relpath,

--- 19 unchanged lines hidden (view full) ---

10360 continue;
10361
10362 if (propname)
10363 filter_unwanted_props(cached_iprop->prop_hash, propname,
10364 scratch_pool);
10365
10366 /* If we didn't filter everything then keep this iprop. */
10367 if (apr_hash_count(cached_iprop->prop_hash))
10867 }
10868 }
10869 }
10870 else if (actual_props)
10871 {
10872 apr_hash_t *changed_props;
10873
10874 SVN_ERR(db_get_changed_props(&changed_props, wcroot, relpath,

--- 19 unchanged lines hidden (view full) ---

10894 continue;
10895
10896 if (propname)
10897 filter_unwanted_props(cached_iprop->prop_hash, propname,
10898 scratch_pool);
10899
10900 /* If we didn't filter everything then keep this iprop. */
10901 if (apr_hash_count(cached_iprop->prop_hash))
10368 svn_sort__array_insert(&cached_iprop, iprops, 0);
10902 svn_sort__array_insert(iprops, &cached_iprop, 0);
10369 }
10370 }
10371
10372 if (actual_props && !*actual_props)
10373 *actual_props = apr_hash_make(result_pool);
10374
10375 svn_pool_destroy(iterpool);
10376 return SVN_NO_ERROR;

--- 97 unchanged lines hidden (view full) ---

10474 {
10475 apr_hash_index_t *hi;
10476 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
10477
10478 for (hi = apr_hash_first(scratch_pool, *iprop_paths);
10479 hi;
10480 hi = apr_hash_next(hi))
10481 {
10903 }
10904 }
10905
10906 if (actual_props && !*actual_props)
10907 *actual_props = apr_hash_make(result_pool);
10908
10909 svn_pool_destroy(iterpool);
10910 return SVN_NO_ERROR;

--- 97 unchanged lines hidden (view full) ---

11008 {
11009 apr_hash_index_t *hi;
11010 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
11011
11012 for (hi = apr_hash_first(scratch_pool, *iprop_paths);
11013 hi;
11014 hi = apr_hash_next(hi))
11015 {
10482 const char *child_abspath = svn__apr_hash_index_key(hi);
11016 const char *child_abspath = apr_hash_this_key(hi);
10483 const char *child_relpath;
10484 svn_node_kind_t child_kind;
10485
10486 svn_pool_clear(iterpool);
10487
10488 child_relpath = svn_dirent_is_child(local_relpath, child_abspath,
10489 NULL);
10490

--- 61 unchanged lines hidden (view full) ---

10552
10553 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
10554
10555 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
10556 local_abspath,
10557 scratch_pool, scratch_pool));
10558 VERIFY_USABLE_WCROOT(wcroot);
10559
11017 const char *child_relpath;
11018 svn_node_kind_t child_kind;
11019
11020 svn_pool_clear(iterpool);
11021
11022 child_relpath = svn_dirent_is_child(local_relpath, child_abspath,
11023 NULL);
11024

--- 61 unchanged lines hidden (view full) ---

11086
11087 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11088
11089 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11090 local_abspath,
11091 scratch_pool, scratch_pool));
11092 VERIFY_USABLE_WCROOT(wcroot);
11093
10560 return gather_children2(children, wcroot, local_relpath,
10561 result_pool, scratch_pool);
11094 return svn_error_trace(
11095 gather_children(children, wcroot, local_relpath,
11096 STMT_SELECT_WORKING_CHILDREN, -1,
11097 result_pool, scratch_pool));
10562}
10563
11098}
11099
11100svn_error_t *
11101svn_wc__db_base_read_not_present_children(
11102 const apr_array_header_t **children,
11103 svn_wc__db_t *db,
11104 const char *local_abspath,
11105 apr_pool_t *result_pool,
11106 apr_pool_t *scratch_pool)
11107{
11108 svn_wc__db_wcroot_t *wcroot;
11109 const char *local_relpath;
11110
11111 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11112
11113 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11114 local_abspath,
11115 scratch_pool, scratch_pool));
11116 VERIFY_USABLE_WCROOT(wcroot);
11117
11118 return svn_error_trace(
11119 gather_children(children, wcroot, local_relpath,
11120 STMT_SELECT_BASE_NOT_PRESENT_CHILDREN, -1,
11121 result_pool, scratch_pool));
11122}
11123
10564/* Helper for svn_wc__db_node_check_replace().
10565 */
10566static svn_error_t *
10567check_replace_txn(svn_boolean_t *is_replace_root_p,
10568 svn_boolean_t *base_replace_p,
10569 svn_boolean_t *is_replace_p,
10570 svn_wc__db_wcroot_t *wcroot,
10571 const char *local_relpath,

--- 168 unchanged lines hidden (view full) ---

10740 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
10741
10742 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
10743 local_abspath,
10744 scratch_pool, scratch_pool));
10745 VERIFY_USABLE_WCROOT(wcroot);
10746
10747 return gather_children(children, wcroot, local_relpath,
11124/* Helper for svn_wc__db_node_check_replace().
11125 */
11126static svn_error_t *
11127check_replace_txn(svn_boolean_t *is_replace_root_p,
11128 svn_boolean_t *base_replace_p,
11129 svn_boolean_t *is_replace_p,
11130 svn_wc__db_wcroot_t *wcroot,
11131 const char *local_relpath,

--- 168 unchanged lines hidden (view full) ---

11300 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11301
11302 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11303 local_abspath,
11304 scratch_pool, scratch_pool));
11305 VERIFY_USABLE_WCROOT(wcroot);
11306
11307 return gather_children(children, wcroot, local_relpath,
11308 STMT_SELECT_NODE_CHILDREN, -1,
10748 result_pool, scratch_pool);
10749}
10750
10751
11309 result_pool, scratch_pool);
11310}
11311
11312
10752/* */
11313/* Implementation of svn_wc__db_global_relocate */
10753static svn_error_t *
10754relocate_txn(svn_wc__db_wcroot_t *wcroot,
10755 const char *local_relpath,
10756 const char *repos_root_url,
11314static svn_error_t *
11315relocate_txn(svn_wc__db_wcroot_t *wcroot,
11316 const char *local_relpath,
11317 const char *repos_root_url,
10757 const char *repos_uuid,
10758 svn_boolean_t have_base_node,
10759 apr_int64_t old_repos_id,
10760 apr_pool_t *scratch_pool)
10761{
10762 svn_sqlite__stmt_t *stmt;
10763 apr_int64_t new_repos_id;
11318 apr_pool_t *scratch_pool)
11319{
11320 svn_sqlite__stmt_t *stmt;
11321 apr_int64_t new_repos_id;
10764
10765 /* This function affects all the children of the given local_relpath,
10766 but the way that it does this is through the repos inheritance mechanism.
10767 So, we only need to rewrite the repos_id of the given local_relpath,
10768 as well as any children with a non-null repos_id, as well as various
10769 repos_id fields in the locks and working_node tables.
10770 */
10771
10772 /* Get the repos_id for the new repository. */
10773 SVN_ERR(create_repos_id(&new_repos_id, repos_root_url, repos_uuid,
10774 wcroot->sdb, scratch_pool));
10775
10776 /* Set the (base and working) repos_ids and clear the dav_caches */
10777 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
10778 STMT_RECURSIVE_UPDATE_NODE_REPO));
10779 SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
10780 old_repos_id, new_repos_id));
10781 SVN_ERR(svn_sqlite__step_done(stmt));
10782
10783 if (have_base_node)
10784 {
10785 /* Update any locks for the root or its children. */
10786 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
10787 STMT_UPDATE_LOCK_REPOS_ID));
10788 SVN_ERR(svn_sqlite__bindf(stmt, "ii", old_repos_id, new_repos_id));
10789 SVN_ERR(svn_sqlite__step_done(stmt));
10790 }
10791
10792 return SVN_NO_ERROR;
10793}
10794
10795
10796svn_error_t *
10797svn_wc__db_global_relocate(svn_wc__db_t *db,
10798 const char *local_dir_abspath,
10799 const char *repos_root_url,
10800 apr_pool_t *scratch_pool)
10801{
10802 svn_wc__db_wcroot_t *wcroot;
10803 const char *local_relpath;
10804 const char *local_dir_relpath;
10805 svn_wc__db_status_t status;
10806 const char *repos_uuid;
10807 svn_boolean_t have_base_node;
10808 apr_int64_t old_repos_id;
10809
11322 const char *local_dir_relpath;
11323 svn_wc__db_status_t status;
11324 const char *repos_uuid;
11325 svn_boolean_t have_base_node;
11326 apr_int64_t old_repos_id;
11327
10810 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
10811 /* ### assert that we were passed a directory? */
11328 local_dir_relpath = local_relpath;
10812
11329
10813 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_dir_relpath,
10814 db, local_dir_abspath, scratch_pool, scratch_pool));
10815 VERIFY_USABLE_WCROOT(wcroot);
10816 local_relpath = local_dir_relpath;
10817
10818 SVN_ERR(read_info(&status,
10819 NULL, NULL, NULL, &old_repos_id,
10820 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
10821 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
10822 NULL,
10823 &have_base_node, NULL, NULL,
10824 wcroot, local_relpath,
10825 scratch_pool, scratch_pool));

--- 21 unchanged lines hidden (view full) ---

10847 added/deleted/excluded without relocating the parent? If not
10848 then perhaps relpath, root_url and uuid should be passed down
10849 to the children so that they don't have to scan? */
10850
10851 if (status == svn_wc__db_status_deleted)
10852 {
10853 const char *work_del_relpath;
10854
11330 SVN_ERR(read_info(&status,
11331 NULL, NULL, NULL, &old_repos_id,
11332 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11333 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
11334 NULL,
11335 &have_base_node, NULL, NULL,
11336 wcroot, local_relpath,
11337 scratch_pool, scratch_pool));

--- 21 unchanged lines hidden (view full) ---

11359 added/deleted/excluded without relocating the parent? If not
11360 then perhaps relpath, root_url and uuid should be passed down
11361 to the children so that they don't have to scan? */
11362
11363 if (status == svn_wc__db_status_deleted)
11364 {
11365 const char *work_del_relpath;
11366
10855 SVN_ERR(scan_deletion_txn(NULL, NULL,
10856 &work_del_relpath, NULL,
10857 wcroot, local_dir_relpath,
10858 scratch_pool,
10859 scratch_pool));
11367 SVN_ERR(scan_deletion(NULL, NULL,
11368 &work_del_relpath, NULL,
11369 wcroot, local_dir_relpath,
11370 scratch_pool,
11371 scratch_pool));
10860 if (work_del_relpath)
10861 {
10862 /* Deleted within a copy/move */
10863
10864 /* The parent of the delete is added. */
10865 status = svn_wc__db_status_added;
10866 local_dir_relpath = svn_relpath_dirname(work_del_relpath,
10867 scratch_pool);

--- 11 unchanged lines hidden (view full) ---

10879 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, NULL,
10880 &old_repos_id,
10881 NULL, NULL, NULL, NULL, NULL,
10882 NULL, NULL, NULL, NULL, NULL,
10883 wcroot, local_dir_relpath,
10884 scratch_pool, scratch_pool));
10885 }
10886
11372 if (work_del_relpath)
11373 {
11374 /* Deleted within a copy/move */
11375
11376 /* The parent of the delete is added. */
11377 status = svn_wc__db_status_added;
11378 local_dir_relpath = svn_relpath_dirname(work_del_relpath,
11379 scratch_pool);

--- 11 unchanged lines hidden (view full) ---

11391 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, NULL,
11392 &old_repos_id,
11393 NULL, NULL, NULL, NULL, NULL,
11394 NULL, NULL, NULL, NULL, NULL,
11395 wcroot, local_dir_relpath,
11396 scratch_pool, scratch_pool));
11397 }
11398
10887 SVN_ERR(svn_wc__db_fetch_repos_info(NULL, &repos_uuid, wcroot->sdb,
11399 SVN_ERR(svn_wc__db_fetch_repos_info(NULL, &repos_uuid, wcroot,
10888 old_repos_id, scratch_pool));
11400 old_repos_id, scratch_pool));
10889 SVN_ERR_ASSERT(repos_uuid);
11401 SVN_ERR_ASSERT(repos_uuid); /* This function affects all the children of the given local_relpath,
11402 but the way that it does this is through the repos inheritance mechanism.
11403 So, we only need to rewrite the repos_id of the given local_relpath,
11404 as well as any children with a non-null repos_id, as well as various
11405 repos_id fields in the locks and working_node tables.
11406 */
10890
11407
11408 /* Get the repos_id for the new repository. */
11409 SVN_ERR(create_repos_id(&new_repos_id, repos_root_url, repos_uuid,
11410 wcroot->sdb, scratch_pool));
11411
11412 /* Set the (base and working) repos_ids and clear the dav_caches */
11413 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11414 STMT_RECURSIVE_UPDATE_NODE_REPO));
11415 SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
11416 old_repos_id, new_repos_id));
11417 SVN_ERR(svn_sqlite__step_done(stmt));
11418
11419 if (have_base_node)
11420 {
11421 /* Update any locks for the root or its children. */
11422 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11423 STMT_UPDATE_LOCK_REPOS_ID));
11424 SVN_ERR(svn_sqlite__bindf(stmt, "ii", old_repos_id, new_repos_id));
11425 SVN_ERR(svn_sqlite__step_done(stmt));
11426 }
11427
11428 return SVN_NO_ERROR;
11429}
11430
11431
11432svn_error_t *
11433svn_wc__db_global_relocate(svn_wc__db_t *db,
11434 const char *local_dir_abspath,
11435 const char *repos_root_url,
11436 apr_pool_t *scratch_pool)
11437{
11438 svn_wc__db_wcroot_t *wcroot;
11439 const char *local_relpath;
11440
11441 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
11442 /* ### assert that we were passed a directory? */
11443
11444 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
11445 db, local_dir_abspath, scratch_pool, scratch_pool));
11446 VERIFY_USABLE_WCROOT(wcroot);
11447
10891 SVN_WC__DB_WITH_TXN(
11448 SVN_WC__DB_WITH_TXN(
10892 relocate_txn(wcroot, local_relpath, repos_root_url, repos_uuid,
10893 have_base_node, old_repos_id, scratch_pool),
11449 relocate_txn(wcroot, local_relpath, repos_root_url, scratch_pool),
10894 wcroot);
10895
11450 wcroot);
11451
11452 SVN_ERR(flush_entries(wcroot, local_dir_abspath, svn_depth_infinity,
11453 scratch_pool));
11454
10896 return SVN_NO_ERROR;
10897}
10898
10899
10900/* Helper for commit_node()
10901 Set *REPOS_ID and *REPOS_RELPATH to the BASE repository location of
10902 (WCROOT, LOCAL_RELPATH), directly if its BASE row exists or implied from
10903 its parent's BASE row if not. In the latter case, error if the parent

--- 70 unchanged lines hidden (view full) ---

10974 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 2));
10975
10976 *repos_id = svn_sqlite__column_int64(stmt, 1);
10977 *repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
10978
10979 return svn_error_trace(svn_sqlite__reset(stmt));
10980}
10981
11455 return SVN_NO_ERROR;
11456}
11457
11458
11459/* Helper for commit_node()
11460 Set *REPOS_ID and *REPOS_RELPATH to the BASE repository location of
11461 (WCROOT, LOCAL_RELPATH), directly if its BASE row exists or implied from
11462 its parent's BASE row if not. In the latter case, error if the parent

--- 70 unchanged lines hidden (view full) ---

11533 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 2));
11534
11535 *repos_id = svn_sqlite__column_int64(stmt, 1);
11536 *repos_relpath = svn_sqlite__column_text(stmt, 2, result_pool);
11537
11538 return svn_error_trace(svn_sqlite__reset(stmt));
11539}
11540
11541static svn_error_t *
11542moved_descendant_collect(apr_hash_t **map,
11543 svn_wc__db_wcroot_t *wcroot,
11544 const char *local_relpath,
11545 int op_depth,
11546 apr_pool_t *result_pool,
11547 apr_pool_t *scratch_pool)
11548{
11549 svn_sqlite__stmt_t *stmt;
11550 svn_boolean_t have_row;
11551
11552 *map = NULL;
11553
11554 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11555 STMT_SELECT_MOVED_DESCENDANTS_SRC));
11556 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
11557 local_relpath,
11558 op_depth));
11559
11560 SVN_ERR(svn_sqlite__step(&have_row, stmt));
11561 if (! have_row)
11562 return svn_error_trace(svn_sqlite__reset(stmt));
11563
11564 /* Find all moved descendants. Key them on target, because that is
11565 always unique */
11566 while (have_row)
11567 {
11568 const char *src_relpath = svn_sqlite__column_text(stmt, 1, result_pool);
11569 const char *to_relpath = svn_sqlite__column_text(stmt, 4, result_pool);
11570
11571 if (!*map)
11572 *map = apr_hash_make(result_pool);
11573
11574 svn_hash_sets(*map, to_relpath, src_relpath);
11575
11576 SVN_ERR(svn_sqlite__step(&have_row, stmt));
11577 }
11578 SVN_ERR(svn_sqlite__reset(stmt));
11579
11580 return SVN_NO_ERROR;
11581}
11582
10982/* Helper for svn_wc__db_global_commit()
10983
10984 Makes local_relpath and all its descendants at the same op-depth represent
10985 the copy origin repos_id:repos_relpath@revision.
10986
10987 This code is only valid to fix-up a move from an old location, to a new
10988 location during a commit.
10989
10990 Assumptions:
10991 * local_relpath is not the working copy root (can't be moved)
10992 * repos_relpath is not the repository root (can't be moved)
11583/* Helper for svn_wc__db_global_commit()
11584
11585 Makes local_relpath and all its descendants at the same op-depth represent
11586 the copy origin repos_id:repos_relpath@revision.
11587
11588 This code is only valid to fix-up a move from an old location, to a new
11589 location during a commit.
11590
11591 Assumptions:
11592 * local_relpath is not the working copy root (can't be moved)
11593 * repos_relpath is not the repository root (can't be moved)
10993 */
11594 */
10994static svn_error_t *
10995moved_descendant_commit(svn_wc__db_wcroot_t *wcroot,
10996 const char *local_relpath,
11595static svn_error_t *
11596moved_descendant_commit(svn_wc__db_wcroot_t *wcroot,
11597 const char *local_relpath,
10997 int op_depth,
10998 apr_int64_t repos_id,
10999 const char *repos_relpath,
11000 svn_revnum_t revision,
11598 apr_int64_t repos_id,
11599 const char *repos_relpath,
11600 svn_revnum_t revision,
11601 apr_hash_t *children,
11001 apr_pool_t *scratch_pool)
11002{
11602 apr_pool_t *scratch_pool)
11603{
11003 apr_hash_t *children;
11004 apr_pool_t *iterpool;
11005 svn_sqlite__stmt_t *stmt;
11604 apr_pool_t *iterpool;
11605 svn_sqlite__stmt_t *stmt;
11006 svn_boolean_t have_row;
11007 apr_hash_index_t *hi;
11008
11009 SVN_ERR_ASSERT(*local_relpath != '\0'
11010 && *repos_relpath != '\0');
11011
11606 apr_hash_index_t *hi;
11607
11608 SVN_ERR_ASSERT(*local_relpath != '\0'
11609 && *repos_relpath != '\0');
11610
11012 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11013 STMT_SELECT_MOVED_DESCENDANTS));
11014 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
11015 local_relpath,
11016 op_depth));
11611 if (!children)
11612 return SVN_NO_ERROR;
11017
11613
11018 SVN_ERR(svn_sqlite__step(&have_row, stmt));
11019 if (! have_row)
11020 return svn_error_trace(svn_sqlite__reset(stmt));
11021
11022 children = apr_hash_make(scratch_pool);
11023
11024 /* First, obtain all moved children */
11025 /* To keep error handling simple, first cache them in a hashtable */
11026 while (have_row)
11027 {
11028 const char *src_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
11029 const char *to_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
11030
11031 svn_hash_sets(children, src_relpath, to_relpath);
11032
11033 SVN_ERR(svn_sqlite__step(&have_row, stmt));
11034 }
11035 SVN_ERR(svn_sqlite__reset(stmt));
11036
11037 /* Then update them */
11038 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11039 STMT_COMMIT_UPDATE_ORIGIN));
11040
11041 iterpool = svn_pool_create(scratch_pool);
11042 for (hi = apr_hash_first(scratch_pool, children); hi; hi = apr_hash_next(hi))
11043 {
11614 /* Then update them */
11615 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11616 STMT_COMMIT_UPDATE_ORIGIN));
11617
11618 iterpool = svn_pool_create(scratch_pool);
11619 for (hi = apr_hash_first(scratch_pool, children); hi; hi = apr_hash_next(hi))
11620 {
11044 const char *src_relpath = svn__apr_hash_index_key(hi);
11045 const char *to_relpath = svn__apr_hash_index_val(hi);
11621 const char *src_relpath = apr_hash_this_val(hi);
11622 const char *to_relpath = apr_hash_this_key(hi);
11046 const char *new_repos_relpath;
11047 int to_op_depth = relpath_depth(to_relpath);
11048 int affected;
11623 const char *new_repos_relpath;
11624 int to_op_depth = relpath_depth(to_relpath);
11625 int affected;
11626 apr_hash_t *map;
11049
11050 svn_pool_clear(iterpool);
11051
11052 SVN_ERR_ASSERT(to_op_depth > 0);
11053
11054 new_repos_relpath = svn_relpath_join(
11055 repos_relpath,
11056 svn_relpath_skip_ancestor(local_relpath,

--- 10 unchanged lines hidden (view full) ---

11067
11068#ifdef SVN_DEBUG
11069 /* Enable in release code?
11070 Broken moves are not fatal yet, but this assertion would break
11071 committing them */
11072 SVN_ERR_ASSERT(affected >= 1); /* If this fails there is no move dest */
11073#endif
11074
11627
11628 svn_pool_clear(iterpool);
11629
11630 SVN_ERR_ASSERT(to_op_depth > 0);
11631
11632 new_repos_relpath = svn_relpath_join(
11633 repos_relpath,
11634 svn_relpath_skip_ancestor(local_relpath,

--- 10 unchanged lines hidden (view full) ---

11645
11646#ifdef SVN_DEBUG
11647 /* Enable in release code?
11648 Broken moves are not fatal yet, but this assertion would break
11649 committing them */
11650 SVN_ERR_ASSERT(affected >= 1); /* If this fails there is no move dest */
11651#endif
11652
11075 SVN_ERR(moved_descendant_commit(wcroot, to_relpath, to_op_depth,
11653 SVN_ERR(moved_descendant_collect(&map, wcroot, to_relpath, to_op_depth,
11654 iterpool, iterpool));
11655 SVN_ERR(moved_descendant_commit(wcroot, to_relpath,
11076 repos_id, new_repos_relpath, revision,
11656 repos_id, new_repos_relpath, revision,
11077 iterpool));
11657 map, iterpool));
11078 }
11079
11080 svn_pool_destroy(iterpool);
11081 return SVN_NO_ERROR;
11082}
11083
11084/* Helper for svn_wc__db_global_commit()
11085

--- 42 unchanged lines hidden (view full) ---

11128static svn_error_t *
11129commit_node(svn_wc__db_wcroot_t *wcroot,
11130 const char *local_relpath,
11131 svn_revnum_t new_revision,
11132 svn_revnum_t changed_rev,
11133 apr_time_t changed_date,
11134 const char *changed_author,
11135 const svn_checksum_t *new_checksum,
11658 }
11659
11660 svn_pool_destroy(iterpool);
11661 return SVN_NO_ERROR;
11662}
11663
11664/* Helper for svn_wc__db_global_commit()
11665

--- 42 unchanged lines hidden (view full) ---

11708static svn_error_t *
11709commit_node(svn_wc__db_wcroot_t *wcroot,
11710 const char *local_relpath,
11711 svn_revnum_t new_revision,
11712 svn_revnum_t changed_rev,
11713 apr_time_t changed_date,
11714 const char *changed_author,
11715 const svn_checksum_t *new_checksum,
11136 const apr_array_header_t *new_children,
11137 apr_hash_t *new_dav_cache,
11138 svn_boolean_t keep_changelist,
11139 svn_boolean_t no_unlock,
11140 const svn_skel_t *work_items,
11141 apr_pool_t *scratch_pool)
11142{
11143 svn_sqlite__stmt_t *stmt_info;
11144 svn_sqlite__stmt_t *stmt_act;

--- 5 unchanged lines hidden (view full) ---

11150 svn_wc__db_status_t new_presence;
11151 svn_node_kind_t new_kind;
11152 const char *new_depth_str = NULL;
11153 svn_sqlite__stmt_t *stmt;
11154 apr_int64_t repos_id;
11155 const char *repos_relpath;
11156 int op_depth;
11157 svn_wc__db_status_t old_presence;
11716 apr_hash_t *new_dav_cache,
11717 svn_boolean_t keep_changelist,
11718 svn_boolean_t no_unlock,
11719 const svn_skel_t *work_items,
11720 apr_pool_t *scratch_pool)
11721{
11722 svn_sqlite__stmt_t *stmt_info;
11723 svn_sqlite__stmt_t *stmt_act;

--- 5 unchanged lines hidden (view full) ---

11729 svn_wc__db_status_t new_presence;
11730 svn_node_kind_t new_kind;
11731 const char *new_depth_str = NULL;
11732 svn_sqlite__stmt_t *stmt;
11733 apr_int64_t repos_id;
11734 const char *repos_relpath;
11735 int op_depth;
11736 svn_wc__db_status_t old_presence;
11737 svn_boolean_t moved_here;
11158
11159 /* If we are adding a file or directory, then we need to get
11160 repository information from the parent node since "this node" does
11161 not have a BASE).
11162
11163 For existing nodes, we should retain the (potentially-switched)
11164 repository information. */
11165 SVN_ERR(determine_commit_repos_info(&repos_id, &repos_relpath,

--- 13 unchanged lines hidden (view full) ---

11179 SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
11180
11181 /* There should be something to commit! */
11182
11183 op_depth = svn_sqlite__column_int(stmt_info, 0);
11184
11185 /* Figure out the new node's kind. It will be whatever is in WORKING_NODE,
11186 or there will be a BASE_NODE that has it. */
11738
11739 /* If we are adding a file or directory, then we need to get
11740 repository information from the parent node since "this node" does
11741 not have a BASE).
11742
11743 For existing nodes, we should retain the (potentially-switched)
11744 repository information. */
11745 SVN_ERR(determine_commit_repos_info(&repos_id, &repos_relpath,

--- 13 unchanged lines hidden (view full) ---

11759 SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
11760
11761 /* There should be something to commit! */
11762
11763 op_depth = svn_sqlite__column_int(stmt_info, 0);
11764
11765 /* Figure out the new node's kind. It will be whatever is in WORKING_NODE,
11766 or there will be a BASE_NODE that has it. */
11767 old_presence = svn_sqlite__column_token(stmt_info, 3, presence_map);
11187 new_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
11188
11189 /* What will the new depth be? */
11190 if (new_kind == svn_node_dir)
11191 new_depth_str = svn_sqlite__column_text(stmt_info, 11, scratch_pool);
11192
11193 /* Check that the repository information is not being changed. */
11194 if (op_depth == 0)
11195 {
11196 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt_info, 1));
11197 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt_info, 2));
11198
11199 /* A commit cannot change these values. */
11200 SVN_ERR_ASSERT(repos_id == svn_sqlite__column_int64(stmt_info, 1));
11201 SVN_ERR_ASSERT(strcmp(repos_relpath,
11202 svn_sqlite__column_text(stmt_info, 2, NULL)) == 0);
11203 }
11204
11768 new_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
11769
11770 /* What will the new depth be? */
11771 if (new_kind == svn_node_dir)
11772 new_depth_str = svn_sqlite__column_text(stmt_info, 11, scratch_pool);
11773
11774 /* Check that the repository information is not being changed. */
11775 if (op_depth == 0)
11776 {
11777 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt_info, 1));
11778 SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt_info, 2));
11779
11780 /* A commit cannot change these values. */
11781 SVN_ERR_ASSERT(repos_id == svn_sqlite__column_int64(stmt_info, 1));
11782 SVN_ERR_ASSERT(strcmp(repos_relpath,
11783 svn_sqlite__column_text(stmt_info, 2, NULL)) == 0);
11784 }
11785
11205 /* Find the appropriate new properties -- ACTUAL overrides any properties
11206 in WORKING that arrived as part of a copy/move.
11786 if (old_presence != svn_wc__db_status_base_deleted)
11787 {
11788 /* Find the appropriate new properties -- ACTUAL overrides any properties
11789 in WORKING that arrived as part of a copy/move.
11207
11790
11208 Note: we'll keep them as a big blob of data, rather than
11209 deserialize/serialize them. */
11210 if (have_act)
11211 prop_blob.data = svn_sqlite__column_blob(stmt_act, 1, &prop_blob.len,
11212 scratch_pool);
11213 if (prop_blob.data == NULL)
11214 prop_blob.data = svn_sqlite__column_blob(stmt_info, 14, &prop_blob.len,
11215 scratch_pool);
11791 Note: we'll keep them as a big blob of data, rather than
11792 deserialize/serialize them. */
11793 if (have_act)
11794 prop_blob.data = svn_sqlite__column_blob(stmt_act, 1, &prop_blob.len,
11795 scratch_pool);
11796 if (prop_blob.data == NULL)
11797 prop_blob.data = svn_sqlite__column_blob(stmt_info, 14, &prop_blob.len,
11798 scratch_pool);
11216
11799
11217 inherited_prop_blob.data = svn_sqlite__column_blob(stmt_info, 16,
11218 &inherited_prop_blob.len,
11219 scratch_pool);
11800 inherited_prop_blob.data = svn_sqlite__column_blob(
11801 stmt_info, 16,
11802 &inherited_prop_blob.len,
11803 scratch_pool);
11220
11804
11221 if (keep_changelist && have_act)
11222 changelist = svn_sqlite__column_text(stmt_act, 0, scratch_pool);
11805 if (keep_changelist && have_act)
11806 changelist = svn_sqlite__column_text(stmt_act, 0, scratch_pool);
11223
11807
11224 old_presence = svn_sqlite__column_token(stmt_info, 3, presence_map);
11808 moved_here = svn_sqlite__column_int(stmt_info, 15);
11809 }
11810 else
11811 {
11812 moved_here = FALSE;
11813 changelist = NULL;
11814 }
11225
11226 /* ### other stuff? */
11227
11228 SVN_ERR(svn_sqlite__reset(stmt_info));
11229 SVN_ERR(svn_sqlite__reset(stmt_act));
11230
11231 if (op_depth > 0)
11232 {
11233 int affected_rows;
11234
11815
11816 /* ### other stuff? */
11817
11818 SVN_ERR(svn_sqlite__reset(stmt_info));
11819 SVN_ERR(svn_sqlite__reset(stmt_act));
11820
11821 if (op_depth > 0)
11822 {
11823 int affected_rows;
11824
11825 SVN_ERR_ASSERT(op_depth == relpath_depth(local_relpath));
11826
11827 /* First clear the moves that we are going to delete in a bit */
11828 {
11829 apr_hash_t *old_moves;
11830 apr_hash_index_t *hi;
11831 SVN_ERR(moved_descendant_collect(&old_moves, wcroot, local_relpath, 0,
11832 scratch_pool, scratch_pool));
11833
11834 if (old_moves)
11835 for (hi = apr_hash_first(scratch_pool, old_moves);
11836 hi; hi = apr_hash_next(hi))
11837 {
11838 SVN_ERR(clear_moved_here(wcroot, apr_hash_this_key(hi),
11839 scratch_pool));
11840 }
11841 }
11842
11235 /* This removes all layers of this node and at the same time determines
11236 if we need to remove shadowed layers below our descendants. */
11237
11238 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11239 STMT_DELETE_NODE_ALL_LAYERS));
11240 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
11241 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
11242

--- 16 unchanged lines hidden (view full) ---

11259
11260 SVN_ERR(svn_sqlite__step_done(stmt));
11261 }
11262
11263 /* Note that while these two calls look so similar that they might
11264 be integrated, they really affect a different op-depth and
11265 completely different nodes (via a different recursion pattern). */
11266
11843 /* This removes all layers of this node and at the same time determines
11844 if we need to remove shadowed layers below our descendants. */
11845
11846 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11847 STMT_DELETE_NODE_ALL_LAYERS));
11848 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
11849 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
11850

--- 16 unchanged lines hidden (view full) ---

11867
11868 SVN_ERR(svn_sqlite__step_done(stmt));
11869 }
11870
11871 /* Note that while these two calls look so similar that they might
11872 be integrated, they really affect a different op-depth and
11873 completely different nodes (via a different recursion pattern). */
11874
11267 /* Collapse descendants of the current op_depth in layer 0 */
11268 SVN_ERR(descendant_commit(wcroot, local_relpath, op_depth,
11269 repos_id, repos_relpath, new_revision,
11270 scratch_pool));
11875 if (old_presence != svn_wc__db_status_base_deleted)
11876 {
11877 /* Collapse descendants of the current op_depth to layer 0,
11878 this includes moved-from/to clearing */
11879 SVN_ERR(descendant_commit(wcroot, local_relpath, op_depth,
11880 repos_id, repos_relpath, new_revision,
11881 scratch_pool));
11882 }
11271
11883
11272 /* And make the recorded local moves represent moves of the node we just
11273 committed. */
11274 SVN_ERR(moved_descendant_commit(wcroot, local_relpath, 0,
11884 if (old_presence != svn_wc__db_status_base_deleted)
11885 {
11886 apr_hash_t *moves = NULL;
11887
11888 SVN_ERR(moved_descendant_collect(&moves, wcroot, local_relpath, 0,
11889 scratch_pool, scratch_pool));
11890
11891 /* And make the recorded local moves represent moves of the node we
11892 just committed. */
11893 SVN_ERR(moved_descendant_commit(wcroot, local_relpath,
11275 repos_id, repos_relpath, new_revision,
11894 repos_id, repos_relpath, new_revision,
11276 scratch_pool));
11895 moves, scratch_pool));
11896 }
11277
11897
11278 /* This node is no longer modified, so no node was moved here */
11279 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11280 STMT_CLEAR_MOVED_TO_FROM_DEST));
11281 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
11282 local_relpath));
11898 if (moved_here)
11899 {
11900 /* This node is no longer modified, so no node was moved here */
11901 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11902 STMT_CLEAR_MOVED_TO_FROM_DEST));
11903 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
11904 local_relpath));
11283
11905
11284 SVN_ERR(svn_sqlite__step_done(stmt));
11906 SVN_ERR(svn_sqlite__step_done(stmt));
11907 }
11285 }
11908 }
11286
11287 /* Update or add the BASE_NODE row with all the new information. */
11288
11289 if (*local_relpath == '\0')
11290 parent_relpath = NULL;
11291 else
11292 parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
11293
11294 /* Preserve any incomplete status */
11909 /* Update or add the BASE_NODE row with all the new information. */
11910
11911 if (*local_relpath == '\0')
11912 parent_relpath = NULL;
11913 else
11914 parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
11915
11916 /* Preserve any incomplete status */
11295 new_presence = (old_presence == svn_wc__db_status_incomplete
11296 ? svn_wc__db_status_incomplete
11297 : svn_wc__db_status_normal);
11917 if (old_presence != svn_wc__db_status_base_deleted)
11918 {
11919 new_presence = (old_presence == svn_wc__db_status_incomplete
11920 ? svn_wc__db_status_incomplete
11921 : svn_wc__db_status_normal);
11298
11922
11299 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11300 STMT_APPLY_CHANGES_TO_BASE_NODE));
11301 /* symlink_target not yet used */
11302 SVN_ERR(svn_sqlite__bindf(stmt, "issisrtstrisnbn",
11303 wcroot->wc_id, local_relpath,
11304 parent_relpath,
11305 repos_id,
11306 repos_relpath,
11307 new_revision,
11308 presence_map, new_presence,
11309 new_depth_str,
11310 kind_map, new_kind,
11311 changed_rev,
11312 changed_date,
11313 changed_author,
11314 prop_blob.data, prop_blob.len));
11923 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11924 STMT_APPLY_CHANGES_TO_BASE_NODE));
11925 /* symlink_target not yet used */
11926 SVN_ERR(svn_sqlite__bindf(stmt, "issisrtstrisnbn",
11927 wcroot->wc_id, local_relpath,
11928 parent_relpath,
11929 repos_id,
11930 repos_relpath,
11931 new_revision,
11932 presence_map, new_presence,
11933 new_depth_str,
11934 kind_map, new_kind,
11935 changed_rev,
11936 changed_date,
11937 changed_author,
11938 prop_blob.data, prop_blob.len));
11315
11939
11316 SVN_ERR(svn_sqlite__bind_checksum(stmt, 13, new_checksum,
11317 scratch_pool));
11318 SVN_ERR(svn_sqlite__bind_properties(stmt, 15, new_dav_cache,
11319 scratch_pool));
11320 if (inherited_prop_blob.data != NULL)
11321 {
11322 SVN_ERR(svn_sqlite__bind_blob(stmt, 17, inherited_prop_blob.data,
11323 inherited_prop_blob.len));
11940 SVN_ERR(svn_sqlite__bind_checksum(stmt, 13, new_checksum,
11941 scratch_pool));
11942 SVN_ERR(svn_sqlite__bind_properties(stmt, 15, new_dav_cache,
11943 scratch_pool));
11944 if (inherited_prop_blob.data != NULL)
11945 {
11946 SVN_ERR(svn_sqlite__bind_blob(stmt, 17, inherited_prop_blob.data,
11947 inherited_prop_blob.len));
11948 }
11949
11950 SVN_ERR(svn_sqlite__step_done(stmt));
11324 }
11951 }
11952 else
11953 {
11954 struct insert_base_baton_t ibb;
11955 blank_ibb(&ibb);
11325
11956
11326 SVN_ERR(svn_sqlite__step_done(stmt));
11957 ibb.repos_id = repos_id;
11958 ibb.status = svn_wc__db_status_not_present;
11959 ibb.kind = new_kind;
11960 ibb.repos_relpath = repos_relpath;
11961 ibb.revision = new_revision;
11327
11962
11963 SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
11964
11965 keep_changelist = FALSE; /* Nothing there */
11966 }
11967
11328 if (have_act)
11329 {
11330 if (keep_changelist && changelist != NULL)
11331 {
11332 /* The user told us to keep the changelist. Replace the row in
11333 ACTUAL_NODE with the basic keys and the changelist. */
11334 SVN_ERR(svn_sqlite__get_statement(
11335 &stmt, wcroot->sdb,

--- 10 unchanged lines hidden (view full) ---

11346 /* Toss the ACTUAL_NODE row. */
11347 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11348 STMT_DELETE_ACTUAL_NODE));
11349 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
11350 SVN_ERR(svn_sqlite__step_done(stmt));
11351 }
11352 }
11353
11968 if (have_act)
11969 {
11970 if (keep_changelist && changelist != NULL)
11971 {
11972 /* The user told us to keep the changelist. Replace the row in
11973 ACTUAL_NODE with the basic keys and the changelist. */
11974 SVN_ERR(svn_sqlite__get_statement(
11975 &stmt, wcroot->sdb,

--- 10 unchanged lines hidden (view full) ---

11986 /* Toss the ACTUAL_NODE row. */
11987 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11988 STMT_DELETE_ACTUAL_NODE));
11989 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
11990 SVN_ERR(svn_sqlite__step_done(stmt));
11991 }
11992 }
11993
11354 if (new_kind == svn_node_dir)
11355 {
11356 /* When committing a directory, we should have its new children. */
11357 /* ### one day. just not today. */
11358#if 0
11359 SVN_ERR_ASSERT(new_children != NULL);
11360#endif
11361
11362 /* ### process the children */
11363 }
11364
11365 if (!no_unlock)
11366 {
11367 svn_sqlite__stmt_t *lock_stmt;
11994 if (!no_unlock)
11995 {
11996 svn_sqlite__stmt_t *lock_stmt;
11997 svn_boolean_t op_root = (op_depth > 0
11998 && (relpath_depth(local_relpath) == op_depth));
11368
11999
12000 /* If we are committing an add of a delete, we can assume we own
12001 all locks at or below REPOS_RELPATH (or the server would have
12002 denied the commit). As we must have passed these to the server
12003 we can now safely remove them.
12004 */
11369 SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
12005 SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
11370 STMT_DELETE_LOCK_RECURSIVELY));
12006 op_root
12007 ? STMT_DELETE_LOCK_RECURSIVELY
12008 : STMT_DELETE_LOCK));
11371 SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
11372 SVN_ERR(svn_sqlite__step_done(lock_stmt));
11373 }
11374
11375 /* Install any work items into the queue, as part of this transaction. */
11376 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
11377
11378 return SVN_NO_ERROR;
11379}
11380
11381
11382svn_error_t *
11383svn_wc__db_global_commit(svn_wc__db_t *db,
11384 const char *local_abspath,
11385 svn_revnum_t new_revision,
11386 svn_revnum_t changed_revision,
11387 apr_time_t changed_date,
11388 const char *changed_author,
11389 const svn_checksum_t *new_checksum,
12009 SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
12010 SVN_ERR(svn_sqlite__step_done(lock_stmt));
12011 }
12012
12013 /* Install any work items into the queue, as part of this transaction. */
12014 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
12015
12016 return SVN_NO_ERROR;
12017}
12018
12019
12020svn_error_t *
12021svn_wc__db_global_commit(svn_wc__db_t *db,
12022 const char *local_abspath,
12023 svn_revnum_t new_revision,
12024 svn_revnum_t changed_revision,
12025 apr_time_t changed_date,
12026 const char *changed_author,
12027 const svn_checksum_t *new_checksum,
11390 const apr_array_header_t *new_children,
11391 apr_hash_t *new_dav_cache,
11392 svn_boolean_t keep_changelist,
11393 svn_boolean_t no_unlock,
11394 const svn_skel_t *work_items,
11395 apr_pool_t *scratch_pool)
11396{
11397 const char *local_relpath;
11398 svn_wc__db_wcroot_t *wcroot;
11399
11400 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11401 SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(new_revision));
12028 apr_hash_t *new_dav_cache,
12029 svn_boolean_t keep_changelist,
12030 svn_boolean_t no_unlock,
12031 const svn_skel_t *work_items,
12032 apr_pool_t *scratch_pool)
12033{
12034 const char *local_relpath;
12035 svn_wc__db_wcroot_t *wcroot;
12036
12037 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12038 SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(new_revision));
11402 SVN_ERR_ASSERT(new_checksum == NULL || new_children == NULL);
11403
11404 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11405 local_abspath, scratch_pool, scratch_pool));
11406 VERIFY_USABLE_WCROOT(wcroot);
11407
11408 SVN_WC__DB_WITH_TXN(
11409 commit_node(wcroot, local_relpath,
11410 new_revision, changed_revision, changed_date, changed_author,
12039
12040 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12041 local_abspath, scratch_pool, scratch_pool));
12042 VERIFY_USABLE_WCROOT(wcroot);
12043
12044 SVN_WC__DB_WITH_TXN(
12045 commit_node(wcroot, local_relpath,
12046 new_revision, changed_revision, changed_date, changed_author,
11411 new_checksum, new_children, new_dav_cache, keep_changelist,
12047 new_checksum, new_dav_cache, keep_changelist,
11412 no_unlock, work_items, scratch_pool),
11413 wcroot);
11414
11415 /* We *totally* monkeyed the entries. Toss 'em. */
11416 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
11417
11418 return SVN_NO_ERROR;
11419}

--- 118 unchanged lines hidden (view full) ---

11538}
11539
11540/* The main body of bump_revisions_post_update().
11541 *
11542 * Tweak the information for LOCAL_RELPATH in WCROOT. If NEW_REPOS_RELPATH is
11543 * non-NULL update the entry to the new url specified by NEW_REPOS_RELPATH,
11544 * NEW_REPOS_ID. If NEW_REV is valid, make this the node's working revision.
11545 *
12048 no_unlock, work_items, scratch_pool),
12049 wcroot);
12050
12051 /* We *totally* monkeyed the entries. Toss 'em. */
12052 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
12053
12054 return SVN_NO_ERROR;
12055}

--- 118 unchanged lines hidden (view full) ---

12174}
12175
12176/* The main body of bump_revisions_post_update().
12177 *
12178 * Tweak the information for LOCAL_RELPATH in WCROOT. If NEW_REPOS_RELPATH is
12179 * non-NULL update the entry to the new url specified by NEW_REPOS_RELPATH,
12180 * NEW_REPOS_ID. If NEW_REV is valid, make this the node's working revision.
12181 *
12182 * NODE_STATUS, NODE_KIND, NODE_REVISION and NODE_REPOS_RELPATH represent the
12183 * values as stored currently in WCROOT for LOCAL_RELPATH.
12184 *
11546 * If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
11547 * working copy paths to depth-first ordered arrays of
11548 * svn_prop_inherited_item_t * structures. If the absolute path equivalent
11549 * of LOCAL_RELPATH exists in WCROOT_IPROPS, then set the hashed value as the
11550 * node's inherited properties.
11551 *
11552 * Unless S_ROOT is TRUE the tweaks might cause the node for LOCAL_ABSPATH to
11553 * be removed from the WC; if IS_ROOT is TRUE this will not happen.
11554 */
11555static svn_error_t *
11556bump_node_revision(svn_wc__db_wcroot_t *wcroot,
11557 const char *local_relpath,
12185 * If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
12186 * working copy paths to depth-first ordered arrays of
12187 * svn_prop_inherited_item_t * structures. If the absolute path equivalent
12188 * of LOCAL_RELPATH exists in WCROOT_IPROPS, then set the hashed value as the
12189 * node's inherited properties.
12190 *
12191 * Unless S_ROOT is TRUE the tweaks might cause the node for LOCAL_ABSPATH to
12192 * be removed from the WC; if IS_ROOT is TRUE this will not happen.
12193 */
12194static svn_error_t *
12195bump_node_revision(svn_wc__db_wcroot_t *wcroot,
12196 const char *local_relpath,
12197 svn_wc__db_status_t node_status,
12198 svn_node_kind_t node_kind,
12199 svn_revnum_t node_revision,
12200 const char *node_repos_relpath,
11558 apr_int64_t new_repos_id,
11559 const char *new_repos_relpath,
11560 svn_revnum_t new_rev,
11561 svn_depth_t depth,
11562 apr_hash_t *exclude_relpaths,
11563 apr_hash_t *wcroot_iprops,
11564 svn_boolean_t is_root,
11565 svn_boolean_t skip_when_dir,
11566 svn_wc__db_t *db,
11567 apr_pool_t *scratch_pool)
11568{
11569 apr_pool_t *iterpool;
12201 apr_int64_t new_repos_id,
12202 const char *new_repos_relpath,
12203 svn_revnum_t new_rev,
12204 svn_depth_t depth,
12205 apr_hash_t *exclude_relpaths,
12206 apr_hash_t *wcroot_iprops,
12207 svn_boolean_t is_root,
12208 svn_boolean_t skip_when_dir,
12209 svn_wc__db_t *db,
12210 apr_pool_t *scratch_pool)
12211{
12212 apr_pool_t *iterpool;
11570 const apr_array_header_t *children;
11571 int i;
11572 svn_wc__db_status_t status;
11573 svn_node_kind_t db_kind;
11574 svn_revnum_t revision;
11575 const char *repos_relpath;
11576 apr_int64_t repos_id;
12213 apr_hash_t *children;
12214 apr_hash_index_t *hi;
11577 svn_boolean_t set_repos_relpath = FALSE;
12215 svn_boolean_t set_repos_relpath = FALSE;
11578 svn_boolean_t update_root;
11579 svn_depth_t depth_below_here = depth;
11580 apr_array_header_t *iprops = NULL;
11581
12216 svn_depth_t depth_below_here = depth;
12217 apr_array_header_t *iprops = NULL;
12218
11582 /* Skip an excluded path and its descendants. */
11583 if (svn_hash_gets(exclude_relpaths, local_relpath))
11584 return SVN_NO_ERROR;
11585
11586 SVN_ERR(svn_wc__db_base_get_info_internal(&status, &db_kind, &revision,
11587 &repos_relpath, &repos_id,
11588 NULL, NULL, NULL, NULL, NULL,
11589 NULL, NULL, NULL, NULL, &update_root,
11590 wcroot, local_relpath,
11591 scratch_pool, scratch_pool));
11592
11593 /* Skip file externals */
11594 if (update_root
11595 && db_kind == svn_node_file
11596 && !is_root)
11597 return SVN_NO_ERROR;
11598
11599 if (skip_when_dir && db_kind == svn_node_dir)
11600 return SVN_NO_ERROR;
11601
11602 /* If the node is still marked 'not-present', then the server did not
11603 re-add it. So it's really gone in this revision, thus we remove the node.
11604
11605 If the node is still marked 'server-excluded' and yet is not the same
11606 revision as new_rev, then the server did not re-add it, nor
11607 re-server-exclude it, so we can remove the node. */
11608 if (!is_root
11609 && (status == svn_wc__db_status_not_present
11610 || (status == svn_wc__db_status_server_excluded &&
11611 revision != new_rev)))
11612 {
11613 return svn_error_trace(db_base_remove(wcroot, local_relpath,
11614 db, FALSE, FALSE, FALSE,
11615 SVN_INVALID_REVNUM,
11616 NULL, NULL, scratch_pool));
11617 }
11618
11619 if (new_repos_relpath != NULL && strcmp(repos_relpath, new_repos_relpath))
12219 if (new_repos_relpath != NULL
12220 && strcmp(node_repos_relpath, new_repos_relpath))
11620 set_repos_relpath = TRUE;
11621
11622 if (wcroot_iprops)
11623 iprops = svn_hash_gets(wcroot_iprops,
11624 svn_dirent_join(wcroot->abspath, local_relpath,
11625 scratch_pool));
11626
11627 if (iprops
11628 || set_repos_relpath
12221 set_repos_relpath = TRUE;
12222
12223 if (wcroot_iprops)
12224 iprops = svn_hash_gets(wcroot_iprops,
12225 svn_dirent_join(wcroot->abspath, local_relpath,
12226 scratch_pool));
12227
12228 if (iprops
12229 || set_repos_relpath
11629 || (SVN_IS_VALID_REVNUM(new_rev) && new_rev != revision))
12230 || (SVN_IS_VALID_REVNUM(new_rev) && new_rev != node_revision))
11630 {
11631 SVN_ERR(db_op_set_rev_repos_relpath_iprops(wcroot, local_relpath,
11632 iprops, new_rev,
11633 set_repos_relpath,
11634 new_repos_relpath,
11635 new_repos_id,
11636 scratch_pool));
11637 }
11638
11639 /* Early out */
11640 if (depth <= svn_depth_empty
12231 {
12232 SVN_ERR(db_op_set_rev_repos_relpath_iprops(wcroot, local_relpath,
12233 iprops, new_rev,
12234 set_repos_relpath,
12235 new_repos_relpath,
12236 new_repos_id,
12237 scratch_pool));
12238 }
12239
12240 /* Early out */
12241 if (depth <= svn_depth_empty
11641 || db_kind != svn_node_dir
11642 || status == svn_wc__db_status_server_excluded
11643 || status == svn_wc__db_status_excluded
11644 || status == svn_wc__db_status_not_present)
12242 || node_kind != svn_node_dir
12243 || node_status == svn_wc__db_status_server_excluded
12244 || node_status == svn_wc__db_status_excluded
12245 || node_status == svn_wc__db_status_not_present)
11645 return SVN_NO_ERROR;
11646
11647 /* And now recurse over the children */
11648
11649 depth_below_here = depth;
11650
11651 if (depth == svn_depth_immediates || depth == svn_depth_files)
11652 depth_below_here = svn_depth_empty;
11653
11654 iterpool = svn_pool_create(scratch_pool);
11655
12246 return SVN_NO_ERROR;
12247
12248 /* And now recurse over the children */
12249
12250 depth_below_here = depth;
12251
12252 if (depth == svn_depth_immediates || depth == svn_depth_files)
12253 depth_below_here = svn_depth_empty;
12254
12255 iterpool = svn_pool_create(scratch_pool);
12256
11656 SVN_ERR(gather_repo_children(&children, wcroot, local_relpath, 0,
11657 scratch_pool, iterpool));
11658 for (i = 0; i < children->nelts; i++)
12257 SVN_ERR(base_get_children_info(&children, wcroot, local_relpath, 0,
12258 scratch_pool, iterpool));
12259 for (hi = apr_hash_first(scratch_pool, children); hi; hi = apr_hash_next(hi))
11659 {
12260 {
11660 const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
12261 const char *child_basename = apr_hash_this_key(hi);
12262 const struct svn_wc__db_base_info_t *child_info;
11661 const char *child_local_relpath;
11662 const char *child_repos_relpath = NULL;
11663
11664 svn_pool_clear(iterpool);
11665
12263 const char *child_local_relpath;
12264 const char *child_repos_relpath = NULL;
12265
12266 svn_pool_clear(iterpool);
12267
12268 child_info = apr_hash_this_val(hi);
12269
12270 if (child_info->update_root && child_info->kind == svn_node_file)
12271 continue; /* Skip file externals */
12272
12273 if (depth < svn_depth_immediates && child_info->kind == svn_node_dir)
12274 continue; /* Skip directories */
12275
12276 child_local_relpath = svn_relpath_join(local_relpath, child_basename,
12277 iterpool);
12278
12279 /* Don't touch nodes that can't be touched via the exclude list */
12280 if (svn_hash_gets(exclude_relpaths, child_local_relpath))
12281 continue;
12282
12283 /* If the node is still marked 'not-present', then the server did not
12284 re-add it. So it's really gone in this revision, thus we remove the
12285 node.
12286
12287 If the node is still marked 'server-excluded' and yet is not the same
12288 revision as new_rev, then the server did not re-add it, nor
12289 re-server-exclude it, so we can remove the node. */
12290 if (child_info->status == svn_wc__db_status_not_present
12291 || (child_info->status == svn_wc__db_status_server_excluded &&
12292 child_info->revnum != new_rev))
12293 {
12294 svn_sqlite__stmt_t *stmt;
12295 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12296 STMT_DELETE_BASE_NODE));
12297 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, child_local_relpath));
12298 SVN_ERR(svn_sqlite__step_done(stmt));
12299 continue;
12300 }
12301
11666 /* Derive the new URL for the current (child) entry */
11667 if (new_repos_relpath)
11668 child_repos_relpath = svn_relpath_join(new_repos_relpath,
11669 child_basename, iterpool);
11670
12302 /* Derive the new URL for the current (child) entry */
12303 if (new_repos_relpath)
12304 child_repos_relpath = svn_relpath_join(new_repos_relpath,
12305 child_basename, iterpool);
12306
11671 child_local_relpath = svn_relpath_join(local_relpath, child_basename,
11672 iterpool);
11673
11674 SVN_ERR(bump_node_revision(wcroot, child_local_relpath, new_repos_id,
12307 SVN_ERR(bump_node_revision(wcroot, child_local_relpath,
12308 child_info->status,
12309 child_info->kind,
12310 child_info->revnum,
12311 child_info->repos_relpath,
12312 new_repos_id,
11675 child_repos_relpath, new_rev,
11676 depth_below_here,
11677 exclude_relpaths, wcroot_iprops,
11678 FALSE /* is_root */,
11679 (depth < svn_depth_immediates), db,
11680 iterpool));
11681 }
11682

--- 11 unchanged lines hidden (view full) ---

11694 svn_wc__db_t *db,
11695 svn_depth_t depth,
11696 const char *new_repos_relpath,
11697 const char *new_repos_root_url,
11698 const char *new_repos_uuid,
11699 svn_revnum_t new_revision,
11700 apr_hash_t *exclude_relpaths,
11701 apr_hash_t *wcroot_iprops,
12313 child_repos_relpath, new_rev,
12314 depth_below_here,
12315 exclude_relpaths, wcroot_iprops,
12316 FALSE /* is_root */,
12317 (depth < svn_depth_immediates), db,
12318 iterpool));
12319 }
12320

--- 11 unchanged lines hidden (view full) ---

12332 svn_wc__db_t *db,
12333 svn_depth_t depth,
12334 const char *new_repos_relpath,
12335 const char *new_repos_root_url,
12336 const char *new_repos_uuid,
12337 svn_revnum_t new_revision,
12338 apr_hash_t *exclude_relpaths,
12339 apr_hash_t *wcroot_iprops,
12340 svn_boolean_t empty_update,
11702 svn_wc_notify_func2_t notify_func,
11703 void *notify_baton,
11704 apr_pool_t *scratch_pool)
11705{
11706 svn_wc__db_status_t status;
11707 svn_node_kind_t kind;
11708 svn_error_t *err;
11709 apr_int64_t new_repos_id = INVALID_REPOS_ID;
12341 svn_wc_notify_func2_t notify_func,
12342 void *notify_baton,
12343 apr_pool_t *scratch_pool)
12344{
12345 svn_wc__db_status_t status;
12346 svn_node_kind_t kind;
12347 svn_error_t *err;
12348 apr_int64_t new_repos_id = INVALID_REPOS_ID;
12349 svn_revnum_t revision;
12350 const char *repos_relpath;
11710
12351
11711 err = svn_wc__db_base_get_info_internal(&status, &kind, NULL, NULL, NULL,
12352 err = svn_wc__db_base_get_info_internal(&status, &kind, &revision,
12353 &repos_relpath, NULL,
11712 NULL, NULL, NULL, NULL, NULL, NULL,
11713 NULL, NULL, NULL, NULL,
11714 wcroot, local_relpath,
11715 scratch_pool, scratch_pool);
11716 if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
11717 {
11718 svn_error_clear(err);
11719 return SVN_NO_ERROR;

--- 13 unchanged lines hidden (view full) ---

11733 break;
11734 }
11735
11736 if (new_repos_root_url != NULL)
11737 SVN_ERR(create_repos_id(&new_repos_id, new_repos_root_url,
11738 new_repos_uuid,
11739 wcroot->sdb, scratch_pool));
11740
12354 NULL, NULL, NULL, NULL, NULL, NULL,
12355 NULL, NULL, NULL, NULL,
12356 wcroot, local_relpath,
12357 scratch_pool, scratch_pool);
12358 if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
12359 {
12360 svn_error_clear(err);
12361 return SVN_NO_ERROR;

--- 13 unchanged lines hidden (view full) ---

12375 break;
12376 }
12377
12378 if (new_repos_root_url != NULL)
12379 SVN_ERR(create_repos_id(&new_repos_id, new_repos_root_url,
12380 new_repos_uuid,
12381 wcroot->sdb, scratch_pool));
12382
11741 SVN_ERR(bump_node_revision(wcroot, local_relpath, new_repos_id,
12383 SVN_ERR(bump_node_revision(wcroot, local_relpath,
12384 status, kind, revision, repos_relpath,
12385 new_repos_id,
11742 new_repos_relpath, new_revision,
11743 depth, exclude_relpaths,
11744 wcroot_iprops,
11745 TRUE /* is_root */, FALSE, db,
11746 scratch_pool));
11747
12386 new_repos_relpath, new_revision,
12387 depth, exclude_relpaths,
12388 wcroot_iprops,
12389 TRUE /* is_root */, FALSE, db,
12390 scratch_pool));
12391
12392 /* ### TODO: Use empty_update flag for change knowledge */
11748 SVN_ERR(svn_wc__db_bump_moved_away(wcroot, local_relpath, depth, db,
11749 scratch_pool));
11750
11751 SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, SVN_INVALID_REVNUM,
11752 SVN_INVALID_REVNUM, notify_func,
11753 notify_baton, scratch_pool));
11754
11755 return SVN_NO_ERROR;

--- 4 unchanged lines hidden (view full) ---

11760 const char *local_abspath,
11761 svn_depth_t depth,
11762 const char *new_repos_relpath,
11763 const char *new_repos_root_url,
11764 const char *new_repos_uuid,
11765 svn_revnum_t new_revision,
11766 apr_hash_t *exclude_relpaths,
11767 apr_hash_t *wcroot_iprops,
12393 SVN_ERR(svn_wc__db_bump_moved_away(wcroot, local_relpath, depth, db,
12394 scratch_pool));
12395
12396 SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, SVN_INVALID_REVNUM,
12397 SVN_INVALID_REVNUM, notify_func,
12398 notify_baton, scratch_pool));
12399
12400 return SVN_NO_ERROR;

--- 4 unchanged lines hidden (view full) ---

12405 const char *local_abspath,
12406 svn_depth_t depth,
12407 const char *new_repos_relpath,
12408 const char *new_repos_root_url,
12409 const char *new_repos_uuid,
12410 svn_revnum_t new_revision,
12411 apr_hash_t *exclude_relpaths,
12412 apr_hash_t *wcroot_iprops,
12413 svn_boolean_t empty_update,
11768 svn_wc_notify_func2_t notify_func,
11769 void *notify_baton,
11770 apr_pool_t *scratch_pool)
11771{
11772 const char *local_relpath;
11773 svn_wc__db_wcroot_t *wcroot;
11774
11775 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,

--- 6 unchanged lines hidden (view full) ---

11782
11783 if (depth == svn_depth_unknown)
11784 depth = svn_depth_infinity;
11785
11786 SVN_WC__DB_WITH_TXN(
11787 bump_revisions_post_update(wcroot, local_relpath, db,
11788 depth, new_repos_relpath, new_repos_root_url,
11789 new_repos_uuid, new_revision,
12414 svn_wc_notify_func2_t notify_func,
12415 void *notify_baton,
12416 apr_pool_t *scratch_pool)
12417{
12418 const char *local_relpath;
12419 svn_wc__db_wcroot_t *wcroot;
12420
12421 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,

--- 6 unchanged lines hidden (view full) ---

12428
12429 if (depth == svn_depth_unknown)
12430 depth = svn_depth_infinity;
12431
12432 SVN_WC__DB_WITH_TXN(
12433 bump_revisions_post_update(wcroot, local_relpath, db,
12434 depth, new_repos_relpath, new_repos_root_url,
12435 new_repos_uuid, new_revision,
11790 exclude_relpaths, wcroot_iprops,
12436 exclude_relpaths, wcroot_iprops, empty_update,
11791 notify_func, notify_baton, scratch_pool),
11792 wcroot);
11793
11794 return SVN_NO_ERROR;
11795}
11796
11797/* The body of svn_wc__db_lock_add().
11798 */

--- 60 unchanged lines hidden (view full) ---

11859}
11860
11861
11862/* The body of svn_wc__db_lock_remove().
11863 */
11864static svn_error_t *
11865lock_remove_txn(svn_wc__db_wcroot_t *wcroot,
11866 const char *local_relpath,
12437 notify_func, notify_baton, scratch_pool),
12438 wcroot);
12439
12440 return SVN_NO_ERROR;
12441}
12442
12443/* The body of svn_wc__db_lock_add().
12444 */

--- 60 unchanged lines hidden (view full) ---

12505}
12506
12507
12508/* The body of svn_wc__db_lock_remove().
12509 */
12510static svn_error_t *
12511lock_remove_txn(svn_wc__db_wcroot_t *wcroot,
12512 const char *local_relpath,
12513 svn_skel_t *work_items,
11867 apr_pool_t *scratch_pool)
11868{
11869 const char *repos_relpath;
11870 apr_int64_t repos_id;
11871 svn_sqlite__stmt_t *stmt;
11872
11873 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
11874 &repos_relpath, &repos_id,
11875 NULL, NULL, NULL, NULL, NULL,
11876 NULL, NULL, NULL, NULL, NULL,
11877 wcroot, local_relpath,
11878 scratch_pool, scratch_pool));
11879
11880 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
11881 STMT_DELETE_LOCK));
11882 SVN_ERR(svn_sqlite__bindf(stmt, "is", repos_id, repos_relpath));
11883
11884 SVN_ERR(svn_sqlite__step_done(stmt));
11885
12514 apr_pool_t *scratch_pool)
12515{
12516 const char *repos_relpath;
12517 apr_int64_t repos_id;
12518 svn_sqlite__stmt_t *stmt;
12519
12520 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
12521 &repos_relpath, &repos_id,
12522 NULL, NULL, NULL, NULL, NULL,
12523 NULL, NULL, NULL, NULL, NULL,
12524 wcroot, local_relpath,
12525 scratch_pool, scratch_pool));
12526
12527 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12528 STMT_DELETE_LOCK));
12529 SVN_ERR(svn_sqlite__bindf(stmt, "is", repos_id, repos_relpath));
12530
12531 SVN_ERR(svn_sqlite__step_done(stmt));
12532
12533 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
12534
11886 return SVN_NO_ERROR;
11887}
11888
11889
11890svn_error_t *
11891svn_wc__db_lock_remove(svn_wc__db_t *db,
11892 const char *local_abspath,
12535 return SVN_NO_ERROR;
12536}
12537
12538
12539svn_error_t *
12540svn_wc__db_lock_remove(svn_wc__db_t *db,
12541 const char *local_abspath,
12542 svn_skel_t *work_items,
11893 apr_pool_t *scratch_pool)
11894{
11895 svn_wc__db_wcroot_t *wcroot;
11896 const char *local_relpath;
11897
11898 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11899
11900 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11901 local_abspath, scratch_pool, scratch_pool));
11902 VERIFY_USABLE_WCROOT(wcroot);
11903
11904 SVN_WC__DB_WITH_TXN(
12543 apr_pool_t *scratch_pool)
12544{
12545 svn_wc__db_wcroot_t *wcroot;
12546 const char *local_relpath;
12547
12548 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12549
12550 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12551 local_abspath, scratch_pool, scratch_pool));
12552 VERIFY_USABLE_WCROOT(wcroot);
12553
12554 SVN_WC__DB_WITH_TXN(
11905 lock_remove_txn(wcroot, local_relpath, scratch_pool),
12555 lock_remove_txn(wcroot, local_relpath, work_items, scratch_pool),
11906 wcroot);
11907
11908 /* There may be some entries, and the lock info is now out of date. */
11909 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
11910
11911 return SVN_NO_ERROR;
11912}
11913
12556 wcroot);
12557
12558 /* There may be some entries, and the lock info is now out of date. */
12559 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
12560
12561 return SVN_NO_ERROR;
12562}
12563
11914
11915svn_error_t *
11916svn_wc__db_scan_base_repos(const char **repos_relpath,
11917 const char **repos_root_url,
11918 const char **repos_uuid,
11919 svn_wc__db_t *db,
11920 const char *local_abspath,
11921 apr_pool_t *result_pool,
11922 apr_pool_t *scratch_pool)
11923{
11924 svn_wc__db_wcroot_t *wcroot;
11925 const char *local_relpath;
11926 apr_int64_t repos_id;
11927
11928 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
11929
11930 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
11931 local_abspath, scratch_pool, scratch_pool));
11932 VERIFY_USABLE_WCROOT(wcroot);
11933
11934 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
11935 repos_relpath, &repos_id,
11936 NULL, NULL, NULL, NULL, NULL,
11937 NULL, NULL, NULL, NULL, NULL,
11938 wcroot, local_relpath,
11939 result_pool, scratch_pool));
11940 SVN_ERR(svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid, wcroot->sdb,
11941 repos_id, result_pool));
11942
11943 return SVN_NO_ERROR;
11944}
11945
11946
11947/* A helper for scan_addition().
11948 * Compute moved-from information for the node at LOCAL_RELPATH which
11949 * has been determined as having been moved-here.
11950 * If MOVED_FROM_RELPATH is not NULL, set *MOVED_FROM_RELPATH to the
11951 * path of the move-source node in *MOVED_FROM_RELPATH.
11952 * If DELETE_OP_ROOT_RELPATH is not NULL, set *DELETE_OP_ROOT_RELPATH
11953 * to the path of the op-root of the delete-half of the move.
11954 * If moved-from information cannot be derived, set both *MOVED_FROM_RELPATH

--- 82 unchanged lines hidden (view full) ---

12037 }
12038 }
12039
12040 SVN_ERR(svn_sqlite__reset(stmt));
12041
12042 return SVN_NO_ERROR;
12043}
12044
12564/* A helper for scan_addition().
12565 * Compute moved-from information for the node at LOCAL_RELPATH which
12566 * has been determined as having been moved-here.
12567 * If MOVED_FROM_RELPATH is not NULL, set *MOVED_FROM_RELPATH to the
12568 * path of the move-source node in *MOVED_FROM_RELPATH.
12569 * If DELETE_OP_ROOT_RELPATH is not NULL, set *DELETE_OP_ROOT_RELPATH
12570 * to the path of the op-root of the delete-half of the move.
12571 * If moved-from information cannot be derived, set both *MOVED_FROM_RELPATH

--- 82 unchanged lines hidden (view full) ---

12654 }
12655 }
12656
12657 SVN_ERR(svn_sqlite__reset(stmt));
12658
12659 return SVN_NO_ERROR;
12660}
12661
12045/* The body of scan_addition().
12046 */
12662/* Like svn_wc__db_scan_addition(), but with WCROOT+LOCAL_RELPATH instead of
12663 DB+LOCAL_ABSPATH.
12664
12665 The output value of *ORIGINAL_REPOS_ID will be INVALID_REPOS_ID if there
12666 is no 'copy-from' repository. */
12047static svn_error_t *
12667static svn_error_t *
12048scan_addition_txn(svn_wc__db_status_t *status,
12049 const char **op_root_relpath_p,
12050 const char **repos_relpath,
12051 apr_int64_t *repos_id,
12052 const char **original_repos_relpath,
12053 apr_int64_t *original_repos_id,
12054 svn_revnum_t *original_revision,
12055 const char **moved_from_relpath,
12056 const char **moved_from_op_root_relpath,
12057 int *moved_from_op_depth,
12058 svn_wc__db_wcroot_t *wcroot,
12059 const char *local_relpath,
12060 apr_pool_t *result_pool,
12061 apr_pool_t *scratch_pool)
12668scan_addition(svn_wc__db_status_t *status,
12669 const char **op_root_relpath_p,
12670 const char **repos_relpath,
12671 apr_int64_t *repos_id,
12672 const char **original_repos_relpath,
12673 apr_int64_t *original_repos_id,
12674 svn_revnum_t *original_revision,
12675 const char **moved_from_relpath,
12676 const char **moved_from_op_root_relpath,
12677 int *moved_from_op_depth,
12678 svn_wc__db_wcroot_t *wcroot,
12679 const char *local_relpath,
12680 apr_pool_t *result_pool,
12681 apr_pool_t *scratch_pool)
12062{
12063 const char *op_root_relpath;
12064 const char *build_relpath = "";
12065
12066 /* Initialize most of the OUT parameters. Generally, we'll only be filling
12067 in a subset of these, so it is easier to init all up front. Note that
12068 the STATUS parameter will be initialized once we read the status of
12069 the specified node. */

--- 12 unchanged lines hidden (view full) ---

12082 if (moved_from_op_depth)
12083 *moved_from_op_depth = 0;
12084
12085 {
12086 svn_sqlite__stmt_t *stmt;
12087 svn_boolean_t have_row;
12088 svn_wc__db_status_t presence;
12089 int op_depth;
12682{
12683 const char *op_root_relpath;
12684 const char *build_relpath = "";
12685
12686 /* Initialize most of the OUT parameters. Generally, we'll only be filling
12687 in a subset of these, so it is easier to init all up front. Note that
12688 the STATUS parameter will be initialized once we read the status of
12689 the specified node. */

--- 12 unchanged lines hidden (view full) ---

12702 if (moved_from_op_depth)
12703 *moved_from_op_depth = 0;
12704
12705 {
12706 svn_sqlite__stmt_t *stmt;
12707 svn_boolean_t have_row;
12708 svn_wc__db_status_t presence;
12709 int op_depth;
12090 const char *repos_prefix_path = "";
12091 int i;
12710 const char *repos_prefix_path;
12092
12093 /* ### is it faster to fetch fewer columns? */
12094 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12095 STMT_SELECT_WORKING_NODE));
12096 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
12097 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12098
12099 if (!have_row)

--- 32 unchanged lines hidden (view full) ---

12132 if (presence == svn_wc__db_status_normal)
12133 *status = svn_wc__db_status_added;
12134 else
12135 *status = svn_wc__db_status_incomplete;
12136 }
12137
12138
12139 /* Calculate the op root local path components */
12711
12712 /* ### is it faster to fetch fewer columns? */
12713 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12714 STMT_SELECT_WORKING_NODE));
12715 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
12716 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12717
12718 if (!have_row)

--- 32 unchanged lines hidden (view full) ---

12751 if (presence == svn_wc__db_status_normal)
12752 *status = svn_wc__db_status_added;
12753 else
12754 *status = svn_wc__db_status_incomplete;
12755 }
12756
12757
12758 /* Calculate the op root local path components */
12140 op_root_relpath = local_relpath;
12759 op_root_relpath = svn_relpath_prefix(local_relpath, op_depth,
12760 scratch_pool);
12761 repos_prefix_path = svn_relpath_skip_ancestor(op_root_relpath,
12762 local_relpath);
12141
12763
12142 for (i = relpath_depth(local_relpath); i > op_depth; --i)
12143 {
12144 /* Calculate the path of the operation root */
12145 repos_prefix_path =
12146 svn_relpath_join(svn_relpath_basename(op_root_relpath, NULL),
12147 repos_prefix_path,
12148 scratch_pool);
12149 op_root_relpath = svn_relpath_dirname(op_root_relpath, scratch_pool);
12150 }
12151
12152 if (op_root_relpath_p)
12153 *op_root_relpath_p = apr_pstrdup(result_pool, op_root_relpath);
12154
12155 /* ### This if-statement is quite redundant.
12156 * ### We're checking all these values again within the body anyway.
12157 * ### The body should be broken up appropriately and move into the
12158 * ### outer scope. */
12159 if (original_repos_relpath

--- 74 unchanged lines hidden (view full) ---

12234 /* ### This loop here is to skip up to the first node which is a BASE node,
12235 because base_get_info() doesn't accommodate the scenario that
12236 we're looking at here; we found the true op_root, which may be inside
12237 further changed trees. */
12238 if (repos_relpath || repos_id)
12239 {
12240 const char *base_relpath;
12241
12764 if (op_root_relpath_p)
12765 *op_root_relpath_p = apr_pstrdup(result_pool, op_root_relpath);
12766
12767 /* ### This if-statement is quite redundant.
12768 * ### We're checking all these values again within the body anyway.
12769 * ### The body should be broken up appropriately and move into the
12770 * ### outer scope. */
12771 if (original_repos_relpath

--- 74 unchanged lines hidden (view full) ---

12846 /* ### This loop here is to skip up to the first node which is a BASE node,
12847 because base_get_info() doesn't accommodate the scenario that
12848 we're looking at here; we found the true op_root, which may be inside
12849 further changed trees. */
12850 if (repos_relpath || repos_id)
12851 {
12852 const char *base_relpath;
12853
12242 while (TRUE)
12243 {
12854 while (TRUE)
12855 {
12856 const char *tmp;
12244
12857
12245 SVN_ERR(svn_sqlite__reset(stmt));
12858 SVN_ERR(svn_sqlite__reset(stmt));
12246
12859
12247 /* Pointing at op_depth, look at the parent */
12248 repos_prefix_path =
12249 svn_relpath_join(svn_relpath_basename(op_root_relpath, NULL),
12250 repos_prefix_path,
12251 scratch_pool);
12252 op_root_relpath = svn_relpath_dirname(op_root_relpath, scratch_pool);
12860 /* Pointing at op_depth, look at the parent */
12861 repos_prefix_path =
12862 svn_relpath_join(svn_relpath_basename(op_root_relpath, NULL),
12863 repos_prefix_path,
12864 scratch_pool);
12865 op_root_relpath = svn_relpath_dirname(op_root_relpath, scratch_pool);
12253
12254
12866
12867
12255 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, op_root_relpath));
12256 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12868 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, op_root_relpath));
12869 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12257
12870
12258 if (! have_row)
12259 break;
12871 if (! have_row)
12872 break;
12260
12873
12261 op_depth = svn_sqlite__column_int(stmt, 0);
12874 op_depth = svn_sqlite__column_int(stmt, 0);
12262
12875
12263 /* Skip to op_depth */
12264 for (i = relpath_depth(op_root_relpath); i > op_depth; i--)
12265 {
12266 /* Calculate the path of the operation root */
12267 repos_prefix_path =
12268 svn_relpath_join(svn_relpath_basename(op_root_relpath, NULL),
12269 repos_prefix_path,
12270 scratch_pool);
12271 op_root_relpath =
12272 svn_relpath_dirname(op_root_relpath, scratch_pool);
12876 /* Skip to op_depth */
12877 tmp = op_root_relpath;
12878
12879 op_root_relpath = svn_relpath_prefix(op_root_relpath, op_depth,
12880 scratch_pool);
12881 repos_prefix_path = svn_relpath_join(
12882 svn_relpath_skip_ancestor(op_root_relpath, tmp),
12883 repos_prefix_path, scratch_pool);
12273 }
12884 }
12274 }
12275
12276 SVN_ERR(svn_sqlite__reset(stmt));
12277
12278 build_relpath = repos_prefix_path;
12279
12280 /* If we're here, then we have an added/copied/moved (start) node, and
12281 CURRENT_ABSPATH now points to a BASE node. Figure out the repository
12282 information for the current node, and use that to compute the start

--- 43 unchanged lines hidden (view full) ---

12326 }
12327 }
12328 SVN_ERR_ASSERT(!op_root_relpath_p || *op_root_relpath_p != NULL);
12329#endif
12330
12331 return SVN_NO_ERROR;
12332}
12333
12885
12886 SVN_ERR(svn_sqlite__reset(stmt));
12887
12888 build_relpath = repos_prefix_path;
12889
12890 /* If we're here, then we have an added/copied/moved (start) node, and
12891 CURRENT_ABSPATH now points to a BASE node. Figure out the repository
12892 information for the current node, and use that to compute the start

--- 43 unchanged lines hidden (view full) ---

12936 }
12937 }
12938 SVN_ERR_ASSERT(!op_root_relpath_p || *op_root_relpath_p != NULL);
12939#endif
12940
12941 return SVN_NO_ERROR;
12942}
12943
12334
12335/* Like svn_wc__db_scan_addition(), but with WCROOT+LOCAL_RELPATH instead of
12336 DB+LOCAL_ABSPATH.
12337
12338 The output value of *ORIGINAL_REPOS_ID will be INVALID_REPOS_ID if there
12339 is no 'copy-from' repository. */
12340static svn_error_t *
12341scan_addition(svn_wc__db_status_t *status,
12342 const char **op_root_relpath,
12944svn_error_t *
12945svn_wc__db_scan_addition_internal(
12946 svn_wc__db_status_t *status,
12947 const char **op_root_relpath_p,
12343 const char **repos_relpath,
12344 apr_int64_t *repos_id,
12345 const char **original_repos_relpath,
12346 apr_int64_t *original_repos_id,
12347 svn_revnum_t *original_revision,
12948 const char **repos_relpath,
12949 apr_int64_t *repos_id,
12950 const char **original_repos_relpath,
12951 apr_int64_t *original_repos_id,
12952 svn_revnum_t *original_revision,
12348 const char **moved_from_relpath,
12349 const char **moved_from_op_root_relpath,
12350 int *moved_from_op_depth,
12351 svn_wc__db_wcroot_t *wcroot,
12352 const char *local_relpath,
12353 apr_pool_t *result_pool,
12354 apr_pool_t *scratch_pool)
12355{
12953 svn_wc__db_wcroot_t *wcroot,
12954 const char *local_relpath,
12955 apr_pool_t *result_pool,
12956 apr_pool_t *scratch_pool)
12957{
12356 SVN_WC__DB_WITH_TXN(
12357 scan_addition_txn(status, op_root_relpath, repos_relpath, repos_id,
12358 original_repos_relpath, original_repos_id,
12359 original_revision, moved_from_relpath,
12360 moved_from_op_root_relpath, moved_from_op_depth,
12361 wcroot, local_relpath, result_pool, scratch_pool),
12362 wcroot);
12363 return SVN_NO_ERROR;
12958 return svn_error_trace(
12959 scan_addition(status, op_root_relpath_p, repos_relpath, repos_id,
12960 original_repos_relpath, original_repos_id,
12961 original_revision, NULL, NULL, NULL,
12962 wcroot, local_relpath, result_pool, scratch_pool));
12364}
12365
12963}
12964
12366
12367svn_error_t *
12368svn_wc__db_scan_addition(svn_wc__db_status_t *status,
12369 const char **op_root_abspath,
12370 const char **repos_relpath,
12371 const char **repos_root_url,
12372 const char **repos_uuid,
12373 const char **original_repos_relpath,
12374 const char **original_root_url,

--- 15 unchanged lines hidden (view full) ---

12390 = (original_root_url || original_uuid) ? &original_repos_id : NULL;
12391
12392 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12393
12394 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12395 local_abspath, scratch_pool, scratch_pool));
12396 VERIFY_USABLE_WCROOT(wcroot);
12397
12965svn_error_t *
12966svn_wc__db_scan_addition(svn_wc__db_status_t *status,
12967 const char **op_root_abspath,
12968 const char **repos_relpath,
12969 const char **repos_root_url,
12970 const char **repos_uuid,
12971 const char **original_repos_relpath,
12972 const char **original_root_url,

--- 15 unchanged lines hidden (view full) ---

12988 = (original_root_url || original_uuid) ? &original_repos_id : NULL;
12989
12990 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12991
12992 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12993 local_abspath, scratch_pool, scratch_pool));
12994 VERIFY_USABLE_WCROOT(wcroot);
12995
12398 SVN_ERR(scan_addition(status,
12996 SVN_WC__DB_WITH_TXN4(
12997 scan_addition(status,
12399 op_root_abspath
12400 ? &op_root_relpath
12401 : NULL,
12402 repos_relpath, repos_id_p,
12403 original_repos_relpath, original_repos_id_p,
12404 original_revision,
12405 NULL, NULL, NULL,
12998 op_root_abspath
12999 ? &op_root_relpath
13000 : NULL,
13001 repos_relpath, repos_id_p,
13002 original_repos_relpath, original_repos_id_p,
13003 original_revision,
13004 NULL, NULL, NULL,
12406 wcroot, local_relpath, result_pool, scratch_pool));
13005 wcroot, local_relpath, result_pool, scratch_pool),
13006 svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid, wcroot,
13007 repos_id, result_pool),
13008 svn_wc__db_fetch_repos_info(original_root_url, original_uuid,
13009 wcroot, original_repos_id,
13010 result_pool),
13011 SVN_NO_ERROR,
13012 wcroot);
12407
12408 if (op_root_abspath)
12409 *op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath,
12410 result_pool);
12411 /* REPOS_ID must be valid if requested; ORIGINAL_REPOS_ID need not be. */
12412 SVN_ERR_ASSERT(repos_id_p == NULL || repos_id != INVALID_REPOS_ID);
12413
13013
13014 if (op_root_abspath)
13015 *op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath,
13016 result_pool);
13017 /* REPOS_ID must be valid if requested; ORIGINAL_REPOS_ID need not be. */
13018 SVN_ERR_ASSERT(repos_id_p == NULL || repos_id != INVALID_REPOS_ID);
13019
12414 SVN_ERR(svn_wc__db_fetch_repos_info(repos_root_url, repos_uuid, wcroot->sdb,
12415 repos_id, result_pool));
12416 SVN_ERR(svn_wc__db_fetch_repos_info(original_root_url, original_uuid,
12417 wcroot->sdb, original_repos_id,
12418 result_pool));
12419
12420 return SVN_NO_ERROR;
12421}
12422
12423svn_error_t *
12424svn_wc__db_scan_moved(const char **moved_from_abspath,
12425 const char **op_root_abspath,
12426 const char **op_root_moved_from_abspath,
12427 const char **moved_from_delete_abspath,

--- 11 unchanged lines hidden (view full) ---

12439 int moved_from_op_depth = -1;
12440
12441 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12442
12443 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12444 local_abspath, scratch_pool, scratch_pool));
12445 VERIFY_USABLE_WCROOT(wcroot);
12446
13020 return SVN_NO_ERROR;
13021}
13022
13023svn_error_t *
13024svn_wc__db_scan_moved(const char **moved_from_abspath,
13025 const char **op_root_abspath,
13026 const char **op_root_moved_from_abspath,
13027 const char **moved_from_delete_abspath,

--- 11 unchanged lines hidden (view full) ---

13039 int moved_from_op_depth = -1;
13040
13041 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
13042
13043 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13044 local_abspath, scratch_pool, scratch_pool));
13045 VERIFY_USABLE_WCROOT(wcroot);
13046
12447 SVN_ERR(scan_addition(&status,
13047 SVN_WC__DB_WITH_TXN(
13048 scan_addition(&status,
12448 op_root_abspath
12449 ? &op_root_relpath
12450 : NULL,
12451 NULL, NULL,
12452 NULL, NULL, NULL,
12453 moved_from_abspath
12454 ? &moved_from_relpath
12455 : NULL,
12456 (op_root_moved_from_abspath
12457 || moved_from_delete_abspath)
12458 ? &moved_from_op_root_relpath
12459 : NULL,
12460 moved_from_delete_abspath
12461 ? &moved_from_op_depth
12462 : NULL,
13049 op_root_abspath
13050 ? &op_root_relpath
13051 : NULL,
13052 NULL, NULL,
13053 NULL, NULL, NULL,
13054 moved_from_abspath
13055 ? &moved_from_relpath
13056 : NULL,
13057 (op_root_moved_from_abspath
13058 || moved_from_delete_abspath)
13059 ? &moved_from_op_root_relpath
13060 : NULL,
13061 moved_from_delete_abspath
13062 ? &moved_from_op_depth
13063 : NULL,
12463 wcroot, local_relpath, scratch_pool, scratch_pool));
13064 wcroot, local_relpath, scratch_pool, scratch_pool),
13065 wcroot);
12464
12465 if (status != svn_wc__db_status_moved_here || !moved_from_relpath)
12466 return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
12467 _("Path '%s' was not moved here"),
12468 path_for_error_message(wcroot, local_relpath,
12469 scratch_pool));
12470
12471 if (op_root_abspath)

--- 7 unchanged lines hidden (view full) ---

12479 if (op_root_moved_from_abspath)
12480 *op_root_moved_from_abspath = svn_dirent_join(wcroot->abspath,
12481 moved_from_op_root_relpath,
12482 result_pool);
12483
12484 /* The deleted node is either where we moved from, or one of its ancestors */
12485 if (moved_from_delete_abspath)
12486 {
13066
13067 if (status != svn_wc__db_status_moved_here || !moved_from_relpath)
13068 return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
13069 _("Path '%s' was not moved here"),
13070 path_for_error_message(wcroot, local_relpath,
13071 scratch_pool));
13072
13073 if (op_root_abspath)

--- 7 unchanged lines hidden (view full) ---

13081 if (op_root_moved_from_abspath)
13082 *op_root_moved_from_abspath = svn_dirent_join(wcroot->abspath,
13083 moved_from_op_root_relpath,
13084 result_pool);
13085
13086 /* The deleted node is either where we moved from, or one of its ancestors */
13087 if (moved_from_delete_abspath)
13088 {
12487 const char *tmp = moved_from_op_root_relpath;
13089 const char *tmp = svn_relpath_prefix(moved_from_op_root_relpath,
13090 moved_from_op_depth, scratch_pool);
12488
13091
12489 SVN_ERR_ASSERT(moved_from_op_depth >= 0);
12490
12491 while (relpath_depth(tmp) > moved_from_op_depth)
12492 tmp = svn_relpath_dirname(tmp, scratch_pool);
12493
12494 *moved_from_delete_abspath = svn_dirent_join(wcroot->abspath, tmp,
12495 scratch_pool);
12496 }
12497
12498 return SVN_NO_ERROR;
12499}
12500
13092 *moved_from_delete_abspath = svn_dirent_join(wcroot->abspath, tmp,
13093 scratch_pool);
13094 }
13095
13096 return SVN_NO_ERROR;
13097}
13098
12501/* ###
13099/* ### Recursive helper for svn_wc__db_follow_moved_to()
12502 */
12503static svn_error_t *
13100 */
13101static svn_error_t *
12504follow_moved_to(apr_array_header_t **moved_tos,
12505 int op_depth,
12506 const char *repos_path,
12507 svn_revnum_t revision,
12508 svn_wc__db_wcroot_t *wcroot,
13102follow_moved_to(svn_wc__db_wcroot_t *wcroot,
12509 const char *local_relpath,
13103 const char *local_relpath,
13104 int op_depth,
13105 apr_array_header_t **moved_tos,
12510 apr_pool_t *result_pool,
12511 apr_pool_t *scratch_pool)
12512{
12513 svn_sqlite__stmt_t *stmt;
12514 svn_boolean_t have_row;
13106 apr_pool_t *result_pool,
13107 apr_pool_t *scratch_pool)
13108{
13109 svn_sqlite__stmt_t *stmt;
13110 svn_boolean_t have_row;
12515 int working_op_depth;
12516 const char *ancestor_relpath, *node_moved_to = NULL;
13111 int shadowing_op_depth;
13112 const char *ancestor_relpath;
13113 const char *node_moved_to = NULL;
12517 int i;
12518
13114 int i;
13115
12519 SVN_ERR_ASSERT((!op_depth && !repos_path) || (op_depth && repos_path));
12520
13116 /* Obtain the depth of the node directly shadowing local_relpath
13117 as it exists at OP_DEPTH, and perhaps moved to info */
12521 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12522 STMT_SELECT_OP_DEPTH_MOVED_TO));
12523 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
12524 op_depth));
12525 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12526 if (have_row)
12527 {
13118 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
13119 STMT_SELECT_OP_DEPTH_MOVED_TO));
13120 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
13121 op_depth));
13122 SVN_ERR(svn_sqlite__step(&have_row, stmt));
13123 if (have_row)
13124 {
12528 working_op_depth = svn_sqlite__column_int(stmt, 0);
13125 shadowing_op_depth = svn_sqlite__column_int(stmt, 0);
12529 node_moved_to = svn_sqlite__column_text(stmt, 1, result_pool);
13126 node_moved_to = svn_sqlite__column_text(stmt, 1, result_pool);
12530 if (!repos_path)
13127
13128 if (node_moved_to)
12531 {
13129 {
12532 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12533 if (!have_row || svn_sqlite__column_revnum(stmt, 0))
12534 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
12535 svn_sqlite__reset(stmt),
12536 _("The base node '%s' was not found."),
12537 path_for_error_message(wcroot,
12538 local_relpath,
12539 scratch_pool));
12540 repos_path = svn_sqlite__column_text(stmt, 2, scratch_pool);
12541 revision = svn_sqlite__column_revnum(stmt, 3);
13130 struct svn_wc__db_moved_to_t *moved_to;
13131
13132 moved_to = apr_palloc(result_pool, sizeof(*moved_to));
13133 moved_to->op_depth = shadowing_op_depth;
13134 moved_to->local_relpath = node_moved_to;
13135 APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
12542 }
12543 }
13136 }
13137 }
13138
12544 SVN_ERR(svn_sqlite__reset(stmt));
12545
13139 SVN_ERR(svn_sqlite__reset(stmt));
13140
12546 if (node_moved_to)
13141 if (!have_row)
12547 {
13142 {
12548 svn_boolean_t have_row2;
12549
12550 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12551 STMT_SELECT_MOVED_HERE));
12552 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, node_moved_to,
12553 relpath_depth(node_moved_to)));
12554 SVN_ERR(svn_sqlite__step(&have_row2, stmt));
12555 if (!have_row2 || !svn_sqlite__column_int(stmt, 0)
12556 || revision != svn_sqlite__column_revnum(stmt, 3)
12557 || strcmp(repos_path, svn_sqlite__column_text(stmt, 2, NULL)))
12558 node_moved_to = NULL;
12559 SVN_ERR(svn_sqlite__reset(stmt));
13143 /* Node is not shadowed, so not moved */
13144 return SVN_NO_ERROR;
12560 }
13145 }
12561
12562 if (node_moved_to)
13146 else if (node_moved_to)
12563 {
13147 {
12564 struct svn_wc__db_moved_to_t *moved_to;
12565
12566 moved_to = apr_palloc(result_pool, sizeof(*moved_to));
12567 moved_to->op_depth = working_op_depth;
12568 moved_to->local_relpath = node_moved_to;
12569 APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
13148 /* Moved directly, so we have the final location */
13149 return SVN_NO_ERROR;
12570 }
13150 }
12571
12572 /* A working row with moved_to, or no working row, and we are done. */
12573 if (node_moved_to || !have_row)
12574 return SVN_NO_ERROR;
12575
12576 /* Need to handle being moved via an ancestor. */
12577 ancestor_relpath = local_relpath;
13151 /* Need to handle being moved via an ancestor. */
13152 ancestor_relpath = local_relpath;
12578 for (i = relpath_depth(local_relpath); i > working_op_depth; --i)
13153 for (i = relpath_depth(local_relpath); i > shadowing_op_depth; --i)
12579 {
12580 const char *ancestor_moved_to;
12581
12582 ancestor_relpath = svn_relpath_dirname(ancestor_relpath, scratch_pool);
12583
12584 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12585 STMT_SELECT_MOVED_TO));
12586 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, ancestor_relpath,
13154 {
13155 const char *ancestor_moved_to;
13156
13157 ancestor_relpath = svn_relpath_dirname(ancestor_relpath, scratch_pool);
13158
13159 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
13160 STMT_SELECT_MOVED_TO));
13161 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, ancestor_relpath,
12587 working_op_depth));
12588 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12589 SVN_ERR_ASSERT(have_row);
13162 shadowing_op_depth));
13163 SVN_ERR(svn_sqlite__step_row(stmt));
13164
12590 ancestor_moved_to = svn_sqlite__column_text(stmt, 0, scratch_pool);
12591 SVN_ERR(svn_sqlite__reset(stmt));
12592 if (ancestor_moved_to)
12593 {
13165 ancestor_moved_to = svn_sqlite__column_text(stmt, 0, scratch_pool);
13166 SVN_ERR(svn_sqlite__reset(stmt));
13167 if (ancestor_moved_to)
13168 {
12594 node_moved_to
12595 = svn_relpath_join(ancestor_moved_to,
12596 svn_relpath_skip_ancestor(ancestor_relpath,
12597 local_relpath),
12598 result_pool);
12599
12600 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12601 STMT_SELECT_MOVED_HERE));
12602 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, node_moved_to,
12603 relpath_depth(ancestor_moved_to)));
12604 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12605 if (!have_row)
12606 ancestor_moved_to = NULL;
12607 else if (!svn_sqlite__column_int(stmt, 0))
12608 {
12609 svn_wc__db_status_t presence
12610 = svn_sqlite__column_token(stmt, 1, presence_map);
12611 if (presence != svn_wc__db_status_not_present)
12612 ancestor_moved_to = NULL;
12613 else
12614 {
12615 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12616 if (!have_row && !svn_sqlite__column_int(stmt, 0))
12617 ancestor_moved_to = NULL;
12618 }
12619 }
12620 SVN_ERR(svn_sqlite__reset(stmt));
12621 if (!ancestor_moved_to)
12622 break;
12623 /* verify repos_path points back? */
12624 }
12625 if (ancestor_moved_to)
12626 {
12627 struct svn_wc__db_moved_to_t *moved_to;
12628
13169 struct svn_wc__db_moved_to_t *moved_to;
13170
13171 node_moved_to
13172 = svn_relpath_join(ancestor_moved_to,
13173 svn_relpath_skip_ancestor(ancestor_relpath,
13174 local_relpath),
13175 result_pool);
13176
12629 moved_to = apr_palloc(result_pool, sizeof(*moved_to));
13177 moved_to = apr_palloc(result_pool, sizeof(*moved_to));
12630 moved_to->op_depth = working_op_depth;
13178 moved_to->op_depth = shadowing_op_depth;
12631 moved_to->local_relpath = node_moved_to;
12632 APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
12633
13179 moved_to->local_relpath = node_moved_to;
13180 APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
13181
12634 SVN_ERR(follow_moved_to(moved_tos, relpath_depth(ancestor_moved_to),
12635 repos_path, revision, wcroot, node_moved_to,
12636 result_pool, scratch_pool));
13182 SVN_ERR(follow_moved_to(wcroot, node_moved_to,
13183 relpath_depth(ancestor_moved_to),
13184 moved_tos, result_pool, scratch_pool));
13185
12637 break;
12638 }
12639 }
12640
12641 return SVN_NO_ERROR;
12642}
12643
12644svn_error_t *

--- 11 unchanged lines hidden (view full) ---

12656 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12657 local_abspath, scratch_pool, scratch_pool));
12658 VERIFY_USABLE_WCROOT(wcroot);
12659
12660 *moved_tos = apr_array_make(result_pool, 0,
12661 sizeof(struct svn_wc__db_moved_to_t *));
12662
12663 /* ### Wrap in a transaction */
13186 break;
13187 }
13188 }
13189
13190 return SVN_NO_ERROR;
13191}
13192
13193svn_error_t *

--- 11 unchanged lines hidden (view full) ---

13205 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13206 local_abspath, scratch_pool, scratch_pool));
13207 VERIFY_USABLE_WCROOT(wcroot);
13208
13209 *moved_tos = apr_array_make(result_pool, 0,
13210 sizeof(struct svn_wc__db_moved_to_t *));
13211
13212 /* ### Wrap in a transaction */
12664 SVN_ERR(follow_moved_to(moved_tos, 0, NULL, SVN_INVALID_REVNUM,
12665 wcroot, local_relpath,
12666 result_pool, scratch_pool));
13213 SVN_WC__DB_WITH_TXN(follow_moved_to(wcroot, local_relpath, 0, moved_tos,
13214 result_pool, scratch_pool),
13215 wcroot);
12667
12668 /* ### Convert moved_to to abspath */
12669
12670 return SVN_NO_ERROR;
12671}
12672
13216
13217 /* ### Convert moved_to to abspath */
13218
13219 return SVN_NO_ERROR;
13220}
13221
12673/* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
12674 examining the lowest working node above OP_DEPTH. The output paths
12675 are NULL if there is no move, otherwise:
13222svn_error_t *
13223svn_wc__db_scan_moved_to_internal(const char **move_src_relpath,
13224 const char **move_dst_relpath,
13225 const char **delete_relpath,
13226 svn_wc__db_wcroot_t *wcroot,
13227 const char *local_relpath,
13228 int op_depth,
13229 apr_pool_t *result_pool,
13230 apr_pool_t *scratch_pool)
13231{
13232 svn_sqlite__stmt_t *stmt;
13233 svn_boolean_t have_row;
13234 int delete_op_depth;
13235 const char *relpath = local_relpath;
13236 const char *dst_relpath;
12676
13237
12677 *MOVE_DST_RELPATH: the moved-to destination of LOCAL_RELPATH.
13238 SVN_ERR_ASSERT(local_relpath[0]); /* Not valid on the WC root */
12678
13239
12679 *MOVE_DST_OP_ROOT_RELPATH: the moved-to destination of the root of
12680 the move of LOCAL_RELPATH. This may be equal to *MOVE_DST_RELPATH
12681 if LOCAL_RELPATH is the root of the move.
13240 if (move_src_relpath)
13241 *move_src_relpath = NULL;
13242 if (move_dst_relpath)
13243 *move_dst_relpath = NULL;
13244 if (delete_relpath)
13245 *delete_relpath = NULL;
12682
13246
12683 *MOVE_SRC_ROOT_RELPATH: the root of the move source. For moves
12684 inside a delete this will be different from *MOVE_SRC_OP_ROOT_RELPATH.
13247 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
13248 STMT_SELECT_OP_DEPTH_MOVED_TO));
13249 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, relpath, op_depth));
12685
13250
12686 *MOVE_SRC_OP_ROOT_RELPATH: the root of the source layer that
12687 contains the move. For moves inside deletes this is the root of
12688 the delete, for other moves this is the root of the move.
13251 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12689
13252
12690 Given a path A/B/C with A/B moved to X then for A/B/C
13253 if (!have_row)
13254 {
13255 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
13256 svn_sqlite__reset(stmt),
13257 _("Node '%s' is not shadowed"),
13258 path_for_error_message(wcroot, local_relpath,
13259 scratch_pool));
13260 }
12691
13261
12692 MOVE_DST_RELPATH is X/C
12693 MOVE_DST_OP_ROOT_RELPATH is X
12694 MOVE_SRC_ROOT_RELPATH is A/B
12695 MOVE_SRC_OP_ROOT_RELPATH is A/B
13262 delete_op_depth = svn_sqlite__column_int(stmt, 0);
13263 dst_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
12696
13264
12697 If A is then deleted the MOVE_DST_RELPATH, MOVE_DST_OP_ROOT_RELPATH
12698 and MOVE_SRC_ROOT_RELPATH remain the same but MOVE_SRC_OP_ROOT_RELPATH
12699 changes to A.
13265 SVN_ERR(svn_sqlite__reset(stmt));
12700
13266
12701 ### Think about combining with scan_deletion? Also with
12702 ### scan_addition to get moved-to for replaces? Do we need to
12703 ### return the op-root of the move source, i.e. A/B in the example
12704 ### above? */
12705svn_error_t *
12706svn_wc__db_op_depth_moved_to(const char **move_dst_relpath,
12707 const char **move_dst_op_root_relpath,
12708 const char **move_src_root_relpath,
12709 const char **move_src_op_root_relpath,
12710 int op_depth,
12711 svn_wc__db_wcroot_t *wcroot,
12712 const char *local_relpath,
12713 apr_pool_t *result_pool,
12714 apr_pool_t *scratch_pool)
12715{
12716 svn_sqlite__stmt_t *stmt;
12717 svn_boolean_t have_row;
12718 int delete_op_depth;
12719 const char *relpath = local_relpath;
13267 while (!dst_relpath && have_row)
13268 {
13269 relpath = svn_relpath_dirname(relpath, scratch_pool);
12720
13270
12721 *move_dst_relpath = *move_dst_op_root_relpath = NULL;
12722 *move_src_root_relpath = *move_src_op_root_relpath = NULL;
13271 if (relpath_depth(relpath) < delete_op_depth)
13272 break;
12723
13273
12724 do
12725 {
12726 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
13274 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
12727 STMT_SELECT_LOWEST_WORKING_NODE));
12728 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, relpath, op_depth));
13275 STMT_SELECT_DEPTH_NODE));
13276 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, relpath,
13277 delete_op_depth));
13278
12729 SVN_ERR(svn_sqlite__step(&have_row, stmt));
13279 SVN_ERR(svn_sqlite__step(&have_row, stmt));
13280
12730 if (have_row)
13281 if (have_row)
12731 {
12732 delete_op_depth = svn_sqlite__column_int(stmt, 0);
12733 *move_dst_op_root_relpath = svn_sqlite__column_text(stmt, 3,
12734 result_pool);
12735 if (*move_dst_op_root_relpath)
12736 *move_src_root_relpath = apr_pstrdup(result_pool, relpath);
12737 }
13282 dst_relpath = svn_sqlite__column_text(stmt, 13, scratch_pool);
13283
12738 SVN_ERR(svn_sqlite__reset(stmt));
13284 SVN_ERR(svn_sqlite__reset(stmt));
12739 if (!*move_dst_op_root_relpath)
12740 relpath = svn_relpath_dirname(relpath, scratch_pool);
12741 }
13285 }
12742 while (!*move_dst_op_root_relpath
12743 && have_row && delete_op_depth <= relpath_depth(relpath));
12744
13286
12745 if (*move_dst_op_root_relpath)
13287 if (dst_relpath)
12746 {
13288 {
12747 *move_dst_relpath
12748 = svn_relpath_join(*move_dst_op_root_relpath,
12749 svn_relpath_skip_ancestor(relpath, local_relpath),
12750 result_pool);
12751 while (delete_op_depth < relpath_depth(relpath))
12752 relpath = svn_relpath_dirname(relpath, scratch_pool);
12753 *move_src_op_root_relpath = apr_pstrdup(result_pool, relpath);
13289 if (move_src_relpath)
13290 *move_src_relpath = apr_pstrdup(result_pool, relpath);
13291
13292 if (move_dst_relpath)
13293 *move_dst_relpath = apr_pstrdup(result_pool, dst_relpath);
13294
13295 if (delete_relpath)
13296 *delete_relpath = svn_relpath_prefix(local_relpath, delete_op_depth,
13297 result_pool);
12754 }
12755
12756 return SVN_NO_ERROR;
12757}
12758
12759/* Public (within libsvn_wc) absolute path version of
12760 svn_wc__db_op_depth_moved_to with the op-depth hard-coded to
12761 BASE. */
12762svn_error_t *
12763svn_wc__db_base_moved_to(const char **move_dst_abspath,
12764 const char **move_dst_op_root_abspath,
12765 const char **move_src_root_abspath,
13298 }
13299
13300 return SVN_NO_ERROR;
13301}
13302
13303/* Public (within libsvn_wc) absolute path version of
13304 svn_wc__db_op_depth_moved_to with the op-depth hard-coded to
13305 BASE. */
13306svn_error_t *
13307svn_wc__db_base_moved_to(const char **move_dst_abspath,
13308 const char **move_dst_op_root_abspath,
13309 const char **move_src_root_abspath,
12766 const char **move_src_op_root_abspath,
13310 const char **delete_abspath,
12767 svn_wc__db_t *db,
12768 const char *local_abspath,
12769 apr_pool_t *result_pool,
12770 apr_pool_t *scratch_pool)
12771{
12772 svn_wc__db_wcroot_t *wcroot;
12773 const char *local_relpath;
13311 svn_wc__db_t *db,
13312 const char *local_abspath,
13313 apr_pool_t *result_pool,
13314 apr_pool_t *scratch_pool)
13315{
13316 svn_wc__db_wcroot_t *wcroot;
13317 const char *local_relpath;
12774 const char *move_dst_relpath, *move_dst_op_root_relpath;
12775 const char *move_src_root_relpath, *move_src_op_root_relpath;
13318 const char *dst_root_relpath;
13319 const char *src_root_relpath, *delete_relpath;
12776
12777 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
12778
13320
13321 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
13322
13323
12779 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
12780 local_abspath, scratch_pool, scratch_pool));
12781 VERIFY_USABLE_WCROOT(wcroot);
12782
13324 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13325 local_abspath, scratch_pool, scratch_pool));
13326 VERIFY_USABLE_WCROOT(wcroot);
13327
12783 SVN_WC__DB_WITH_TXN(svn_wc__db_op_depth_moved_to(&move_dst_relpath,
12784 &move_dst_op_root_relpath,
12785 &move_src_root_relpath,
12786 &move_src_op_root_relpath,
12787 0 /* BASE op-depth */,
12788 wcroot, local_relpath,
12789 scratch_pool, scratch_pool),
13328 SVN_WC__DB_WITH_TXN(svn_wc__db_scan_moved_to_internal(&src_root_relpath,
13329 &dst_root_relpath,
13330 &delete_relpath,
13331 wcroot, local_relpath,
13332 0 /* BASE */,
13333 scratch_pool,
13334 scratch_pool),
12790 wcroot);
12791
12792 if (move_dst_abspath)
13335 wcroot);
13336
13337 if (move_dst_abspath)
12793 *move_dst_abspath
12794 = move_dst_relpath
12795 ? svn_dirent_join(wcroot->abspath, move_dst_relpath, result_pool)
12796 : NULL;
13338 *move_dst_abspath =
13339 dst_root_relpath
13340 ? svn_dirent_join(wcroot->abspath,
13341 svn_dirent_join(
13342 dst_root_relpath,
13343 svn_relpath_skip_ancestor(src_root_relpath,
13344 local_relpath),
13345 scratch_pool),
13346 result_pool)
13347 : NULL;
12797
12798 if (move_dst_op_root_abspath)
13348
13349 if (move_dst_op_root_abspath)
12799 *move_dst_op_root_abspath
12800 = move_dst_op_root_relpath
12801 ? svn_dirent_join(wcroot->abspath, move_dst_op_root_relpath, result_pool)
12802 : NULL;
13350 *move_dst_op_root_abspath =
13351 dst_root_relpath
13352 ? svn_dirent_join(wcroot->abspath, dst_root_relpath, result_pool)
13353 : NULL;
12803
12804 if (move_src_root_abspath)
13354
13355 if (move_src_root_abspath)
12805 *move_src_root_abspath
12806 = move_src_root_relpath
12807 ? svn_dirent_join(wcroot->abspath, move_src_root_relpath, result_pool)
12808 : NULL;
13356 *move_src_root_abspath =
13357 src_root_relpath
13358 ? svn_dirent_join(wcroot->abspath, src_root_relpath, result_pool)
13359 : NULL;
12809
13360
12810 if (move_src_op_root_abspath)
12811 *move_src_op_root_abspath
12812 = move_src_op_root_relpath
12813 ? svn_dirent_join(wcroot->abspath, move_src_op_root_relpath, result_pool)
12814 : NULL;
13361 if (delete_abspath)
13362 *delete_abspath =
13363 delete_relpath
13364 ? svn_dirent_join(wcroot->abspath, delete_relpath, result_pool)
13365 : NULL;
12815
12816 return SVN_NO_ERROR;
12817}
12818
12819svn_error_t *
12820svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb,
12821 apr_int64_t *repos_id,
12822 apr_int64_t *wc_id,

--- 6 unchanged lines hidden (view full) ---

12829 svn_wc__db_wcroot_t *wcroot;
12830
12831 /* Upgrade is inherently exclusive so specify exclusive locking. */
12832 SVN_ERR(create_db(sdb, repos_id, wc_id, dir_abspath,
12833 repos_root_url, repos_uuid,
12834 SDB_FILE,
12835 NULL, SVN_INVALID_REVNUM, svn_depth_unknown,
12836 TRUE /* exclusive */,
13366
13367 return SVN_NO_ERROR;
13368}
13369
13370svn_error_t *
13371svn_wc__db_upgrade_begin(svn_sqlite__db_t **sdb,
13372 apr_int64_t *repos_id,
13373 apr_int64_t *wc_id,

--- 6 unchanged lines hidden (view full) ---

13380 svn_wc__db_wcroot_t *wcroot;
13381
13382 /* Upgrade is inherently exclusive so specify exclusive locking. */
13383 SVN_ERR(create_db(sdb, repos_id, wc_id, dir_abspath,
13384 repos_root_url, repos_uuid,
13385 SDB_FILE,
13386 NULL, SVN_INVALID_REVNUM, svn_depth_unknown,
13387 TRUE /* exclusive */,
13388 0 /* timeout */,
12837 wc_db->state_pool, scratch_pool));
12838
12839 SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot,
12840 apr_pstrdup(wc_db->state_pool,
12841 dir_abspath),
12842 *sdb, *wc_id, FORMAT_FROM_SDB,
12843 FALSE /* auto-upgrade */,
13389 wc_db->state_pool, scratch_pool));
13390
13391 SVN_ERR(svn_wc__db_pdh_create_wcroot(&wcroot,
13392 apr_pstrdup(wc_db->state_pool,
13393 dir_abspath),
13394 *sdb, *wc_id, FORMAT_FROM_SDB,
13395 FALSE /* auto-upgrade */,
12844 FALSE /* enforce_empty_wq */,
12845 wc_db->state_pool, scratch_pool));
12846
12847 /* The WCROOT is complete. Stash it into DB. */
12848 svn_hash_sets(wc_db->dir_data, wcroot->abspath, wcroot);
12849
12850 return SVN_NO_ERROR;
12851}
12852
13396 wc_db->state_pool, scratch_pool));
13397
13398 /* The WCROOT is complete. Stash it into DB. */
13399 svn_hash_sets(wc_db->dir_data, wcroot->abspath, wcroot);
13400
13401 return SVN_NO_ERROR;
13402}
13403
12853
12854svn_error_t *
13404svn_error_t *
12855svn_wc__db_upgrade_apply_dav_cache(svn_sqlite__db_t *sdb,
12856 const char *dir_relpath,
12857 apr_hash_t *cache_values,
12858 apr_pool_t *scratch_pool)
12859{
12860 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
12861 apr_int64_t wc_id;
12862 apr_hash_index_t *hi;
12863 svn_sqlite__stmt_t *stmt;
12864
12865 SVN_ERR(svn_wc__db_util_fetch_wc_id(&wc_id, sdb, iterpool));
12866
12867 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
12868 STMT_UPDATE_BASE_NODE_DAV_CACHE));
12869
12870 /* Iterate over all the wcprops, writing each one to the wc_db. */
12871 for (hi = apr_hash_first(scratch_pool, cache_values);
12872 hi;
12873 hi = apr_hash_next(hi))
12874 {
12875 const char *name = svn__apr_hash_index_key(hi);
12876 apr_hash_t *props = svn__apr_hash_index_val(hi);
12877 const char *local_relpath;
12878
12879 svn_pool_clear(iterpool);
12880
12881 local_relpath = svn_relpath_join(dir_relpath, name, iterpool);
12882
12883 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
12884 SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, iterpool));
12885 SVN_ERR(svn_sqlite__step_done(stmt));
12886 }
12887
12888 svn_pool_destroy(iterpool);
12889
12890 return SVN_NO_ERROR;
12891}
12892
12893
12894svn_error_t *
12895svn_wc__db_upgrade_apply_props(svn_sqlite__db_t *sdb,
12896 const char *dir_abspath,
12897 const char *local_relpath,
12898 apr_hash_t *base_props,
12899 apr_hash_t *revert_props,
12900 apr_hash_t *working_props,
12901 int original_format,
12902 apr_int64_t wc_id,
12903 apr_pool_t *scratch_pool)
12904{
12905 svn_sqlite__stmt_t *stmt;
12906 svn_boolean_t have_row;
12907 int top_op_depth = -1;
12908 int below_op_depth = -1;
12909 svn_wc__db_status_t top_presence;
12910 svn_wc__db_status_t below_presence;
12911 int affected_rows;
12912
12913 /* ### working_props: use set_props_txn.
12914 ### if working_props == NULL, then skip. what if they equal the
12915 ### pristine props? we should probably do the compare here.
12916 ###
12917 ### base props go into WORKING_NODE if avail, otherwise BASE.
12918 ###
12919 ### revert only goes into BASE. (and WORKING better be there!)
12920
12921 Prior to 1.4.0 (ORIGINAL_FORMAT < 8), REVERT_PROPS did not exist. If a
12922 file was deleted, then a copy (potentially with props) was disallowed
12923 and could not replace the deletion. An addition *could* be performed,
12924 but that would never bring its own props.
12925
12926 1.4.0 through 1.4.5 created the concept of REVERT_PROPS, but had a
12927 bug in svn_wc_add_repos_file2() whereby a copy-with-props did NOT
12928 construct a REVERT_PROPS if the target had no props. Thus, reverting
12929 the delete/copy would see no REVERT_PROPS to restore, leaving the
12930 props from the copy source intact, and appearing as if they are (now)
12931 the base props for the previously-deleted file. (wc corruption)
12932
12933 1.4.6 ensured that an empty REVERT_PROPS would be established at all
12934 times. See issue 2530, and r861670 as starting points.
12935
12936 We will use ORIGINAL_FORMAT and SVN_WC__NO_REVERT_FILES to determine
12937 the handling of our inputs, relative to the state of this node.
12938 */
12939
12940 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODE_INFO));
12941 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
12942 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12943 if (have_row)
12944 {
12945 top_op_depth = svn_sqlite__column_int(stmt, 0);
12946 top_presence = svn_sqlite__column_token(stmt, 3, presence_map);
12947 SVN_ERR(svn_sqlite__step(&have_row, stmt));
12948 if (have_row)
12949 {
12950 below_op_depth = svn_sqlite__column_int(stmt, 0);
12951 below_presence = svn_sqlite__column_token(stmt, 3, presence_map);
12952 }
12953 }
12954 SVN_ERR(svn_sqlite__reset(stmt));
12955
12956 /* Detect the buggy scenario described above. We cannot upgrade this
12957 working copy if we have no idea where BASE_PROPS should go. */
12958 if (original_format > SVN_WC__NO_REVERT_FILES
12959 && revert_props == NULL
12960 && top_op_depth != -1
12961 && top_presence == svn_wc__db_status_normal
12962 && below_op_depth != -1
12963 && below_presence != svn_wc__db_status_not_present)
12964 {
12965 /* There should be REVERT_PROPS, so it appears that we just ran into
12966 the described bug. Sigh. */
12967 return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
12968 _("The properties of '%s' are in an "
12969 "indeterminate state and cannot be "
12970 "upgraded. See issue #2530."),
12971 svn_dirent_local_style(
12972 svn_dirent_join(dir_abspath, local_relpath,
12973 scratch_pool), scratch_pool));
12974 }
12975
12976 /* Need at least one row, or two rows if there are revert props */
12977 if (top_op_depth == -1
12978 || (below_op_depth == -1 && revert_props))
12979 return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
12980 _("Insufficient NODES rows for '%s'"),
12981 svn_dirent_local_style(
12982 svn_dirent_join(dir_abspath, local_relpath,
12983 scratch_pool), scratch_pool));
12984
12985 /* one row, base props only: upper row gets base props
12986 two rows, base props only: lower row gets base props
12987 two rows, revert props only: lower row gets revert props
12988 two rows, base and revert props: upper row gets base, lower gets revert */
12989
12990
12991 if (revert_props || below_op_depth == -1)
12992 {
12993 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
12994 STMT_UPDATE_NODE_PROPS));
12995 SVN_ERR(svn_sqlite__bindf(stmt, "isd",
12996 wc_id, local_relpath, top_op_depth));
12997 SVN_ERR(svn_sqlite__bind_properties(stmt, 4, base_props, scratch_pool));
12998 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
12999
13000 SVN_ERR_ASSERT(affected_rows == 1);
13001 }
13002
13003 if (below_op_depth != -1)
13004 {
13005 apr_hash_t *props = revert_props ? revert_props : base_props;
13006
13007 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
13008 STMT_UPDATE_NODE_PROPS));
13009 SVN_ERR(svn_sqlite__bindf(stmt, "isd",
13010 wc_id, local_relpath, below_op_depth));
13011 SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
13012 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
13013
13014 SVN_ERR_ASSERT(affected_rows == 1);
13015 }
13016
13017 /* If there are WORKING_PROPS, then they always go into ACTUAL_NODE. */
13018 if (working_props != NULL
13019 && base_props != NULL)
13020 {
13021 apr_array_header_t *diffs;
13022
13023 SVN_ERR(svn_prop_diffs(&diffs, working_props, base_props, scratch_pool));
13024
13025 if (diffs->nelts == 0)
13026 working_props = NULL; /* No differences */
13027 }
13028
13029 if (working_props != NULL)
13030 {
13031 SVN_ERR(set_actual_props(wc_id, local_relpath, working_props,
13032 sdb, scratch_pool));
13033 }
13034
13035 return SVN_NO_ERROR;
13036}
13037
13038svn_error_t *
13039svn_wc__db_upgrade_insert_external(svn_wc__db_t *db,
13040 const char *local_abspath,
13041 svn_node_kind_t kind,
13042 const char *parent_abspath,
13043 const char *def_local_abspath,
13044 const char *repos_relpath,
13045 const char *repos_root_url,
13046 const char *repos_uuid,

--- 58 unchanged lines hidden (view full) ---

13105 SVN_ERR(svn_sqlite__bind_revnum(stmt, 10, def_revision));
13106
13107 SVN_ERR(svn_sqlite__insert(NULL, stmt));
13108
13109 return SVN_NO_ERROR;
13110}
13111
13112svn_error_t *
13405svn_wc__db_upgrade_insert_external(svn_wc__db_t *db,
13406 const char *local_abspath,
13407 svn_node_kind_t kind,
13408 const char *parent_abspath,
13409 const char *def_local_abspath,
13410 const char *repos_relpath,
13411 const char *repos_root_url,
13412 const char *repos_uuid,

--- 58 unchanged lines hidden (view full) ---

13471 SVN_ERR(svn_sqlite__bind_revnum(stmt, 10, def_revision));
13472
13473 SVN_ERR(svn_sqlite__insert(NULL, stmt));
13474
13475 return SVN_NO_ERROR;
13476}
13477
13478svn_error_t *
13113svn_wc__db_upgrade_get_repos_id(apr_int64_t *repos_id,
13114 svn_sqlite__db_t *sdb,
13115 const char *repos_root_url,
13116 apr_pool_t *scratch_pool)
13479svn_wc__db_wq_add_internal(svn_wc__db_wcroot_t *wcroot,
13480 const svn_skel_t *work_item,
13481 apr_pool_t *scratch_pool)
13117{
13482{
13118 svn_sqlite__stmt_t *stmt;
13119 svn_boolean_t have_row;
13120
13121 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_REPOSITORY));
13122 SVN_ERR(svn_sqlite__bindf(stmt, "s", repos_root_url));
13123 SVN_ERR(svn_sqlite__step(&have_row, stmt));
13124
13125 if (!have_row)
13126 return svn_error_createf(SVN_ERR_WC_DB_ERROR, svn_sqlite__reset(stmt),
13127 _("Repository '%s' not found in the database"),
13128 repos_root_url);
13129
13130 *repos_id = svn_sqlite__column_int64(stmt, 0);
13131 return svn_error_trace(svn_sqlite__reset(stmt));
13483 /* Add the work item(s) to the WORK_QUEUE. */
13484 return svn_error_trace(add_work_items(wcroot->sdb, work_item,
13485 scratch_pool));
13132}
13133
13486}
13487
13134
13135svn_error_t *
13136svn_wc__db_wq_add(svn_wc__db_t *db,
13137 const char *wri_abspath,
13138 const svn_skel_t *work_item,
13139 apr_pool_t *scratch_pool)
13140{
13141 svn_wc__db_wcroot_t *wcroot;
13142 const char *local_relpath;

--- 96 unchanged lines hidden (view full) ---

13239 apr_pool_t *scratch_pool)
13240{
13241 apr_hash_index_t *hi;
13242 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
13243
13244 for (hi = apr_hash_first(scratch_pool, record_map); hi;
13245 hi = apr_hash_next(hi))
13246 {
13488svn_error_t *
13489svn_wc__db_wq_add(svn_wc__db_t *db,
13490 const char *wri_abspath,
13491 const svn_skel_t *work_item,
13492 apr_pool_t *scratch_pool)
13493{
13494 svn_wc__db_wcroot_t *wcroot;
13495 const char *local_relpath;

--- 96 unchanged lines hidden (view full) ---

13592 apr_pool_t *scratch_pool)
13593{
13594 apr_hash_index_t *hi;
13595 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
13596
13597 for (hi = apr_hash_first(scratch_pool, record_map); hi;
13598 hi = apr_hash_next(hi))
13599 {
13247 const char *local_abspath = svn__apr_hash_index_key(hi);
13248 const svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
13600 const char *local_abspath = apr_hash_this_key(hi);
13601 const svn_io_dirent2_t *dirent = apr_hash_this_val(hi);
13249 const char *local_relpath = svn_dirent_skip_ancestor(wcroot->abspath,
13250 local_abspath);
13251
13252 svn_pool_clear(iterpool);
13253
13254 if (! local_relpath)
13255 continue;
13256

--- 196 unchanged lines hidden (view full) ---

13453{
13454 apr_hash_t *result = apr_hash_make(result_pool);
13455 apr_hash_index_t *hi;
13456
13457 for (hi = apr_hash_first(result_pool, db->dir_data);
13458 hi;
13459 hi = apr_hash_next(hi))
13460 {
13602 const char *local_relpath = svn_dirent_skip_ancestor(wcroot->abspath,
13603 local_abspath);
13604
13605 svn_pool_clear(iterpool);
13606
13607 if (! local_relpath)
13608 continue;
13609

--- 196 unchanged lines hidden (view full) ---

13806{
13807 apr_hash_t *result = apr_hash_make(result_pool);
13808 apr_hash_index_t *hi;
13809
13810 for (hi = apr_hash_first(result_pool, db->dir_data);
13811 hi;
13812 hi = apr_hash_next(hi))
13813 {
13461 const svn_wc__db_wcroot_t *wcroot = svn__apr_hash_index_val(hi);
13814 const svn_wc__db_wcroot_t *wcroot = apr_hash_this_val(hi);
13462
13463 /* This is highly redundant, 'cause the same WCROOT will appear many
13464 times in dir_data. */
13465 result = apr_hash_overlay(result_pool, result, wcroot->access_cache);
13466 }
13467
13468 return result;
13469}

--- 170 unchanged lines hidden (view full) ---

13640 wcroot);
13641
13642 return SVN_NO_ERROR;
13643}
13644
13645
13646svn_error_t *
13647svn_wc__db_read_conflict(svn_skel_t **conflict,
13815
13816 /* This is highly redundant, 'cause the same WCROOT will appear many
13817 times in dir_data. */
13818 result = apr_hash_overlay(result_pool, result, wcroot->access_cache);
13819 }
13820
13821 return result;
13822}

--- 170 unchanged lines hidden (view full) ---

13993 wcroot);
13994
13995 return SVN_NO_ERROR;
13996}
13997
13998
13999svn_error_t *
14000svn_wc__db_read_conflict(svn_skel_t **conflict,
14001 svn_node_kind_t *kind,
14002 apr_hash_t **props,
13648 svn_wc__db_t *db,
13649 const char *local_abspath,
13650 apr_pool_t *result_pool,
13651 apr_pool_t *scratch_pool)
13652{
13653 svn_wc__db_wcroot_t *wcroot;
13654 const char *local_relpath;
13655
13656 /* The parent should be a working copy directory. */
13657 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13658 local_abspath, scratch_pool, scratch_pool));
13659 VERIFY_USABLE_WCROOT(wcroot);
13660
14003 svn_wc__db_t *db,
14004 const char *local_abspath,
14005 apr_pool_t *result_pool,
14006 apr_pool_t *scratch_pool)
14007{
14008 svn_wc__db_wcroot_t *wcroot;
14009 const char *local_relpath;
14010
14011 /* The parent should be a working copy directory. */
14012 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
14013 local_abspath, scratch_pool, scratch_pool));
14014 VERIFY_USABLE_WCROOT(wcroot);
14015
13661 return svn_error_trace(svn_wc__db_read_conflict_internal(conflict, wcroot,
13662 local_relpath,
14016 return svn_error_trace(svn_wc__db_read_conflict_internal(conflict, kind, props,
14017 wcroot, local_relpath,
13663 result_pool,
13664 scratch_pool));
13665}
13666
13667svn_error_t *
13668svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
14018 result_pool,
14019 scratch_pool));
14020}
14021
14022svn_error_t *
14023svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
14024 svn_node_kind_t *kind,
14025 apr_hash_t **props,
13669 svn_wc__db_wcroot_t *wcroot,
13670 const char *local_relpath,
13671 apr_pool_t *result_pool,
13672 apr_pool_t *scratch_pool)
13673{
13674 svn_sqlite__stmt_t *stmt;
13675 svn_boolean_t have_row;
13676
14026 svn_wc__db_wcroot_t *wcroot,
14027 const char *local_relpath,
14028 apr_pool_t *result_pool,
14029 apr_pool_t *scratch_pool)
14030{
14031 svn_sqlite__stmt_t *stmt;
14032 svn_boolean_t have_row;
14033
14034 if (kind)
14035 *kind = svn_node_none;
14036 if (props)
14037 *props = NULL;
14038
13677 /* Check if we have a conflict in ACTUAL */
13678 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
13679 STMT_SELECT_ACTUAL_NODE));
13680 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
13681
13682 SVN_ERR(svn_sqlite__step(&have_row, stmt));
13683
14039 /* Check if we have a conflict in ACTUAL */
14040 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14041 STMT_SELECT_ACTUAL_NODE));
14042 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
14043
14044 SVN_ERR(svn_sqlite__step(&have_row, stmt));
14045
13684 if (! have_row)
14046 if (have_row)
13685 {
14047 {
13686 /* Do this while stmt is still open to avoid closing the sqlite
13687 transaction and then reopening. */
13688 svn_sqlite__stmt_t *stmt_node;
13689 svn_error_t *err;
14048 apr_size_t cfl_len;
14049 const void *cfl_data;
13690
14050
13691 err = svn_sqlite__get_statement(&stmt_node, wcroot->sdb,
13692 STMT_SELECT_NODE_INFO);
14051 /* svn_skel__parse doesn't copy data, so store in result_pool */
14052 cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
13693
14053
13694 if (err)
13695 stmt_node = NULL;
14054 if (cfl_data)
14055 *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
13696 else
14056 else
13697 err = svn_sqlite__bindf(stmt_node, "is", wcroot->wc_id,
13698 local_relpath);
14057 *conflict = NULL;
13699
14058
13700 if (!err)
13701 err = svn_sqlite__step(&have_row, stmt_node);
14059 if (props)
14060 {
14061 svn_error_t *err;
13702
14062
13703 if (stmt_node)
13704 err = svn_error_compose_create(err,
13705 svn_sqlite__reset(stmt_node));
14063 err = svn_error_trace(svn_sqlite__column_properties(props, stmt, 1,
14064 result_pool,
14065 scratch_pool));
13706
14066
13707 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
14067 if (err)
14068 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
14069 }
14070 }
14071 else
14072 *conflict = NULL;
13708
14073
13709 if (have_row)
14074 SVN_ERR(svn_sqlite__reset(stmt));
14075
14076 if (!have_row || kind || (props && !*props))
14077 {
14078 svn_error_t *err = NULL;
14079 svn_boolean_t have_info = FALSE;
14080
14081 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14082 STMT_SELECT_NODE_INFO));
14083
14084 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
14085 local_relpath));
14086
14087 SVN_ERR(svn_sqlite__step(&have_info, stmt));
14088
14089 if (have_info)
13710 {
14090 {
13711 *conflict = NULL;
13712 return SVN_NO_ERROR;
14091 if (kind)
14092 {
14093 svn_wc__db_status_t status;
14094 int op_depth = svn_sqlite__column_int(stmt, 0);
14095
14096 status = svn_sqlite__column_token(stmt, 3, presence_map);
14097
14098 if (op_depth > 0)
14099 err = convert_to_working_status(&status, status);
14100
14101 if (!err && (status == svn_wc__db_status_normal
14102 || status == svn_wc__db_status_added
14103 || status == svn_wc__db_status_deleted
14104 || status == svn_wc__db_status_incomplete))
14105 {
14106 *kind = svn_sqlite__column_token(stmt, 4, kind_map);
14107 }
14108 }
14109
14110 /* Need props, and no props in ACTUAL? */
14111 if (!err && (props && !*props))
14112 {
14113 err = svn_sqlite__column_properties(props, stmt, 14,
14114 result_pool, scratch_pool);
14115 }
13713 }
13714
14116 }
14117
13715 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
13716 _("The node '%s' was not found."),
14118 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
14119
14120 if (!have_row && !have_info)
14121 {
14122 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
14123 _("The node '%s' was not found."),
13717 path_for_error_message(wcroot,
13718 local_relpath,
13719 scratch_pool));
14124 path_for_error_message(wcroot,
14125 local_relpath,
14126 scratch_pool));
14127 }
13720 }
13721
14128 }
14129
13722 {
13723 apr_size_t cfl_len;
13724 const void *cfl_data;
13725
13726 /* svn_skel__parse doesn't copy data, so store in result_pool */
13727 cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
13728
13729 if (cfl_data)
13730 *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
13731 else
13732 *conflict = NULL;
13733
13734 return svn_error_trace(svn_sqlite__reset(stmt));
13735 }
14130 return SVN_NO_ERROR;
13736}
13737
13738
13739svn_error_t *
13740svn_wc__db_read_kind(svn_node_kind_t *kind,
13741 svn_wc__db_t *db,
13742 const char *local_abspath,
13743 svn_boolean_t allow_missing,
13744 svn_boolean_t show_deleted,
13745 svn_boolean_t show_hidden,
13746 apr_pool_t *scratch_pool)
13747{
13748 svn_wc__db_wcroot_t *wcroot;
13749 const char *local_relpath;
13750 svn_sqlite__stmt_t *stmt_info;
13751 svn_boolean_t have_info;
14131}
14132
14133
14134svn_error_t *
14135svn_wc__db_read_kind(svn_node_kind_t *kind,
14136 svn_wc__db_t *db,
14137 const char *local_abspath,
14138 svn_boolean_t allow_missing,
14139 svn_boolean_t show_deleted,
14140 svn_boolean_t show_hidden,
14141 apr_pool_t *scratch_pool)
14142{
14143 svn_wc__db_wcroot_t *wcroot;
14144 const char *local_relpath;
14145 svn_sqlite__stmt_t *stmt_info;
14146 svn_boolean_t have_info;
14147 svn_wc__db_status_t status;
13752
13753 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
13754
13755 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13756 local_abspath, scratch_pool, scratch_pool));
13757 VERIFY_USABLE_WCROOT(wcroot);
13758
13759 SVN_ERR(svn_sqlite__get_statement(&stmt_info, wcroot->sdb,

--- 15 unchanged lines hidden (view full) ---

13775 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
13776 _("The node '%s' was not found."),
13777 path_for_error_message(wcroot,
13778 local_relpath,
13779 scratch_pool));
13780 }
13781 }
13782
14148
14149 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
14150
14151 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
14152 local_abspath, scratch_pool, scratch_pool));
14153 VERIFY_USABLE_WCROOT(wcroot);
14154
14155 SVN_ERR(svn_sqlite__get_statement(&stmt_info, wcroot->sdb,

--- 15 unchanged lines hidden (view full) ---

14171 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
14172 _("The node '%s' was not found."),
14173 path_for_error_message(wcroot,
14174 local_relpath,
14175 scratch_pool));
14176 }
14177 }
14178
14179 status = svn_sqlite__column_token(stmt_info, 3, presence_map);
14180
14181 if (show_deleted && status == svn_wc__db_status_base_deleted)
14182 {
14183 /* Let's return the kind of what is really deleted insead of what
14184 we have cached in the base-deleted record */
14185
14186 SVN_ERR(svn_sqlite__step(&have_info, stmt_info));
14187
14188 if (!have_info)
14189 {
14190 /* No lower layer deleted? Database inconsistency! */
14191 *kind = svn_node_none;
14192 return svn_error_trace(svn_sqlite__reset(stmt_info));
14193 }
14194 }
14195
13783 if (!(show_deleted && show_hidden))
13784 {
13785 int op_depth = svn_sqlite__column_int(stmt_info, 0);
13786 svn_boolean_t report_none = FALSE;
14196 if (!(show_deleted && show_hidden))
14197 {
14198 int op_depth = svn_sqlite__column_int(stmt_info, 0);
14199 svn_boolean_t report_none = FALSE;
13787 svn_wc__db_status_t status = svn_sqlite__column_token(stmt_info, 3,
13788 presence_map);
13789
13790 if (op_depth > 0)
13791 SVN_ERR(convert_to_working_status(&status, status));
13792
13793 switch (status)
13794 {
13795 case svn_wc__db_status_not_present:
13796 if (! (show_hidden && show_deleted))

--- 19 unchanged lines hidden (view full) ---

13816 }
13817 }
13818
13819 *kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
13820
13821 return svn_error_trace(svn_sqlite__reset(stmt_info));
13822}
13823
14200
14201 if (op_depth > 0)
14202 SVN_ERR(convert_to_working_status(&status, status));
14203
14204 switch (status)
14205 {
14206 case svn_wc__db_status_not_present:
14207 if (! (show_hidden && show_deleted))

--- 19 unchanged lines hidden (view full) ---

14227 }
14228 }
14229
14230 *kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
14231
14232 return svn_error_trace(svn_sqlite__reset(stmt_info));
14233}
14234
13824
13825svn_error_t *
14235svn_error_t *
13826svn_wc__db_node_hidden(svn_boolean_t *hidden,
13827 svn_wc__db_t *db,
13828 const char *local_abspath,
13829 apr_pool_t *scratch_pool)
13830{
13831 svn_wc__db_wcroot_t *wcroot;
13832 const char *local_relpath;
13833 svn_wc__db_status_t status;
13834
13835 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
13836
13837 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
13838 local_abspath, scratch_pool, scratch_pool));
13839 VERIFY_USABLE_WCROOT(wcroot);
13840
13841 SVN_ERR(read_info(&status, NULL, NULL, NULL, NULL, NULL,
13842 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
13843 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
13844 NULL, NULL, NULL,
13845 wcroot, local_relpath,
13846 scratch_pool, scratch_pool));
13847
13848 *hidden = (status == svn_wc__db_status_server_excluded
13849 || status == svn_wc__db_status_not_present
13850 || status == svn_wc__db_status_excluded);
13851
13852 return SVN_NO_ERROR;
13853}
13854
13855
13856svn_error_t *
13857svn_wc__db_is_wcroot(svn_boolean_t *is_wcroot,
13858 svn_wc__db_t *db,
13859 const char *local_abspath,
13860 apr_pool_t *scratch_pool)
13861{
13862 svn_wc__db_wcroot_t *wcroot;
13863 const char *local_relpath;
13864

--- 147 unchanged lines hidden (view full) ---

14012 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
14013 wri_abspath, scratch_pool, scratch_pool));
14014 VERIFY_USABLE_WCROOT(wcroot);
14015
14016 *temp_dir_abspath = svn_dirent_join_many(result_pool,
14017 wcroot->abspath,
14018 svn_wc_get_adm_dir(scratch_pool),
14019 WCROOT_TEMPDIR_RELPATH,
14236svn_wc__db_is_wcroot(svn_boolean_t *is_wcroot,
14237 svn_wc__db_t *db,
14238 const char *local_abspath,
14239 apr_pool_t *scratch_pool)
14240{
14241 svn_wc__db_wcroot_t *wcroot;
14242 const char *local_relpath;
14243

--- 147 unchanged lines hidden (view full) ---

14391 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
14392 wri_abspath, scratch_pool, scratch_pool));
14393 VERIFY_USABLE_WCROOT(wcroot);
14394
14395 *temp_dir_abspath = svn_dirent_join_many(result_pool,
14396 wcroot->abspath,
14397 svn_wc_get_adm_dir(scratch_pool),
14398 WCROOT_TEMPDIR_RELPATH,
14020 NULL);
14399 SVN_VA_NULL);
14021 return SVN_NO_ERROR;
14022}
14023
14024
14025/* Helper for wclock_obtain_cb() to steal an existing lock */
14026static svn_error_t *
14027wclock_steal(svn_wc__db_wcroot_t *wcroot,
14028 const char *local_relpath,

--- 12 unchanged lines hidden (view full) ---

14041
14042/* The body of svn_wc__db_wclock_obtain().
14043 */
14044static svn_error_t *
14045wclock_obtain_cb(svn_wc__db_wcroot_t *wcroot,
14046 const char *local_relpath,
14047 int levels_to_lock,
14048 svn_boolean_t steal_lock,
14400 return SVN_NO_ERROR;
14401}
14402
14403
14404/* Helper for wclock_obtain_cb() to steal an existing lock */
14405static svn_error_t *
14406wclock_steal(svn_wc__db_wcroot_t *wcroot,
14407 const char *local_relpath,

--- 12 unchanged lines hidden (view full) ---

14420
14421/* The body of svn_wc__db_wclock_obtain().
14422 */
14423static svn_error_t *
14424wclock_obtain_cb(svn_wc__db_wcroot_t *wcroot,
14425 const char *local_relpath,
14426 int levels_to_lock,
14427 svn_boolean_t steal_lock,
14428 svn_boolean_t enforce_empty_wq,
14049 apr_pool_t *scratch_pool)
14050{
14051 svn_sqlite__stmt_t *stmt;
14052 svn_error_t *err;
14053 const char *lock_relpath;
14054 int max_depth;
14055 int lock_depth;
14056 svn_boolean_t got_row;

--- 13 unchanged lines hidden (view full) ---

14070 if (!exists)
14071 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
14072 _("The node '%s' was not found."),
14073 path_for_error_message(wcroot,
14074 local_relpath,
14075 scratch_pool));
14076 }
14077
14429 apr_pool_t *scratch_pool)
14430{
14431 svn_sqlite__stmt_t *stmt;
14432 svn_error_t *err;
14433 const char *lock_relpath;
14434 int max_depth;
14435 int lock_depth;
14436 svn_boolean_t got_row;

--- 13 unchanged lines hidden (view full) ---

14450 if (!exists)
14451 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
14452 _("The node '%s' was not found."),
14453 path_for_error_message(wcroot,
14454 local_relpath,
14455 scratch_pool));
14456 }
14457
14458 if (enforce_empty_wq)
14459 SVN_ERR(svn_wc__db_verify_no_work(wcroot->sdb));
14460
14078 /* Check if there are nodes locked below the new lock root */
14079 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_FIND_WC_LOCK));
14080 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
14081
14082 lock_depth = relpath_depth(local_relpath);
14083 max_depth = lock_depth + levels_to_lock;
14084
14085 SVN_ERR(svn_sqlite__step(&got_row, stmt));

--- 10 unchanged lines hidden (view full) ---

14096 && relpath_depth(lock_relpath) > max_depth)
14097 {
14098 SVN_ERR(svn_sqlite__step(&got_row, stmt));
14099 continue;
14100 }
14101
14102 /* Check if we are the lock owner, because we should be able to
14103 extend our lock. */
14461 /* Check if there are nodes locked below the new lock root */
14462 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_FIND_WC_LOCK));
14463 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
14464
14465 lock_depth = relpath_depth(local_relpath);
14466 max_depth = lock_depth + levels_to_lock;
14467
14468 SVN_ERR(svn_sqlite__step(&got_row, stmt));

--- 10 unchanged lines hidden (view full) ---

14479 && relpath_depth(lock_relpath) > max_depth)
14480 {
14481 SVN_ERR(svn_sqlite__step(&got_row, stmt));
14482 continue;
14483 }
14484
14485 /* Check if we are the lock owner, because we should be able to
14486 extend our lock. */
14104 err = wclock_owns_lock(&own_lock, wcroot, lock_relpath,
14105 TRUE, scratch_pool);
14487 err = svn_wc__db_wclock_owns_lock_internal(&own_lock, wcroot,
14488 lock_relpath,
14489 TRUE, scratch_pool);
14106
14107 if (err)
14108 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
14109
14110 if (!own_lock && !steal_lock)
14111 {
14112 SVN_ERR(svn_sqlite__reset(stmt));
14113 err = svn_error_createf(SVN_ERR_WC_LOCKED, NULL,

--- 71 unchanged lines hidden (view full) ---

14185 }
14186
14187 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_WC_LOCK));
14188 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
14189 levels_to_lock));
14190 err = svn_sqlite__insert(NULL, stmt);
14191 if (err)
14192 return svn_error_createf(SVN_ERR_WC_LOCKED, err,
14490
14491 if (err)
14492 SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
14493
14494 if (!own_lock && !steal_lock)
14495 {
14496 SVN_ERR(svn_sqlite__reset(stmt));
14497 err = svn_error_createf(SVN_ERR_WC_LOCKED, NULL,

--- 71 unchanged lines hidden (view full) ---

14569 }
14570
14571 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_WC_LOCK));
14572 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
14573 levels_to_lock));
14574 err = svn_sqlite__insert(NULL, stmt);
14575 if (err)
14576 return svn_error_createf(SVN_ERR_WC_LOCKED, err,
14193 _("Working copy '%s' locked"),
14577 _("Failed to lock working copy '%s'."),
14194 path_for_error_message(wcroot,
14195 local_relpath,
14196 scratch_pool));
14197
14198 /* And finally store that we obtained the lock */
14199 lock.local_relpath = apr_pstrdup(wcroot->owned_locks->pool, local_relpath);
14200 lock.levels = levels_to_lock;
14201 APR_ARRAY_PUSH(wcroot->owned_locks, svn_wc__db_wclock_t) = lock;

--- 42 unchanged lines hidden (view full) ---

14244 path_for_error_message(wcroot, lock->local_relpath,
14245 scratch_pool));
14246 }
14247 }
14248 }
14249
14250 SVN_WC__DB_WITH_TXN(
14251 wclock_obtain_cb(wcroot, local_relpath, levels_to_lock, steal_lock,
14578 path_for_error_message(wcroot,
14579 local_relpath,
14580 scratch_pool));
14581
14582 /* And finally store that we obtained the lock */
14583 lock.local_relpath = apr_pstrdup(wcroot->owned_locks->pool, local_relpath);
14584 lock.levels = levels_to_lock;
14585 APR_ARRAY_PUSH(wcroot->owned_locks, svn_wc__db_wclock_t) = lock;

--- 42 unchanged lines hidden (view full) ---

14628 path_for_error_message(wcroot, lock->local_relpath,
14629 scratch_pool));
14630 }
14631 }
14632 }
14633
14634 SVN_WC__DB_WITH_TXN(
14635 wclock_obtain_cb(wcroot, local_relpath, levels_to_lock, steal_lock,
14252 scratch_pool),
14636 db->enforce_empty_wq, scratch_pool),
14253 wcroot);
14254 return SVN_NO_ERROR;
14255}
14256
14257
14258/* The body of svn_wc__db_wclock_find_root() and svn_wc__db_wclocked(). */
14259static svn_error_t *
14260find_wclock(const char **lock_relpath,

--- 174 unchanged lines hidden (view full) ---

14435 SVN_ERR(svn_sqlite__step_done(stmt));
14436
14437 return SVN_NO_ERROR;
14438}
14439
14440
14441/* Like svn_wc__db_wclock_owns_lock() but taking WCROOT+LOCAL_RELPATH instead
14442 of DB+LOCAL_ABSPATH. */
14637 wcroot);
14638 return SVN_NO_ERROR;
14639}
14640
14641
14642/* The body of svn_wc__db_wclock_find_root() and svn_wc__db_wclocked(). */
14643static svn_error_t *
14644find_wclock(const char **lock_relpath,

--- 174 unchanged lines hidden (view full) ---

14819 SVN_ERR(svn_sqlite__step_done(stmt));
14820
14821 return SVN_NO_ERROR;
14822}
14823
14824
14825/* Like svn_wc__db_wclock_owns_lock() but taking WCROOT+LOCAL_RELPATH instead
14826 of DB+LOCAL_ABSPATH. */
14443static svn_error_t *
14444wclock_owns_lock(svn_boolean_t *own_lock,
14445 svn_wc__db_wcroot_t *wcroot,
14446 const char *local_relpath,
14447 svn_boolean_t exact,
14448 apr_pool_t *scratch_pool)
14827svn_error_t *
14828svn_wc__db_wclock_owns_lock_internal(svn_boolean_t *own_lock,
14829 svn_wc__db_wcroot_t *wcroot,
14830 const char *local_relpath,
14831 svn_boolean_t exact,
14832 apr_pool_t *scratch_pool)
14449{
14450 apr_array_header_t *owned_locks;
14451 int lock_level;
14452 int i;
14453
14454 *own_lock = FALSE;
14455 owned_locks = wcroot->owned_locks;
14456 lock_level = relpath_depth(local_relpath);

--- 50 unchanged lines hidden (view full) ---

14507 if (!wcroot)
14508 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
14509 _("The node '%s' was not found."),
14510 svn_dirent_local_style(local_abspath,
14511 scratch_pool));
14512
14513 VERIFY_USABLE_WCROOT(wcroot);
14514
14833{
14834 apr_array_header_t *owned_locks;
14835 int lock_level;
14836 int i;
14837
14838 *own_lock = FALSE;
14839 owned_locks = wcroot->owned_locks;
14840 lock_level = relpath_depth(local_relpath);

--- 50 unchanged lines hidden (view full) ---

14891 if (!wcroot)
14892 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
14893 _("The node '%s' was not found."),
14894 svn_dirent_local_style(local_abspath,
14895 scratch_pool));
14896
14897 VERIFY_USABLE_WCROOT(wcroot);
14898
14515 SVN_ERR(wclock_owns_lock(own_lock, wcroot, local_relpath, exact,
14516 scratch_pool));
14899 SVN_ERR(svn_wc__db_wclock_owns_lock_internal(own_lock, wcroot, local_relpath,
14900 exact, scratch_pool));
14517
14518 return SVN_NO_ERROR;
14519}
14520
14521/* The body of svn_wc__db_temp_op_end_directory_update().
14522 */
14523static svn_error_t *
14524end_directory_update(svn_wc__db_wcroot_t *wcroot,

--- 99 unchanged lines hidden (view full) ---

14624 new_repos_relpath, new_rev, scratch_pool),
14625 wcroot);
14626
14627 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
14628
14629 return SVN_NO_ERROR;
14630}
14631
14901
14902 return SVN_NO_ERROR;
14903}
14904
14905/* The body of svn_wc__db_temp_op_end_directory_update().
14906 */
14907static svn_error_t *
14908end_directory_update(svn_wc__db_wcroot_t *wcroot,

--- 99 unchanged lines hidden (view full) ---

15008 new_repos_relpath, new_rev, scratch_pool),
15009 wcroot);
15010
15011 SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
15012
15013 return SVN_NO_ERROR;
15014}
15015
15016/* Helper for svn_wc__db_op_make_copy_internal */
15017static svn_error_t *
15018db_move_moved_to(svn_wc__db_wcroot_t *wcroot,
15019 const char *src1_relpath,
15020 int src1_op_depth,
15021 const char *src2_relpath,
15022 int src2_op_depth,
15023 const char *dst_relpath,
15024 apr_pool_t *scratch_pool)
15025{
15026 svn_sqlite__stmt_t *stmt;
15027 int affected_rows;
14632
15028
15029 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15030 STMT_UPDATE_MOVED_TO_RELPATH));
15031 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
15032 src1_relpath, src1_op_depth));
15033 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
15034
15035 if (affected_rows == 1)
15036 {
15037 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15038 STMT_UPDATE_MOVED_TO_RELPATH));
15039 SVN_ERR(svn_sqlite__bindf(stmt, "isds", wcroot->wc_id,
15040 src2_relpath, src2_op_depth,
15041 dst_relpath));
15042 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
15043 }
15044 if (affected_rows != 1)
15045 return svn_error_create(SVN_ERR_WC_PATH_NOT_FOUND, NULL, NULL);
15046
15047 return SVN_NO_ERROR;
15048}
15049
15050static svn_error_t *
15051db_move_moved_to_down_recursive(svn_wc__db_wcroot_t *wcroot,
15052 const char *local_relpath,
15053 int new_shadow_layer,
15054 apr_pool_t *scratch_pool)
15055{
15056 svn_sqlite__stmt_t *stmt;
15057 svn_boolean_t have_row;
15058 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
15059
15060 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15061 STMT_SELECT_MOVED_DESCENDANTS_SRC));
15062 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
15063 new_shadow_layer));
15064 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15065
15066 while (have_row)
15067 {
15068 int del_op_depth;
15069 const char *src_relpath;
15070 const char *dst_relpath;
15071 svn_error_t *err;
15072
15073 svn_pool_clear(iterpool);
15074
15075 del_op_depth = svn_sqlite__column_int(stmt, 0);
15076 src_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
15077 dst_relpath = svn_sqlite__column_text(stmt, 4, iterpool);
15078
15079 err = svn_error_trace(
15080 db_move_moved_to(
15081 wcroot,
15082 src_relpath, del_op_depth,
15083 src_relpath, new_shadow_layer,
15084 dst_relpath, iterpool));
15085
15086 if (err)
15087 return svn_error_compose_create(err, svn_sqlite__reset(stmt));
15088
15089 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15090 }
15091
15092 SVN_ERR(svn_sqlite__reset(stmt));
15093
15094 return SVN_NO_ERROR;
15095}
15096
15097
14633/* The body of svn_wc__db_temp_op_make_copy(). This is
14634 used by the update editor when deleting a base node tree would be a
14635 tree-conflict because there are changes to subtrees. This function
14636 inserts a copy of the base node tree below any existing working
14637 subtrees. Given a tree:
14638
14639 0 1 2 3
14640 / normal -

--- 20 unchanged lines hidden (view full) ---

14661 A/F/H normal norm not-pres
14662 A/F/E normal norm base-del
14663 A/X normal norm
14664 A/X/Y incomplete incomplete
14665 */
14666static svn_error_t *
14667make_copy_txn(svn_wc__db_wcroot_t *wcroot,
14668 const char *local_relpath,
15098/* The body of svn_wc__db_temp_op_make_copy(). This is
15099 used by the update editor when deleting a base node tree would be a
15100 tree-conflict because there are changes to subtrees. This function
15101 inserts a copy of the base node tree below any existing working
15102 subtrees. Given a tree:
15103
15104 0 1 2 3
15105 / normal -

--- 20 unchanged lines hidden (view full) ---

15126 A/F/H normal norm not-pres
15127 A/F/E normal norm base-del
15128 A/X normal norm
15129 A/X/Y incomplete incomplete
15130 */
15131static svn_error_t *
15132make_copy_txn(svn_wc__db_wcroot_t *wcroot,
15133 const char *local_relpath,
14669 int op_depth,
14670 const svn_skel_t *conflicts,
14671 const svn_skel_t *work_items,
15134 apr_int64_t last_repos_id,
15135 const char *last_repos_relpath,
15136 svn_revnum_t last_revision,
15137 int last_op_depth,
15138 svn_boolean_t shadowed,
15139 int root_shadow_depth,
14672 apr_pool_t *scratch_pool)
14673{
14674 svn_sqlite__stmt_t *stmt;
15140 apr_pool_t *scratch_pool)
15141{
15142 svn_sqlite__stmt_t *stmt;
14675 svn_boolean_t have_row;
14676 svn_boolean_t add_working_base_deleted = FALSE;
14677 svn_boolean_t remove_working = FALSE;
14678 const apr_array_header_t *children;
14679 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
14680 int i;
15143 svn_boolean_t have_row = FALSE;
15144 svn_revnum_t revision;
15145 apr_int64_t repos_id;
15146 const char *repos_relpath;
15147 svn_node_kind_t kind;
15148 int op_depth = relpath_depth(local_relpath);
14681
15149
14682 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14683 STMT_SELECT_LOWEST_WORKING_NODE));
14684 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath, 0));
14685 SVN_ERR(svn_sqlite__step(&have_row, stmt));
14686
14687 if (have_row)
15150 if (last_op_depth != op_depth)
14688 {
15151 {
14689 svn_wc__db_status_t working_status;
14690 int working_op_depth;
14691
14692 working_status = svn_sqlite__column_token(stmt, 1, presence_map);
14693 working_op_depth = svn_sqlite__column_int(stmt, 0);
15152 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15153 STMT_SELECT_DEPTH_NODE));
15154 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
15155 op_depth));
15156 SVN_ERR(svn_sqlite__step(&have_row, stmt));
14694 SVN_ERR(svn_sqlite__reset(stmt));
15157 SVN_ERR(svn_sqlite__reset(stmt));
15158 if (have_row)
15159 shadowed = TRUE;
15160 }
14695
15161
14696 SVN_ERR_ASSERT(working_status == svn_wc__db_status_normal
14697 || working_status == svn_wc__db_status_base_deleted
14698 || working_status == svn_wc__db_status_not_present
14699 || working_status == svn_wc__db_status_incomplete);
15162 SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &kind, &revision,
15163 &repos_relpath, &repos_id, NULL,
15164 NULL, NULL, NULL, NULL, NULL, NULL,
15165 NULL, NULL, NULL,
15166 wcroot, local_relpath,
15167 scratch_pool, scratch_pool));
14700
15168
14701 /* Only change nodes in the layers where we are creating the copy.
14702 Deletes in higher layers will just apply to the copy */
14703 if (working_op_depth <= op_depth)
14704 {
14705 add_working_base_deleted = TRUE;
15169 if (last_repos_relpath
15170 && repos_id == last_repos_id
15171 && revision == last_revision)
15172 {
15173 const char *name = svn_relpath_skip_ancestor(last_repos_relpath,
15174 repos_relpath);
14706
15175
14707 if (working_status == svn_wc__db_status_base_deleted)
14708 remove_working = TRUE;
14709 }
15176 if (name && strcmp(name, svn_relpath_basename(local_relpath, NULL)) == 0)
15177 op_depth = last_op_depth;
14710 }
15178 }
14711 else
14712 SVN_ERR(svn_sqlite__reset(stmt));
14713
15179
14714 if (remove_working)
15180 /* Can we add a new copy node at the wanted op-depth? */
15181 if (!have_row || op_depth == last_op_depth)
14715 {
15182 {
14716 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14717 STMT_DELETE_LOWEST_WORKING_NODE));
14718 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
14719 SVN_ERR(svn_sqlite__step_done(stmt));
14720 }
15183 int i;
14721
15184
14722 if (add_working_base_deleted)
14723 {
14724 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14725 STMT_INSERT_DELETE_FROM_BASE));
15185 SVN_ERR(svn_sqlite__get_statement(
15186 &stmt, wcroot->sdb,
15187 STMT_INSERT_WORKING_NODE_FROM_BASE_COPY));
14726 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
14727 op_depth));
14728 SVN_ERR(svn_sqlite__step_done(stmt));
15188 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
15189 op_depth));
15190 SVN_ERR(svn_sqlite__step_done(stmt));
15191
15192 if (shadowed)
15193 SVN_ERR(db_extend_parent_delete(wcroot, local_relpath, kind,
15194 op_depth, scratch_pool));
15195
15196 if (kind == svn_node_dir)
15197 {
15198 const apr_array_header_t *children;
15199 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
15200
15201 SVN_ERR(gather_children(&children, wcroot, local_relpath,
15202 STMT_SELECT_OP_DEPTH_CHILDREN, 0,
15203 scratch_pool, iterpool));
15204
15205 for (i = 0; i < children->nelts; i++)
15206 {
15207 const char *name = APR_ARRAY_IDX(children, i, const char *);
15208 const char *copy_relpath;
15209
15210 svn_pool_clear(iterpool);
15211
15212 copy_relpath = svn_relpath_join(local_relpath, name, iterpool);
15213
15214 SVN_ERR(make_copy_txn(wcroot, copy_relpath,
15215 repos_id, repos_relpath, revision,
15216 op_depth, shadowed, root_shadow_depth,
15217 scratch_pool));
15218 }
15219 svn_pool_destroy(iterpool);
15220 }
14729 }
14730 else
14731 {
15221 }
15222 else
15223 {
15224 /* Auch... we can't make a copy of whatever comes deeper, as this
15225 op-depth is already filled by something else. Let's hope
15226 the user doesn't mind.
15227
15228 Luckily we know that the moves are already moved to the shadowing
15229 layer, so we can just remove dangling base-deletes if there are
15230 any.
15231 */
15232 /* BASE_DELETED may be at op_depth, so let's use last_op_depth! */
15233 SVN_ERR(db_move_moved_to_down_recursive(wcroot, local_relpath,
15234 root_shadow_depth,
15235 scratch_pool));
15236
14732 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15237 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14733 STMT_INSERT_WORKING_NODE_FROM_BASE_COPY));
15238 STMT_DELETE_WORKING_BASE_DELETE));
14734 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
15239 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
14735 op_depth));
15240 last_op_depth));
14736 SVN_ERR(svn_sqlite__step_done(stmt));
15241 SVN_ERR(svn_sqlite__step_done(stmt));
15242 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15243 STMT_DELETE_WORKING_BASE_DELETE_RECURSIVE));
15244 SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
15245 last_op_depth));
15246 SVN_ERR(svn_sqlite__step_done(stmt));
14737 }
14738
15247 }
15248
14739 /* Get the BASE children, as WORKING children don't need modifications */
14740 SVN_ERR(gather_repo_children(&children, wcroot, local_relpath,
14741 0, scratch_pool, iterpool));
15249 /* Insert a not-present node to mark that we don't know what exists here.
14742
15250
14743 for (i = 0; i < children->nelts; i++)
15251 We do this last (after recursing), to allow the move fix-up code to
15252 see the original moves. */
15253 if (last_op_depth > 0 && last_op_depth != op_depth)
14744 {
15254 {
14745 const char *name = APR_ARRAY_IDX(children, i, const char *);
14746 const char *copy_relpath;
15255 insert_working_baton_t iwb;
14747
15256
14748 svn_pool_clear(iterpool);
15257 blank_iwb(&iwb);
15258 iwb.presence = svn_wc__db_status_not_present;
15259 iwb.op_depth = last_op_depth;
14749
15260
14750 copy_relpath = svn_relpath_join(local_relpath, name, iterpool);
15261 iwb.original_repos_id = repos_id;
15262 iwb.original_repos_relpath = repos_relpath;
15263 iwb.original_revnum = revision;
15264 iwb.kind = kind;
14751
15265
14752 SVN_ERR(make_copy_txn(wcroot, copy_relpath, op_depth, NULL, NULL,
14753 iterpool));
15266 SVN_ERR(insert_working_node(&iwb, wcroot, local_relpath, scratch_pool));
14754 }
14755
15267 }
15268
14756 SVN_ERR(flush_entries(wcroot, svn_dirent_join(wcroot->abspath, local_relpath,
14757 iterpool),
14758 svn_depth_empty, iterpool));
15269 return SVN_NO_ERROR;
15270}
14759
15271
15272
15273svn_error_t *
15274svn_wc__db_op_make_copy_internal(svn_wc__db_wcroot_t *wcroot,
15275 const char *local_relpath,
15276 svn_boolean_t move_move_info,
15277 const svn_skel_t *conflicts,
15278 const svn_skel_t *work_items,
15279 apr_pool_t *scratch_pool)
15280{
15281 svn_sqlite__stmt_t *stmt;
15282 svn_boolean_t have_row;
15283 int op_depth = -1;
15284
15285 /* The update editor is supposed to call this function when there is
15286 no working node for LOCAL_ABSPATH. */
15287 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15288 STMT_SELECT_WORKING_NODE));
15289 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15290 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15291 if (have_row)
15292 op_depth = svn_sqlite__column_int(stmt, 0);
15293 SVN_ERR(svn_sqlite__reset(stmt));
15294
15295 if (have_row)
15296 {
15297 if (op_depth == relpath_depth(local_relpath))
15298 return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
15299 _("Modification of '%s' already exists"),
15300 path_for_error_message(wcroot,
15301 local_relpath,
15302 scratch_pool));
15303
15304 /* We have a working layer, but not one at the op-depth of local-relpath,
15305 so we can create a copy by just copying the lower layer */
15306
15307 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15308 STMT_COPY_OP_DEPTH_RECURSIVE));
15309 SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, local_relpath,
15310 op_depth, relpath_depth(local_relpath)));
15311 SVN_ERR(svn_sqlite__step_done(stmt));
15312 }
15313 else
15314 {
15315 int affected_rows;
15316
15317 op_depth = relpath_depth(local_relpath);
15318 /* We don't allow copies to contain server-excluded nodes;
15319 the update editor is going to have to bail out. */
15320 SVN_ERR(catch_copy_of_server_excluded(wcroot, local_relpath,
15321 scratch_pool));
15322
15323 /* Insert a shadowing layer */
15324 SVN_ERR(svn_sqlite__get_statement(
15325 &stmt, wcroot->sdb,
15326 STMT_INSERT_DELETE_FROM_NODE_RECURSIVE));
15327
15328 /* As we are keeping whatever is below, move the*/
15329
15330 SVN_ERR(svn_sqlite__bindf(stmt, "isdd",
15331 wcroot->wc_id, local_relpath,
15332 0, op_depth));
15333 SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
15334 SVN_ERR_ASSERT(affected_rows > 0);
15335
15336 if (!move_move_info)
15337 SVN_ERR(db_move_moved_to_down_recursive(wcroot, local_relpath,
15338 op_depth, scratch_pool));
15339
15340
15341 SVN_ERR(make_copy_txn(wcroot, local_relpath,
15342 INVALID_REPOS_ID, NULL, SVN_INVALID_REVNUM,
15343 op_depth, FALSE, op_depth,
15344 scratch_pool));
15345 }
15346
14760 if (conflicts)
14761 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
15347 if (conflicts)
15348 SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
14762 conflicts, iterpool));
15349 conflicts, scratch_pool));
14763
15350
14764 SVN_ERR(add_work_items(wcroot->sdb, work_items, iterpool));
15351 SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
14765
15352
14766 svn_pool_destroy(iterpool);
14767
14768 return SVN_NO_ERROR;
14769}
14770
14771
14772svn_error_t *
14773svn_wc__db_op_make_copy(svn_wc__db_t *db,
14774 const char *local_abspath,
14775 const svn_skel_t *conflicts,
14776 const svn_skel_t *work_items,
14777 apr_pool_t *scratch_pool)
14778{
14779 svn_wc__db_wcroot_t *wcroot;
14780 const char *local_relpath;
15353 return SVN_NO_ERROR;
15354}
15355
15356
15357svn_error_t *
15358svn_wc__db_op_make_copy(svn_wc__db_t *db,
15359 const char *local_abspath,
15360 const svn_skel_t *conflicts,
15361 const svn_skel_t *work_items,
15362 apr_pool_t *scratch_pool)
15363{
15364 svn_wc__db_wcroot_t *wcroot;
15365 const char *local_relpath;
14781 svn_sqlite__stmt_t *stmt;
14782 svn_boolean_t have_row;
14783
14784 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
14785
14786 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
14787 local_abspath, scratch_pool, scratch_pool));
14788 VERIFY_USABLE_WCROOT(wcroot);
14789
15366
15367 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
15368
15369 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
15370 local_abspath, scratch_pool, scratch_pool));
15371 VERIFY_USABLE_WCROOT(wcroot);
15372
14790 /* The update editor is supposed to call this function when there is
14791 no working node for LOCAL_ABSPATH. */
14792 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
14793 STMT_SELECT_WORKING_NODE));
14794 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
14795 SVN_ERR(svn_sqlite__step(&have_row, stmt));
14796 SVN_ERR(svn_sqlite__reset(stmt));
14797 if (have_row)
14798 return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
14799 _("Modification of '%s' already exists"),
14800 path_for_error_message(wcroot,
14801 local_relpath,
14802 scratch_pool));
14803
14804 /* We don't allow copies to contain server-excluded nodes;
14805 the update editor is going to have to bail out. */
14806 SVN_ERR(catch_copy_of_server_excluded(wcroot, local_relpath, scratch_pool));
14807
14808 SVN_WC__DB_WITH_TXN(
15373 SVN_WC__DB_WITH_TXN(
14809 make_copy_txn(wcroot, local_relpath,
14810 relpath_depth(local_relpath), conflicts, work_items,
14811 scratch_pool),
15374 svn_wc__db_op_make_copy_internal(wcroot, local_relpath, FALSE,
15375 conflicts, work_items,
15376 scratch_pool),
14812 wcroot);
14813
15377 wcroot);
15378
15379 SVN_ERR(flush_entries(wcroot, local_abspath,
15380 svn_depth_infinity, scratch_pool));
15381
14814 return SVN_NO_ERROR;
14815}
14816
14817svn_error_t *
14818svn_wc__db_info_below_working(svn_boolean_t *have_base,
14819 svn_boolean_t *have_work,
14820 svn_wc__db_status_t *status,
14821 svn_wc__db_t *db,

--- 190 unchanged lines hidden (view full) ---

15012 const char *repos_root_url;
15013 const char *url;
15014 apr_size_t len1, len2;
15015
15016 /* If the trailing part of the URL of the working copy directory
15017 does not match the given trailing URL then the whole working
15018 copy is switched. */
15019
15382 return SVN_NO_ERROR;
15383}
15384
15385svn_error_t *
15386svn_wc__db_info_below_working(svn_boolean_t *have_base,
15387 svn_boolean_t *have_work,
15388 svn_wc__db_status_t *status,
15389 svn_wc__db_t *db,

--- 190 unchanged lines hidden (view full) ---

15580 const char *repos_root_url;
15581 const char *url;
15582 apr_size_t len1, len2;
15583
15584 /* If the trailing part of the URL of the working copy directory
15585 does not match the given trailing URL then the whole working
15586 copy is switched. */
15587
15020 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, NULL, wcroot->sdb,
15588 SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, NULL, wcroot,
15021 repos_id, scratch_pool));
15022 url = svn_path_url_add_component2(repos_root_url, repos_relpath,
15023 scratch_pool);
15024
15025 len1 = strlen(trail_url);
15026 len2 = strlen(url);
15027 if ((len1 > len2) || strcmp(url + len2 - len1, trail_url))
15028 {

--- 74 unchanged lines hidden (view full) ---

15103 svn_hash_sets(*excluded_subtrees, abs_path, abs_path);
15104 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15105 }
15106
15107 SVN_ERR(svn_sqlite__reset(stmt));
15108 return SVN_NO_ERROR;
15109}
15110
15589 repos_id, scratch_pool));
15590 url = svn_path_url_add_component2(repos_root_url, repos_relpath,
15591 scratch_pool);
15592
15593 len1 = strlen(trail_url);
15594 len2 = strlen(url);
15595 if ((len1 > len2) || strcmp(url + len2 - len1, trail_url))
15596 {

--- 74 unchanged lines hidden (view full) ---

15671 svn_hash_sets(*excluded_subtrees, abs_path, abs_path);
15672 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15673 }
15674
15675 SVN_ERR(svn_sqlite__reset(stmt));
15676 return SVN_NO_ERROR;
15677}
15678
15111/* Like svn_wc__db_has_local_mods(),
15679/* Like svn_wc__db_has_db_mods(),
15112 * but accepts a WCROOT/LOCAL_RELPATH pair.
15113 * ### This needs a DB as well as a WCROOT/RELPATH pair... */
15114static svn_error_t *
15680 * but accepts a WCROOT/LOCAL_RELPATH pair.
15681 * ### This needs a DB as well as a WCROOT/RELPATH pair... */
15682static svn_error_t *
15115has_local_mods(svn_boolean_t *is_modified,
15116 svn_wc__db_wcroot_t *wcroot,
15117 const char *local_relpath,
15118 svn_wc__db_t *db,
15119 svn_cancel_func_t cancel_func,
15120 void *cancel_baton,
15121 apr_pool_t *scratch_pool)
15683has_db_mods(svn_boolean_t *is_modified,
15684 svn_wc__db_wcroot_t *wcroot,
15685 const char *local_relpath,
15686 apr_pool_t *scratch_pool)
15122{
15123 svn_sqlite__stmt_t *stmt;
15124
15125 /* Check for additions or deletions. */
15126 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15127 STMT_SUBTREE_HAS_TREE_MODIFICATIONS));
15128 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15129 /* If this query returns a row, the working copy is modified. */
15130 SVN_ERR(svn_sqlite__step(is_modified, stmt));
15131 SVN_ERR(svn_sqlite__reset(stmt));
15132
15687{
15688 svn_sqlite__stmt_t *stmt;
15689
15690 /* Check for additions or deletions. */
15691 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15692 STMT_SUBTREE_HAS_TREE_MODIFICATIONS));
15693 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15694 /* If this query returns a row, the working copy is modified. */
15695 SVN_ERR(svn_sqlite__step(is_modified, stmt));
15696 SVN_ERR(svn_sqlite__reset(stmt));
15697
15133 if (cancel_func)
15134 SVN_ERR(cancel_func(cancel_baton));
15135
15136 if (! *is_modified)
15137 {
15138 /* Check for property modifications. */
15139 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15140 STMT_SUBTREE_HAS_PROP_MODIFICATIONS));
15141 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15142 /* If this query returns a row, the working copy is modified. */
15143 SVN_ERR(svn_sqlite__step(is_modified, stmt));
15144 SVN_ERR(svn_sqlite__reset(stmt));
15698 if (! *is_modified)
15699 {
15700 /* Check for property modifications. */
15701 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15702 STMT_SUBTREE_HAS_PROP_MODIFICATIONS));
15703 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15704 /* If this query returns a row, the working copy is modified. */
15705 SVN_ERR(svn_sqlite__step(is_modified, stmt));
15706 SVN_ERR(svn_sqlite__reset(stmt));
15145
15146 if (cancel_func)
15147 SVN_ERR(cancel_func(cancel_baton));
15148 }
15149
15707 }
15708
15150 if (! *is_modified)
15151 {
15152 apr_pool_t *iterpool = NULL;
15153 svn_boolean_t have_row;
15154
15155 /* Check for text modifications. */
15156 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
15157 STMT_SELECT_BASE_FILES_RECURSIVE));
15158 SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
15159 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15160 if (have_row)
15161 iterpool = svn_pool_create(scratch_pool);
15162 while (have_row)
15163 {
15164 const char *node_abspath;
15165 svn_filesize_t recorded_size;
15166 apr_time_t recorded_time;
15167 svn_boolean_t skip_check = FALSE;
15168 svn_error_t *err;
15169
15170 if (cancel_func)
15171 {
15172 err = cancel_func(cancel_baton);
15173 if (err)
15174 return svn_error_trace(svn_error_compose_create(
15175 err,
15176 svn_sqlite__reset(stmt)));
15177 }
15178
15179 svn_pool_clear(iterpool);
15180
15181 node_abspath = svn_dirent_join(wcroot->abspath,
15182 svn_sqlite__column_text(stmt, 0,
15183 iterpool),
15184 iterpool);
15185
15186 recorded_size = get_recorded_size(stmt, 1);
15187 recorded_time = svn_sqlite__column_int64(stmt, 2);
15188
15189 if (recorded_size != SVN_INVALID_FILESIZE
15190 && recorded_time != 0)
15191 {
15192 const svn_io_dirent2_t *dirent;
15193
15194 err = svn_io_stat_dirent2(&dirent, node_abspath, FALSE, TRUE,
15195 iterpool, iterpool);
15196 if (err)
15197 return svn_error_trace(svn_error_compose_create(
15198 err,
15199 svn_sqlite__reset(stmt)));
15200
15201 if (dirent->kind != svn_node_file)
15202 {
15203 *is_modified = TRUE; /* Missing or obstruction */
15204 break;
15205 }
15206 else if (dirent->filesize == recorded_size
15207 && dirent->mtime == recorded_time)
15208 {
15209 /* The file is not modified */
15210 skip_check = TRUE;
15211 }
15212 }
15213
15214 if (! skip_check)
15215 {
15216 err = svn_wc__internal_file_modified_p(is_modified,
15217 db, node_abspath,
15218 FALSE, iterpool);
15219
15220 if (err)
15221 return svn_error_trace(svn_error_compose_create(
15222 err,
15223 svn_sqlite__reset(stmt)));
15224
15225 if (*is_modified)
15226 break;
15227 }
15228
15229 SVN_ERR(svn_sqlite__step(&have_row, stmt));
15230 }
15231 if (iterpool)
15232 svn_pool_destroy(iterpool);
15233
15234 SVN_ERR(svn_sqlite__reset(stmt));
15235 }
15236
15237 return SVN_NO_ERROR;
15238}
15239
15240
15241svn_error_t *
15709 return SVN_NO_ERROR;
15710}
15711
15712
15713svn_error_t *
15242svn_wc__db_has_local_mods(svn_boolean_t *is_modified,
15243 svn_wc__db_t *db,
15244 const char *local_abspath,
15245 svn_cancel_func_t cancel_func,
15246 void *cancel_baton,
15247 apr_pool_t *scratch_pool)
15714svn_wc__db_has_db_mods(svn_boolean_t *is_modified,
15715 svn_wc__db_t *db,
15716 const char *local_abspath,
15717 apr_pool_t *scratch_pool)
15248{
15249 svn_wc__db_wcroot_t *wcroot;
15250 const char *local_relpath;
15251
15252 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
15253
15254 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
15255 db, local_abspath,
15256 scratch_pool, scratch_pool));
15257 VERIFY_USABLE_WCROOT(wcroot);
15258
15718{
15719 svn_wc__db_wcroot_t *wcroot;
15720 const char *local_relpath;
15721
15722 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
15723
15724 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
15725 db, local_abspath,
15726 scratch_pool, scratch_pool));
15727 VERIFY_USABLE_WCROOT(wcroot);
15728
15259 return svn_error_trace(has_local_mods(is_modified, wcroot, local_relpath,
15260 db, cancel_func, cancel_baton,
15261 scratch_pool));
15729 return svn_error_trace(has_db_mods(is_modified, wcroot, local_relpath,
15730 scratch_pool));
15262}
15263
15264
15265/* The body of svn_wc__db_revision_status().
15266 */
15267static svn_error_t *
15268revision_status_txn(svn_revnum_t *min_revision,
15269 svn_revnum_t *max_revision,
15270 svn_boolean_t *is_sparse_checkout,
15271 svn_boolean_t *is_modified,
15272 svn_boolean_t *is_switched,
15273 svn_wc__db_wcroot_t *wcroot,
15274 const char *local_relpath,
15275 svn_wc__db_t *db,
15276 const char *trail_url,
15277 svn_boolean_t committed,
15731}
15732
15733
15734/* The body of svn_wc__db_revision_status().
15735 */
15736static svn_error_t *
15737revision_status_txn(svn_revnum_t *min_revision,
15738 svn_revnum_t *max_revision,
15739 svn_boolean_t *is_sparse_checkout,
15740 svn_boolean_t *is_modified,
15741 svn_boolean_t *is_switched,
15742 svn_wc__db_wcroot_t *wcroot,
15743 const char *local_relpath,
15744 svn_wc__db_t *db,
15745 const char *trail_url,
15746 svn_boolean_t committed,
15278 svn_cancel_func_t cancel_func,
15279 void *cancel_baton,
15280 apr_pool_t *scratch_pool)
15281{
15282 svn_error_t *err;
15283 svn_boolean_t exists;
15284
15285 SVN_ERR(does_node_exist(&exists, wcroot, local_relpath));
15286
15287 if (!exists)
15288 {
15289 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
15290 _("The node '%s' was not found."),
15291 path_for_error_message(wcroot, local_relpath,
15292 scratch_pool));
15293 }
15294
15295 /* Determine mixed-revisionness. */
15296 SVN_ERR(get_min_max_revisions(min_revision, max_revision, wcroot,
15297 local_relpath, committed, scratch_pool));
15298
15747 apr_pool_t *scratch_pool)
15748{
15749 svn_error_t *err;
15750 svn_boolean_t exists;
15751
15752 SVN_ERR(does_node_exist(&exists, wcroot, local_relpath));
15753
15754 if (!exists)
15755 {
15756 return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
15757 _("The node '%s' was not found."),
15758 path_for_error_message(wcroot, local_relpath,
15759 scratch_pool));
15760 }
15761
15762 /* Determine mixed-revisionness. */
15763 SVN_ERR(get_min_max_revisions(min_revision, max_revision, wcroot,
15764 local_relpath, committed, scratch_pool));
15765
15299 if (cancel_func)
15300 SVN_ERR(cancel_func(cancel_baton));
15301
15302 /* Determine sparseness. */
15303 SVN_ERR(is_sparse_checkout_internal(is_sparse_checkout, wcroot,
15304 local_relpath, scratch_pool));
15305
15766 /* Determine sparseness. */
15767 SVN_ERR(is_sparse_checkout_internal(is_sparse_checkout, wcroot,
15768 local_relpath, scratch_pool));
15769
15306 if (cancel_func)
15307 SVN_ERR(cancel_func(cancel_baton));
15308
15309 /* Check for switched nodes. */
15310 {
15311 err = has_switched_subtrees(is_switched, wcroot, local_relpath,
15312 trail_url, scratch_pool);
15313
15314 if (err)
15315 {
15316 if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
15317 return svn_error_trace(err);
15318
15319 svn_error_clear(err); /* No Base node, but no fatal error */
15320 *is_switched = FALSE;
15321 }
15322 }
15323
15770 /* Check for switched nodes. */
15771 {
15772 err = has_switched_subtrees(is_switched, wcroot, local_relpath,
15773 trail_url, scratch_pool);
15774
15775 if (err)
15776 {
15777 if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
15778 return svn_error_trace(err);
15779
15780 svn_error_clear(err); /* No Base node, but no fatal error */
15781 *is_switched = FALSE;
15782 }
15783 }
15784
15324 if (cancel_func)
15325 SVN_ERR(cancel_func(cancel_baton));
15785 /* Check for db mods. */
15786 SVN_ERR(has_db_mods(is_modified, wcroot, local_relpath, scratch_pool));
15326
15787
15327 /* Check for local mods. */
15328 SVN_ERR(has_local_mods(is_modified, wcroot, local_relpath, db,
15329 cancel_func, cancel_baton, scratch_pool));
15330
15331 return SVN_NO_ERROR;
15332}
15333
15334
15335svn_error_t *
15336svn_wc__db_revision_status(svn_revnum_t *min_revision,
15337 svn_revnum_t *max_revision,
15338 svn_boolean_t *is_sparse_checkout,
15339 svn_boolean_t *is_modified,
15340 svn_boolean_t *is_switched,
15341 svn_wc__db_t *db,
15342 const char *local_abspath,
15343 const char *trail_url,
15344 svn_boolean_t committed,
15788 return SVN_NO_ERROR;
15789}
15790
15791
15792svn_error_t *
15793svn_wc__db_revision_status(svn_revnum_t *min_revision,
15794 svn_revnum_t *max_revision,
15795 svn_boolean_t *is_sparse_checkout,
15796 svn_boolean_t *is_modified,
15797 svn_boolean_t *is_switched,
15798 svn_wc__db_t *db,
15799 const char *local_abspath,
15800 const char *trail_url,
15801 svn_boolean_t committed,
15345 svn_cancel_func_t cancel_func,
15346 void *cancel_baton,
15347 apr_pool_t *scratch_pool)
15348{
15349 svn_wc__db_wcroot_t *wcroot;
15350 const char *local_relpath;
15351
15352 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
15353
15354 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
15355 db, local_abspath,
15356 scratch_pool, scratch_pool));
15357 VERIFY_USABLE_WCROOT(wcroot);
15358
15359 SVN_WC__DB_WITH_TXN(
15360 revision_status_txn(min_revision, max_revision,
15361 is_sparse_checkout, is_modified, is_switched,
15362 wcroot, local_relpath, db,
15802 apr_pool_t *scratch_pool)
15803{
15804 svn_wc__db_wcroot_t *wcroot;
15805 const char *local_relpath;
15806
15807 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
15808
15809 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
15810 db, local_abspath,
15811 scratch_pool, scratch_pool));
15812 VERIFY_USABLE_WCROOT(wcroot);
15813
15814 SVN_WC__DB_WITH_TXN(
15815 revision_status_txn(min_revision, max_revision,
15816 is_sparse_checkout, is_modified, is_switched,
15817 wcroot, local_relpath, db,
15363 trail_url, committed, cancel_func, cancel_baton,
15818 trail_url, committed,
15364 scratch_pool),
15365 wcroot);
15366 return SVN_NO_ERROR;
15367}
15368
15369
15370svn_error_t *
15371svn_wc__db_base_get_lock_tokens_recursive(apr_hash_t **lock_tokens,

--- 29 unchanged lines hidden (view full) ---

15401 {
15402 apr_int64_t child_repos_id = svn_sqlite__column_int64(stmt, 0);
15403 const char *child_relpath = svn_sqlite__column_text(stmt, 1, NULL);
15404 const char *lock_token = svn_sqlite__column_text(stmt, 2, result_pool);
15405
15406 if (child_repos_id != last_repos_id)
15407 {
15408 svn_error_t *err = svn_wc__db_fetch_repos_info(&last_repos_root_url,
15819 scratch_pool),
15820 wcroot);
15821 return SVN_NO_ERROR;
15822}
15823
15824
15825svn_error_t *
15826svn_wc__db_base_get_lock_tokens_recursive(apr_hash_t **lock_tokens,

--- 29 unchanged lines hidden (view full) ---

15856 {
15857 apr_int64_t child_repos_id = svn_sqlite__column_int64(stmt, 0);
15858 const char *child_relpath = svn_sqlite__column_text(stmt, 1, NULL);
15859 const char *lock_token = svn_sqlite__column_text(stmt, 2, result_pool);
15860
15861 if (child_repos_id != last_repos_id)
15862 {
15863 svn_error_t *err = svn_wc__db_fetch_repos_info(&last_repos_root_url,
15409 NULL, wcroot->sdb,
15864 NULL, wcroot,
15410 child_repos_id,
15411 scratch_pool);
15412
15413 if (err)
15414 {
15415 return svn_error_trace(
15416 svn_error_compose_create(err,
15417 svn_sqlite__reset(stmt)));

--- 106 unchanged lines hidden (view full) ---

15524 db, wri_abspath,
15525 scratch_pool, scratch_pool));
15526 VERIFY_USABLE_WCROOT(wcroot);
15527
15528 SVN_ERR(verify_wcroot(wcroot, scratch_pool));
15529 return SVN_NO_ERROR;
15530}
15531
15865 child_repos_id,
15866 scratch_pool);
15867
15868 if (err)
15869 {
15870 return svn_error_trace(
15871 svn_error_compose_create(err,
15872 svn_sqlite__reset(stmt)));

--- 106 unchanged lines hidden (view full) ---

15979 db, wri_abspath,
15980 scratch_pool, scratch_pool));
15981 VERIFY_USABLE_WCROOT(wcroot);
15982
15983 SVN_ERR(verify_wcroot(wcroot, scratch_pool));
15984 return SVN_NO_ERROR;
15985}
15986
15987
15532svn_error_t *
15988svn_error_t *
15989svn_wc__db_verify_db_full_internal(svn_wc__db_wcroot_t *wcroot,
15990 svn_wc__db_verify_cb_t callback,
15991 void *baton,
15992 apr_pool_t *scratch_pool)
15993{
15994 svn_sqlite__stmt_t *stmt;
15995 svn_boolean_t have_row;
15996 svn_error_t *err = NULL;
15997 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
15998
15999 SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_STATIC_VERIFY));
16000 SVN_ERR(svn_sqlite__step(&have_row, stmt));
16001
16002 while (have_row)
16003 {
16004 const char *local_relpath;
16005 int op_depth = svn_sqlite__column_int(stmt, 1);
16006 int id = svn_sqlite__column_int(stmt, 2);
16007 const char *msg;
16008
16009 svn_pool_clear(iterpool);
16010
16011 local_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
16012 msg = svn_sqlite__column_text(stmt, 3, scratch_pool);
16013
16014 err = callback(baton, wcroot->abspath, local_relpath, op_depth,
16015 id, msg, iterpool);
16016
16017 if (err)
16018 break;
16019
16020 SVN_ERR(svn_sqlite__step(&have_row, stmt));
16021 }
16022
16023 svn_pool_destroy(iterpool);
16024
16025 return svn_error_trace(
16026 svn_error_compose_create(err, svn_sqlite__reset(stmt)));
16027}
16028
16029svn_error_t *
16030svn_wc__db_verify_db_full(svn_wc__db_t *db,
16031 const char *wri_abspath,
16032 svn_wc__db_verify_cb_t callback,
16033 void *baton,
16034 apr_pool_t *scratch_pool)
16035{
16036 svn_wc__db_wcroot_t *wcroot;
16037 const char *local_relpath;
16038
16039 SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
16040
16041 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
16042 wri_abspath, scratch_pool, scratch_pool));
16043 VERIFY_USABLE_WCROOT(wcroot);
16044
16045 return svn_error_trace(
16046 svn_wc__db_verify_db_full_internal(wcroot, callback, baton,
16047 scratch_pool));
16048}
16049
16050svn_error_t *
15533svn_wc__db_bump_format(int *result_format,
15534 svn_boolean_t *bumped_format,
15535 svn_wc__db_t *db,
15536 const char *wcroot_abspath,
15537 apr_pool_t *scratch_pool)
15538{
15539 svn_sqlite__db_t *sdb;
15540 svn_error_t *err;
15541 int format;
15542
15543 if (bumped_format)
15544 *bumped_format = FALSE;
15545
15546 /* Do not scan upwards for a working copy root here to prevent accidental
15547 * upgrades of any working copies the WCROOT might be nested in.
15548 * Just try to open a DB at the specified path instead. */
15549 err = svn_wc__db_util_open_db(&sdb, wcroot_abspath, SDB_FILE,
15550 svn_sqlite__mode_readwrite,
15551 TRUE, /* exclusive */
16051svn_wc__db_bump_format(int *result_format,
16052 svn_boolean_t *bumped_format,
16053 svn_wc__db_t *db,
16054 const char *wcroot_abspath,
16055 apr_pool_t *scratch_pool)
16056{
16057 svn_sqlite__db_t *sdb;
16058 svn_error_t *err;
16059 int format;
16060
16061 if (bumped_format)
16062 *bumped_format = FALSE;
16063
16064 /* Do not scan upwards for a working copy root here to prevent accidental
16065 * upgrades of any working copies the WCROOT might be nested in.
16066 * Just try to open a DB at the specified path instead. */
16067 err = svn_wc__db_util_open_db(&sdb, wcroot_abspath, SDB_FILE,
16068 svn_sqlite__mode_readwrite,
16069 TRUE, /* exclusive */
16070 0, /* default timeout */
15552 NULL, /* my statements */
15553 scratch_pool, scratch_pool);
15554 if (err)
15555 {
15556 svn_error_t *err2;
15557 apr_hash_t *entries;
15558
15559 /* Could not open an sdb. Check for an entries file instead. */

--- 43 unchanged lines hidden (view full) ---

15603
15604 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
15605 db, local_abspath,
15606 scratch_pool, scratch_pool));
15607 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb, STMT_VACUUM));
15608
15609 return SVN_NO_ERROR;
15610}
16071 NULL, /* my statements */
16072 scratch_pool, scratch_pool);
16073 if (err)
16074 {
16075 svn_error_t *err2;
16076 apr_hash_t *entries;
16077
16078 /* Could not open an sdb. Check for an entries file instead. */

--- 43 unchanged lines hidden (view full) ---

16122
16123 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
16124 db, local_abspath,
16125 scratch_pool, scratch_pool));
16126 SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb, STMT_VACUUM));
16127
16128 return SVN_NO_ERROR;
16129}
16130
16131/* Item queued with svn_wc__db_commit_queue_add */
16132typedef struct commit_queue_item_t
16133{
16134 const char *local_relpath;
16135 svn_boolean_t recurse; /* Use legacy recursion */
16136 svn_boolean_t committed; /* Process the node as committed */
16137 svn_boolean_t remove_lock; /* Remove existing lock on node */
16138 svn_boolean_t remove_changelist; /* Remove changelist on node */
16139
16140 /* The pristine text checksum. NULL if the old value should be kept
16141 and for directories */
16142 const svn_checksum_t *new_sha1_checksum;
16143
16144 apr_hash_t *new_dav_cache; /* New DAV cache for the node */
16145} commit_queue_item_t;
16146
16147/* The queue definition for vn_wc__db_create_commit_queue,
16148 svn_wc__db_commit_queue_add and finally svn_wc__db_process_commit_queue */
16149struct svn_wc__db_commit_queue_t
16150{
16151 svn_wc__db_wcroot_t *wcroot; /* Wcroot for ITEMS */
16152 apr_array_header_t *items; /* List of commit_queue_item_t* */
16153 svn_boolean_t have_recurse; /* Is one or more item[x]->recurse TRUE? */
16154};
16155
16156/* Create a new svn_wc__db_commit_queue_t instance in RESULT_POOL for the
16157 working copy specified with WRI_ABSPATH */
16158svn_error_t *
16159svn_wc__db_create_commit_queue(svn_wc__db_commit_queue_t **queue,
16160 svn_wc__db_t *db,
16161 const char *wri_abspath,
16162 apr_pool_t *result_pool,
16163 apr_pool_t *scratch_pool)
16164{
16165 svn_wc__db_wcroot_t *wcroot;
16166 const char *local_relpath;
16167 svn_wc__db_commit_queue_t *q;
16168
16169 SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
16170
16171 SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
16172 wri_abspath, result_pool, scratch_pool));
16173 VERIFY_USABLE_WCROOT(wcroot);
16174
16175 q = apr_pcalloc(result_pool, sizeof(*q));
16176
16177 SVN_ERR_ASSERT(wcroot->sdb);
16178
16179 q->wcroot = wcroot;
16180 q->items = apr_array_make(result_pool, 64,
16181 sizeof(commit_queue_item_t*));
16182 q->have_recurse = FALSE;
16183
16184 *queue = q;
16185 return SVN_NO_ERROR;
16186}
16187
16188svn_error_t *
16189svn_wc__db_commit_queue_add(svn_wc__db_commit_queue_t *queue,
16190 const char *local_abspath,
16191 svn_boolean_t recurse,
16192 svn_boolean_t is_commited,
16193 svn_boolean_t remove_lock,
16194 svn_boolean_t remove_changelist,
16195 const svn_checksum_t *new_sha1_checksum,
16196 apr_hash_t *new_dav_cache,
16197 apr_pool_t *result_pool,
16198 apr_pool_t *scratch_pool)
16199{
16200 commit_queue_item_t *cqi;
16201 const char *local_relpath;
16202
16203 local_relpath = svn_dirent_skip_ancestor(queue->wcroot->abspath,
16204 local_abspath);
16205
16206 if (! local_relpath)
16207 return svn_error_createf(
16208 SVN_ERR_WC_PATH_NOT_FOUND, NULL,
16209 _("The path '%s' is not in the working copy '%s'"),
16210 svn_dirent_local_style(local_abspath, scratch_pool),
16211 svn_dirent_local_style(queue->wcroot->abspath, scratch_pool));
16212
16213 cqi = apr_pcalloc(result_pool, sizeof(*cqi));
16214 cqi->local_relpath = local_relpath;
16215 cqi->recurse = recurse;
16216 cqi->committed = is_commited;
16217 cqi->remove_lock = remove_lock;
16218 cqi->remove_changelist = remove_changelist;
16219 cqi->new_sha1_checksum = new_sha1_checksum;
16220 cqi->new_dav_cache = new_dav_cache;
16221
16222 queue->have_recurse |= recurse;
16223
16224 APR_ARRAY_PUSH(queue->items, commit_queue_item_t *) = cqi;
16225 return SVN_NO_ERROR;
16226}
16227
16228/*** Finishing updates and commits. ***/
16229
16230/* Post process an item that is committed in the repository. Collapse layers into
16231 * BASE. Queue work items that will finish a commit of the file or directory
16232 * LOCAL_ABSPATH in DB:
16233 */
16234static svn_error_t *
16235process_committed_leaf(svn_wc__db_t *db,
16236 svn_wc__db_wcroot_t *wcroot,
16237 const char *local_relpath,
16238 svn_boolean_t via_recurse,
16239 svn_wc__db_status_t status,
16240 svn_node_kind_t kind,
16241 svn_boolean_t prop_mods,
16242 const svn_checksum_t *old_checksum,
16243 svn_revnum_t new_revnum,
16244 apr_time_t new_changed_date,
16245 const char *new_changed_author,
16246 apr_hash_t *new_dav_cache,
16247 svn_boolean_t remove_lock,
16248 svn_boolean_t remove_changelist,
16249 const svn_checksum_t *checksum,
16250 apr_pool_t *scratch_pool)
16251{
16252 svn_revnum_t new_changed_rev = new_revnum;
16253 svn_skel_t *work_item = NULL;
16254
16255 {
16256 const char *lock_relpath;
16257 svn_boolean_t locked;
16258
16259 if (kind == svn_node_dir)
16260 lock_relpath = local_relpath;
16261 else
16262 lock_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
16263
16264 SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot,
16265 lock_relpath, FALSE,
16266 scratch_pool));
16267
16268 if (!locked)
16269 return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
16270 _("No write-lock in '%s'"),
16271 path_for_error_message(wcroot, local_relpath,
16272 scratch_pool));
16273
16274 SVN_ERR(flush_entries(wcroot, lock_relpath, svn_depth_empty,
16275 scratch_pool));
16276 }
16277
16278 if (status == svn_wc__db_status_not_present)
16279 {
16280 /* We are committing the leaf of a copy operation.
16281 We leave the not-present marker to allow pulling in excluded
16282 children of a copy.
16283
16284 The next update will remove the not-present marker. */
16285
16286 return SVN_NO_ERROR;
16287 }
16288
16289 SVN_ERR_ASSERT(status == svn_wc__db_status_normal
16290 || status == svn_wc__db_status_incomplete
16291 || status == svn_wc__db_status_added
16292 || status == svn_wc__db_status_deleted);
16293
16294 if (kind != svn_node_dir
16295 && status != svn_wc__db_status_deleted)
16296 {
16297 /* If we sent a delta (meaning: post-copy modification),
16298 then this file will appear in the queue and so we should have
16299 its checksum already. */
16300 if (checksum == NULL)
16301 {
16302 /* It was copied and not modified. We must have a text
16303 base for it. And the node should have a checksum. */
16304 SVN_ERR_ASSERT(old_checksum != NULL);
16305
16306 checksum = old_checksum;
16307
16308 /* Is the node completely unmodified and are we recursing? */
16309 if (via_recurse && !prop_mods)
16310 {
16311 /* If a copied node itself is not modified, but the op_root of
16312 the copy is committed we have to make sure that changed_rev,
16313 changed_date and changed_author don't change or the working
16314 copy used for committing will show different last modified
16315 information then a clean checkout of exactly the same
16316 revisions. (Issue #3676) */
16317
16318 SVN_ERR(svn_wc__db_read_info_internal(
16319 NULL, NULL, NULL, NULL, NULL,
16320 &new_changed_rev,
16321 &new_changed_date,
16322 &new_changed_author, NULL, NULL,
16323 NULL, NULL, NULL, NULL, NULL,
16324 NULL, NULL, NULL, NULL,
16325 NULL, NULL, NULL, NULL,
16326 NULL, NULL,
16327 wcroot, local_relpath,
16328 scratch_pool, scratch_pool));
16329 }
16330 }
16331
16332 SVN_ERR(svn_wc__wq_build_file_commit(&work_item,
16333 db, svn_dirent_join(wcroot->abspath,
16334 local_relpath,
16335 scratch_pool),
16336 prop_mods,
16337 scratch_pool, scratch_pool));
16338 }
16339
16340 /* The new text base will be found in the pristine store by its checksum. */
16341 SVN_ERR(commit_node(wcroot, local_relpath,
16342 new_revnum, new_changed_rev,
16343 new_changed_date, new_changed_author,
16344 checksum,
16345 new_dav_cache,
16346 !remove_changelist,
16347 !remove_lock,
16348 work_item,
16349 scratch_pool));
16350
16351 return SVN_NO_ERROR;
16352}
16353
16354/** Internal helper for svn_wc_process_committed_queue2().
16355 * Bump a commit item, collapsing local changes with the new repository
16356 * information to a new BASE node.
16357 *
16358 * @a new_date is the (server-side) date of the new revision, or 0.
16359 *
16360 * @a rev_author is the (server-side) author of the new
16361 * revision; it may be @c NULL.
16362 *
16363 * @a new_dav_cache is a hash of all the new dav properties for LOCAL_RELPATH.
16364 *
16365 * If @a remove_lock is set, release any user locks on @a
16366 * local_abspath; otherwise keep them during processing.
16367 *
16368 * If @a remove_changelist is set, clear any changeset assignments
16369 * from @a local_abspath; otherwise, keep such assignments.
16370 *
16371 * If @a new_sha1_checksum is non-NULL, use it to identify the node's pristine
16372 * text.
16373 *
16374 * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly
16375 * recursive commit operation. (Part of the legacy recurse handling)
16376 */
16377static svn_error_t *
16378process_committed_internal(svn_wc__db_t *db,
16379 svn_wc__db_wcroot_t *wcroot,
16380 const char *local_relpath,
16381 svn_boolean_t recurse,
16382 svn_boolean_t top_of_recurse,
16383 svn_revnum_t new_revnum,
16384 apr_time_t new_date,
16385 const char *rev_author,
16386 apr_hash_t *new_dav_cache,
16387 svn_boolean_t remove_lock,
16388 svn_boolean_t remove_changelist,
16389 const svn_checksum_t *new_sha1_checksum,
16390 apr_hash_t *items_by_relpath,
16391 apr_pool_t *scratch_pool)
16392{
16393 svn_wc__db_status_t status;
16394 svn_node_kind_t kind;
16395 const svn_checksum_t *old_checksum;
16396 svn_boolean_t prop_mods;
16397
16398 SVN_ERR(svn_wc__db_read_info_internal(&status, &kind, NULL, NULL, NULL, NULL, NULL,
16399 NULL, NULL, &old_checksum, NULL, NULL,
16400 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
16401 NULL, &prop_mods, NULL, NULL, NULL,
16402 wcroot, local_relpath,
16403 scratch_pool, scratch_pool));
16404
16405 /* NOTE: be wary of making crazy semantic changes in this function, since
16406 svn_wc_process_committed4() calls this. */
16407
16408 SVN_ERR(process_committed_leaf(db, wcroot, local_relpath, !top_of_recurse,
16409 status, kind, prop_mods, old_checksum,
16410 new_revnum, new_date, rev_author,
16411 new_dav_cache,
16412 remove_lock, remove_changelist,
16413 new_sha1_checksum,
16414 scratch_pool));
16415
16416 /* Only check for recursion on nodes that have children */
16417 if (kind != svn_node_dir
16418 || status == svn_wc__db_status_not_present
16419 || status == svn_wc__db_status_excluded
16420 || status == svn_wc__db_status_server_excluded
16421 /* Node deleted -> then no longer a directory */
16422 || status == svn_wc__db_status_deleted)
16423 {
16424 return SVN_NO_ERROR;
16425 }
16426
16427 if (recurse)
16428 {
16429 const apr_array_header_t *children;
16430 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
16431 int i;
16432
16433 /* Read PATH's entries; this is the absolute path. */
16434 SVN_ERR(gather_children(&children, wcroot, local_relpath,
16435 STMT_SELECT_NODE_CHILDREN, -1,
16436 scratch_pool, iterpool));
16437
16438 /* Recursively loop over all children. */
16439 for (i = 0; i < children->nelts; i++)
16440 {
16441 const char *name = APR_ARRAY_IDX(children, i, const char *);
16442 const char *this_relpath;
16443 const commit_queue_item_t *cqi;
16444
16445 svn_pool_clear(iterpool);
16446
16447 this_relpath = svn_dirent_join(local_relpath, name, iterpool);
16448
16449 new_sha1_checksum = NULL;
16450 cqi = svn_hash_gets(items_by_relpath, this_relpath);
16451
16452 if (cqi != NULL)
16453 new_sha1_checksum = cqi->new_sha1_checksum;
16454
16455 /* Recurse. Pass NULL for NEW_DAV_CACHE, because the
16456 ones present in the current call are only applicable to
16457 this one committed item. */
16458 SVN_ERR(process_committed_internal(
16459 db, wcroot, this_relpath,
16460 TRUE /* recurse */,
16461 FALSE /* top_of_recurse */,
16462 new_revnum, new_date,
16463 rev_author,
16464 NULL /* new_dav_cache */,
16465 FALSE /* remove_lock */,
16466 remove_changelist,
16467 new_sha1_checksum,
16468 items_by_relpath,
16469 iterpool));
16470 }
16471
16472 svn_pool_destroy(iterpool);
16473 }
16474
16475 return SVN_NO_ERROR;
16476}
16477
16478/* Return TRUE if any item of QUEUE is a parent of ITEM and will be
16479 processed recursively, return FALSE otherwise.
16480
16481 The algorithmic complexity of this search implementation is O(queue
16482 length), but it's quite quick.
16483*/
16484static svn_boolean_t
16485have_recursive_parent(const apr_array_header_t *all_items,
16486 const commit_queue_item_t *item,
16487 apr_pool_t *scratch_pool)
16488{
16489 const char *local_relpath = item->local_relpath;
16490 int i;
16491
16492 for (i = 0; i < all_items->nelts; i++)
16493 {
16494 const commit_queue_item_t *qi
16495 = APR_ARRAY_IDX(all_items, i, const commit_queue_item_t *);
16496
16497 if (qi == item)
16498 continue;
16499
16500 if (qi->recurse && svn_relpath_skip_ancestor(qi->local_relpath,
16501 local_relpath))
16502 {
16503 return TRUE;
16504 }
16505 }
16506
16507 return FALSE;
16508}
16509
16510/* Compare function for svn_sort__array */
16511static int
16512compare_queue_items(const void *v1,
16513 const void *v2)
16514{
16515 const commit_queue_item_t *cqi1
16516 = *(const commit_queue_item_t **)v1;
16517 const commit_queue_item_t *cqi2
16518 = *(const commit_queue_item_t **)v2;
16519
16520 return svn_path_compare_paths(cqi1->local_relpath, cqi2->local_relpath);
16521}
16522
16523/* Internal, locked version of svn_wc__db_process_commit_queue */
16524static svn_error_t *
16525db_process_commit_queue(svn_wc__db_t *db,
16526 svn_wc__db_commit_queue_t *queue,
16527 svn_revnum_t new_revnum,
16528 apr_time_t new_date,
16529 const char *new_author,
16530 apr_pool_t *scratch_pool)
16531{
16532 apr_hash_t *items_by_relpath = NULL;
16533 int j;
16534 apr_pool_t *iterpool = svn_pool_create(scratch_pool);
16535
16536 svn_sort__array(queue->items, compare_queue_items);
16537
16538 if (queue->have_recurse)
16539 {
16540 items_by_relpath = apr_hash_make(scratch_pool);
16541
16542 for (j = 0; j < queue->items->nelts; j++)
16543 {
16544 commit_queue_item_t *cqi
16545 = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *);
16546
16547 svn_hash_sets(items_by_relpath, cqi->local_relpath, cqi);
16548 }
16549 }
16550
16551 for (j = 0; j < queue->items->nelts; j++)
16552 {
16553 commit_queue_item_t *cqi
16554 = APR_ARRAY_IDX(queue->items, j, commit_queue_item_t *);
16555
16556 svn_pool_clear(iterpool);
16557
16558 /* Skip this item if it is a child of a recursive item, because it has
16559 been (or will be) accounted for when that recursive item was (or
16560 will be) processed. */
16561 if (queue->have_recurse && have_recursive_parent(queue->items, cqi,
16562 iterpool))
16563 continue;
16564
16565 if (!cqi->committed)
16566 {
16567 if (cqi->remove_lock)
16568 {
16569 svn_skel_t *work_item;
16570
16571 SVN_ERR(svn_wc__wq_build_sync_file_flags(
16572 &work_item,
16573 db,
16574 svn_dirent_join(
16575 queue->wcroot->abspath,
16576 cqi->local_relpath,
16577 iterpool),
16578 iterpool, iterpool));
16579
16580 lock_remove_txn(queue->wcroot, cqi->local_relpath, work_item,
16581 iterpool);
16582 }
16583 if (cqi->remove_changelist)
16584 SVN_ERR(svn_wc__db_op_set_changelist(db,
16585 svn_dirent_join(
16586 queue->wcroot->abspath,
16587 cqi->local_relpath,
16588 iterpool),
16589 NULL, NULL,
16590 svn_depth_empty,
16591 NULL, NULL, /* notify */
16592 NULL, NULL, /* cancel */
16593 iterpool));
16594 }
16595 else
16596 {
16597 SVN_ERR(process_committed_internal(
16598 db, queue->wcroot, cqi->local_relpath,
16599 cqi->recurse,
16600 TRUE /* top_of_recurse */,
16601 new_revnum, new_date, new_author,
16602 cqi->new_dav_cache,
16603 cqi->remove_lock,
16604 cqi->remove_changelist,
16605 cqi->new_sha1_checksum,
16606 items_by_relpath,
16607 iterpool));
16608 }
16609 }
16610
16611 svn_pool_destroy(iterpool);
16612
16613 return SVN_NO_ERROR;
16614}
16615
16616svn_error_t *
16617svn_wc__db_process_commit_queue(svn_wc__db_t *db,
16618 svn_wc__db_commit_queue_t *queue,
16619 svn_revnum_t new_revnum,
16620 apr_time_t new_date,
16621 const char *new_author,
16622 apr_pool_t *scratch_pool)
16623{
16624 SVN_WC__DB_WITH_TXN(db_process_commit_queue(db, queue,
16625 new_revnum, new_date,
16626 new_author, scratch_pool),
16627 queue->wcroot);
16628
16629 return SVN_NO_ERROR;
16630}