wc_db_private.h revision 262253
1/** 2 * @copyright 3 * ==================================================================== 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 * ==================================================================== 21 * @endcopyright 22 */ 23 24/* This file is not for general consumption; it should only be used by 25 wc_db.c. */ 26#ifndef SVN_WC__I_AM_WC_DB 27#error "You should not be using these data structures directly" 28#endif /* SVN_WC__I_AM_WC_DB */ 29 30#ifndef WC_DB_PRIVATE_H 31#define WC_DB_PRIVATE_H 32 33#include "wc_db.h" 34 35 36struct svn_wc__db_t { 37 /* We need the config whenever we run into a new WC directory, in order 38 to figure out where we should look for the corresponding datastore. */ 39 svn_config_t *config; 40 41 /* Should we fail with SVN_ERR_WC_UPGRADE_REQUIRED when it is 42 opened, and found to be not-current? */ 43 svn_boolean_t verify_format; 44 45 /* Should we ensure the WORK_QUEUE is empty when a WCROOT is opened? */ 46 svn_boolean_t enforce_empty_wq; 47 48 /* Should we open Sqlite databases EXCLUSIVE */ 49 svn_boolean_t exclusive; 50 51 /* Map a given working copy directory to its relevant data. 52 const char *local_abspath -> svn_wc__db_wcroot_t *wcroot */ 53 apr_hash_t *dir_data; 54 55 /* A few members to assist with caching of kind values for paths. See 56 get_path_kind() for use. */ 57 struct 58 { 59 svn_stringbuf_t *abspath; 60 svn_node_kind_t kind; 61 } parse_cache; 62 63 /* As we grow the state of this DB, allocate that state here. */ 64 apr_pool_t *state_pool; 65}; 66 67 68/* Hold information about an owned lock */ 69typedef struct svn_wc__db_wclock_t 70{ 71 /* Relative path of the lock root */ 72 const char *local_relpath; 73 74 /* Number of levels locked (0 for infinity) */ 75 int levels; 76} svn_wc__db_wclock_t; 77 78 79/** Hold information about a WCROOT. 80 * 81 * This structure is referenced by all per-directory handles underneath it. 82 */ 83typedef struct svn_wc__db_wcroot_t { 84 /* Location of this wcroot in the filesystem. */ 85 const char *abspath; 86 87 /* The SQLite database containing the metadata for everything in 88 this wcroot. */ 89 svn_sqlite__db_t *sdb; 90 91 /* The WCROOT.id for this directory (and all its children). */ 92 apr_int64_t wc_id; 93 94 /* The format of this wcroot's metadata storage (see wc.h). If the 95 format has not (yet) been determined, this will be UNKNOWN_FORMAT. */ 96 int format; 97 98 /* Array of svn_wc__db_wclock_t structures (not pointers!). 99 Typically just one or two locks maximum. */ 100 apr_array_header_t *owned_locks; 101 102 /* Map a working copy directory to a cached adm_access baton. 103 const char *local_abspath -> svn_wc_adm_access_t *adm_access */ 104 apr_hash_t *access_cache; 105 106} svn_wc__db_wcroot_t; 107 108 109/* */ 110svn_error_t * 111svn_wc__db_close_many_wcroots(apr_hash_t *roots, 112 apr_pool_t *state_pool, 113 apr_pool_t *scratch_pool); 114 115 116/* Construct a new svn_wc__db_wcroot_t. The WCROOT_ABSPATH and SDB parameters 117 must have lifetime of at least RESULT_POOL. */ 118svn_error_t * 119svn_wc__db_pdh_create_wcroot(svn_wc__db_wcroot_t **wcroot, 120 const char *wcroot_abspath, 121 svn_sqlite__db_t *sdb, 122 apr_int64_t wc_id, 123 int format, 124 svn_boolean_t verify_format, 125 svn_boolean_t enforce_empty_wq, 126 apr_pool_t *result_pool, 127 apr_pool_t *scratch_pool); 128 129 130/* For a given LOCAL_ABSPATH, figure out what sqlite database (WCROOT) to 131 use and the RELPATH within that wcroot. 132 133 *LOCAL_RELPATH will be allocated within RESULT_POOL. Temporary allocations 134 will be made in SCRATCH_POOL. 135 136 *WCROOT will be allocated within DB->STATE_POOL. 137 138 Certain internal structures will be allocated in DB->STATE_POOL. 139*/ 140svn_error_t * 141svn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot, 142 const char **local_relpath, 143 svn_wc__db_t *db, 144 const char *local_abspath, 145 apr_pool_t *result_pool, 146 apr_pool_t *scratch_pool); 147 148 149/* Assert that the given WCROOT is usable. 150 NOTE: the expression is multiply-evaluated!! */ 151#define VERIFY_USABLE_WCROOT(wcroot) SVN_ERR_ASSERT( \ 152 (wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION) 153 154/* Check if the WCROOT is usable for light db operations such as path 155 calculations */ 156#define CHECK_MINIMAL_WCROOT(wcroot, abspath, scratch_pool) \ 157 do \ 158 { \ 159 if (wcroot == NULL) \ 160 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, \ 161 _("The node '%s' is not in a working copy."), \ 162 svn_dirent_local_style(wri_abspath, \ 163 scratch_pool)); \ 164 } \ 165 while (0) 166 167/* Calculates the depth of the relpath below "" */ 168APR_INLINE static int 169relpath_depth(const char *relpath) 170{ 171 int n = 1; 172 if (*relpath == '\0') 173 return 0; 174 175 do 176 { 177 if (*relpath == '/') 178 n++; 179 } 180 while (*(++relpath)); 181 182 return n; 183} 184 185 186/* */ 187svn_error_t * 188svn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id, 189 svn_sqlite__db_t *sdb, 190 apr_pool_t *scratch_pool); 191 192/* Open a connection in *SDB to the WC database found in the WC metadata 193 * directory inside DIR_ABSPATH, having the filename SDB_FNAME. 194 * 195 * SMODE is passed to svn_sqlite__open(). 196 * 197 * Register MY_STATEMENTS, or if that is null, the default set of WC DB 198 * statements, as the set of statements to be prepared now and executed 199 * later. MY_STATEMENTS (the strings and the array itself) is not duplicated 200 * internally, and should have a lifetime at least as long as RESULT_POOL. 201 * See svn_sqlite__open() for details. */ 202svn_error_t * 203svn_wc__db_util_open_db(svn_sqlite__db_t **sdb, 204 const char *dir_abspath, 205 const char *sdb_fname, 206 svn_sqlite__mode_t smode, 207 svn_boolean_t exclusive, 208 const char *const *my_statements, 209 apr_pool_t *result_pool, 210 apr_pool_t *scratch_pool); 211 212/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of 213 DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */ 214svn_error_t * 215svn_wc__db_read_info_internal(svn_wc__db_status_t *status, 216 svn_node_kind_t *kind, 217 svn_revnum_t *revision, 218 const char **repos_relpath, 219 apr_int64_t *repos_id, 220 svn_revnum_t *changed_rev, 221 apr_time_t *changed_date, 222 const char **changed_author, 223 svn_depth_t *depth, 224 const svn_checksum_t **checksum, 225 const char **target, 226 const char **original_repos_relpath, 227 apr_int64_t *original_repos_id, 228 svn_revnum_t *original_revision, 229 svn_wc__db_lock_t **lock, 230 svn_filesize_t *recorded_size, 231 apr_time_t *recorded_mod_time, 232 const char **changelist, 233 svn_boolean_t *conflicted, 234 svn_boolean_t *op_root, 235 svn_boolean_t *had_props, 236 svn_boolean_t *props_mod, 237 svn_boolean_t *have_base, 238 svn_boolean_t *have_more_work, 239 svn_boolean_t *have_work, 240 svn_wc__db_wcroot_t *wcroot, 241 const char *local_relpath, 242 apr_pool_t *result_pool, 243 apr_pool_t *scratch_pool); 244 245/* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of 246 DB+LOCAL_ABSPATH and outputting REPOS_ID instead of URL+UUID. */ 247svn_error_t * 248svn_wc__db_base_get_info_internal(svn_wc__db_status_t *status, 249 svn_node_kind_t *kind, 250 svn_revnum_t *revision, 251 const char **repos_relpath, 252 apr_int64_t *repos_id, 253 svn_revnum_t *changed_rev, 254 apr_time_t *changed_date, 255 const char **changed_author, 256 svn_depth_t *depth, 257 const svn_checksum_t **checksum, 258 const char **target, 259 svn_wc__db_lock_t **lock, 260 svn_boolean_t *had_props, 261 apr_hash_t **props, 262 svn_boolean_t *update_root, 263 svn_wc__db_wcroot_t *wcroot, 264 const char *local_relpath, 265 apr_pool_t *result_pool, 266 apr_pool_t *scratch_pool); 267 268/* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH 269 * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get 270 * information about, and outputting REPOS_ID instead of URL+UUID, and 271 * without the LOCK or UPDATE_ROOT outputs. 272 * 273 * OR 274 * 275 * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit 276 * op-depth OP_DEPTH of the node to get information about, and without the 277 * LOCK or UPDATE_ROOT outputs. 278 * 279 * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with 280 * svn_wc__db_depth_get_info -- common API, common implementation. 281 */ 282svn_error_t * 283svn_wc__db_depth_get_info(svn_wc__db_status_t *status, 284 svn_node_kind_t *kind, 285 svn_revnum_t *revision, 286 const char **repos_relpath, 287 apr_int64_t *repos_id, 288 svn_revnum_t *changed_rev, 289 apr_time_t *changed_date, 290 const char **changed_author, 291 svn_depth_t *depth, 292 const svn_checksum_t **checksum, 293 const char **target, 294 svn_boolean_t *had_props, 295 apr_hash_t **props, 296 svn_wc__db_wcroot_t *wcroot, 297 const char *local_relpath, 298 int op_depth, 299 apr_pool_t *result_pool, 300 apr_pool_t *scratch_pool); 301 302/* Look up REPOS_ID in SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID to 303 its root URL and UUID respectively. If REPOS_ID is INVALID_REPOS_ID, 304 use NULL for both URL and UUID. Either or both output parameters may be 305 NULL if not wanted. */ 306svn_error_t * 307svn_wc__db_fetch_repos_info(const char **repos_root_url, 308 const char **repos_uuid, 309 svn_sqlite__db_t *sdb, 310 apr_int64_t repos_id, 311 apr_pool_t *result_pool); 312 313/* Like svn_wc__db_read_conflict(), but with WCROOT+LOCAL_RELPATH instead of 314 DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */ 315svn_error_t * 316svn_wc__db_read_conflict_internal(svn_skel_t **conflict, 317 svn_wc__db_wcroot_t *wcroot, 318 const char *local_relpath, 319 apr_pool_t *result_pool, 320 apr_pool_t *scratch_pool); 321 322/* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of 323 DB+LOCAL_ABSPATH. */ 324svn_error_t * 325svn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot, 326 const char *local_relpath, 327 const svn_skel_t *conflict_skel, 328 apr_pool_t *scratch_pool); 329 330 331/* Transaction handling */ 332 333/* A callback which supplies WCROOTs and LOCAL_RELPATHs. */ 334typedef svn_error_t *(*svn_wc__db_txn_callback_t)(void *baton, 335 svn_wc__db_wcroot_t *wcroot, 336 const char *local_relpath, 337 apr_pool_t *scratch_pool); 338 339 340/* Run CB_FUNC in a SQLite transaction with CB_BATON, using WCROOT and 341 LOCAL_RELPATH. If callbacks require additional information, they may 342 provide it using CB_BATON. */ 343svn_error_t * 344svn_wc__db_with_txn(svn_wc__db_wcroot_t *wcroot, 345 const char *local_relpath, 346 svn_wc__db_txn_callback_t cb_func, 347 void *cb_baton, 348 apr_pool_t *scratch_pool); 349 350/* Evaluate the expression EXPR within a transaction. 351 * 352 * Begin a transaction in WCROOT's DB; evaluate the expression EXPR, which would 353 * typically be a function call that does some work in DB; finally commit 354 * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back 355 * the transaction. 356 */ 357#define SVN_WC__DB_WITH_TXN(expr, wcroot) \ 358 SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb) 359 360 361/* Return CHILDREN mapping const char * names to svn_node_kind_t * for the 362 children of LOCAL_RELPATH at OP_DEPTH. */ 363svn_error_t * 364svn_wc__db_get_children_op_depth(apr_hash_t **children, 365 svn_wc__db_wcroot_t *wcroot, 366 const char *local_relpath, 367 int op_depth, 368 apr_pool_t *result_pool, 369 apr_pool_t *scratch_pool); 370 371 372/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH. 373 374 ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm 375 discussing on dev@ whether we can let that be null for presence 376 == base-deleted. OP_DEPTH is the op-depth of what, and why? 377 It is used to select the lowest working node higher than OP_DEPTH, 378 so, in terms of the API, OP_DEPTH means ...? 379 380 Given a wc: 381 382 0 1 2 3 4 383 normal 384 A normal 385 A/B normal normal 386 A/B/C not-pres normal 387 A/B/C/D normal 388 389 That is checkout, delete A/B, copy a replacement A/B, delete copied 390 child A/B/C, add replacement A/B/C, add A/B/C/D. 391 392 Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E 393 must extend the A/B deletion: 394 395 0 1 2 3 4 396 normal 397 A normal 398 A/B normal normal 399 A/B/C normal not-pres normal 400 A/B/C/D normal base-del normal 401 A/B/C/D/E normal base-del 402 403 When adding a node if the parent has a higher working node then the 404 parent node is deleted (or replaced) and the delete must be extended 405 to cover new node. 406 407 In the example above A/B/C/D and A/B/C/D/E are the nodes that get 408 the extended delete, A/B/C is already deleted. 409 */ 410svn_error_t * 411svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot, 412 const char *local_relpath, 413 svn_node_kind_t kind, 414 int op_depth, 415 apr_pool_t *scratch_pool); 416 417svn_error_t * 418svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot, 419 const char *local_relpath, 420 int op_depth, 421 apr_pool_t *scratch_pool); 422 423svn_error_t * 424svn_wc__db_op_depth_moved_to(const char **move_dst_relpath, 425 const char **move_dst_op_root_relpath, 426 const char **move_src_root_relpath, 427 const char **move_src_op_root_relpath, 428 int op_depth, 429 svn_wc__db_wcroot_t *wcroot, 430 const char *local_relpath, 431 apr_pool_t *result_pool, 432 apr_pool_t *scratch_pool); 433 434/* Do a post-drive revision bump for the moved-away destination for 435 any move sources under LOCAL_RELPATH. This is called from within 436 the revision bump transaction after the tree at LOCAL_RELPATH has 437 been bumped. */ 438svn_error_t * 439svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot, 440 const char *local_relpath, 441 svn_depth_t depth, 442 svn_wc__db_t *db, 443 apr_pool_t *scratch_pool); 444 445/* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making 446 the destination a normal copy */ 447svn_error_t * 448svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot, 449 const char *local_relpath, 450 int op_depth, 451 apr_pool_t *scratch_pool); 452 453svn_error_t * 454svn_wc__db_update_move_list_notify(svn_wc__db_wcroot_t *wcroot, 455 svn_revnum_t old_revision, 456 svn_revnum_t new_revision, 457 svn_wc_notify_func2_t notify_func, 458 void *notify_baton, 459 apr_pool_t *scratch_pool); 460 461#endif /* WC_DB_PRIVATE_H */ 462