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} |
|