1251881Speter/** 2251881Speter * @copyright 3251881Speter * ==================================================================== 4251881Speter * Licensed to the Apache Software Foundation (ASF) under one 5251881Speter * or more contributor license agreements. See the NOTICE file 6251881Speter * distributed with this work for additional information 7251881Speter * regarding copyright ownership. The ASF licenses this file 8251881Speter * to you under the Apache License, Version 2.0 (the 9251881Speter * "License"); you may not use this file except in compliance 10251881Speter * with the License. You may obtain a copy of the License at 11251881Speter * 12251881Speter * http://www.apache.org/licenses/LICENSE-2.0 13251881Speter * 14251881Speter * Unless required by applicable law or agreed to in writing, 15251881Speter * software distributed under the License is distributed on an 16251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17251881Speter * KIND, either express or implied. See the License for the 18251881Speter * specific language governing permissions and limitations 19251881Speter * under the License. 20251881Speter * ==================================================================== 21251881Speter * @endcopyright 22251881Speter */ 23251881Speter 24251881Speter/* This file is not for general consumption; it should only be used by 25251881Speter wc_db.c. */ 26251881Speter#ifndef SVN_WC__I_AM_WC_DB 27251881Speter#error "You should not be using these data structures directly" 28251881Speter#endif /* SVN_WC__I_AM_WC_DB */ 29251881Speter 30251881Speter#ifndef WC_DB_PRIVATE_H 31251881Speter#define WC_DB_PRIVATE_H 32251881Speter 33251881Speter#include "wc_db.h" 34251881Speter 35251881Speter 36251881Speterstruct svn_wc__db_t { 37251881Speter /* We need the config whenever we run into a new WC directory, in order 38251881Speter to figure out where we should look for the corresponding datastore. */ 39251881Speter svn_config_t *config; 40251881Speter 41251881Speter /* Should we fail with SVN_ERR_WC_UPGRADE_REQUIRED when it is 42251881Speter opened, and found to be not-current? */ 43251881Speter svn_boolean_t verify_format; 44251881Speter 45251881Speter /* Should we ensure the WORK_QUEUE is empty when a WCROOT is opened? */ 46251881Speter svn_boolean_t enforce_empty_wq; 47251881Speter 48251881Speter /* Should we open Sqlite databases EXCLUSIVE */ 49251881Speter svn_boolean_t exclusive; 50251881Speter 51251881Speter /* Map a given working copy directory to its relevant data. 52251881Speter const char *local_abspath -> svn_wc__db_wcroot_t *wcroot */ 53251881Speter apr_hash_t *dir_data; 54251881Speter 55251881Speter /* A few members to assist with caching of kind values for paths. See 56251881Speter get_path_kind() for use. */ 57251881Speter struct 58251881Speter { 59251881Speter svn_stringbuf_t *abspath; 60251881Speter svn_node_kind_t kind; 61251881Speter } parse_cache; 62251881Speter 63251881Speter /* As we grow the state of this DB, allocate that state here. */ 64251881Speter apr_pool_t *state_pool; 65251881Speter}; 66251881Speter 67251881Speter 68251881Speter/* Hold information about an owned lock */ 69251881Spetertypedef struct svn_wc__db_wclock_t 70251881Speter{ 71251881Speter /* Relative path of the lock root */ 72251881Speter const char *local_relpath; 73251881Speter 74251881Speter /* Number of levels locked (0 for infinity) */ 75251881Speter int levels; 76251881Speter} svn_wc__db_wclock_t; 77251881Speter 78251881Speter 79251881Speter/** Hold information about a WCROOT. 80251881Speter * 81251881Speter * This structure is referenced by all per-directory handles underneath it. 82251881Speter */ 83251881Spetertypedef struct svn_wc__db_wcroot_t { 84251881Speter /* Location of this wcroot in the filesystem. */ 85251881Speter const char *abspath; 86251881Speter 87251881Speter /* The SQLite database containing the metadata for everything in 88251881Speter this wcroot. */ 89251881Speter svn_sqlite__db_t *sdb; 90251881Speter 91251881Speter /* The WCROOT.id for this directory (and all its children). */ 92251881Speter apr_int64_t wc_id; 93251881Speter 94251881Speter /* The format of this wcroot's metadata storage (see wc.h). If the 95251881Speter format has not (yet) been determined, this will be UNKNOWN_FORMAT. */ 96251881Speter int format; 97251881Speter 98251881Speter /* Array of svn_wc__db_wclock_t structures (not pointers!). 99251881Speter Typically just one or two locks maximum. */ 100251881Speter apr_array_header_t *owned_locks; 101251881Speter 102251881Speter /* Map a working copy directory to a cached adm_access baton. 103251881Speter const char *local_abspath -> svn_wc_adm_access_t *adm_access */ 104251881Speter apr_hash_t *access_cache; 105251881Speter 106251881Speter} svn_wc__db_wcroot_t; 107251881Speter 108251881Speter 109251881Speter/* */ 110251881Spetersvn_error_t * 111251881Spetersvn_wc__db_close_many_wcroots(apr_hash_t *roots, 112251881Speter apr_pool_t *state_pool, 113251881Speter apr_pool_t *scratch_pool); 114251881Speter 115251881Speter 116251881Speter/* Construct a new svn_wc__db_wcroot_t. The WCROOT_ABSPATH and SDB parameters 117251881Speter must have lifetime of at least RESULT_POOL. */ 118251881Spetersvn_error_t * 119251881Spetersvn_wc__db_pdh_create_wcroot(svn_wc__db_wcroot_t **wcroot, 120251881Speter const char *wcroot_abspath, 121251881Speter svn_sqlite__db_t *sdb, 122251881Speter apr_int64_t wc_id, 123251881Speter int format, 124251881Speter svn_boolean_t verify_format, 125251881Speter svn_boolean_t enforce_empty_wq, 126251881Speter apr_pool_t *result_pool, 127251881Speter apr_pool_t *scratch_pool); 128251881Speter 129251881Speter 130251881Speter/* For a given LOCAL_ABSPATH, figure out what sqlite database (WCROOT) to 131251881Speter use and the RELPATH within that wcroot. 132251881Speter 133251881Speter *LOCAL_RELPATH will be allocated within RESULT_POOL. Temporary allocations 134251881Speter will be made in SCRATCH_POOL. 135251881Speter 136251881Speter *WCROOT will be allocated within DB->STATE_POOL. 137251881Speter 138251881Speter Certain internal structures will be allocated in DB->STATE_POOL. 139251881Speter*/ 140251881Spetersvn_error_t * 141251881Spetersvn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot, 142251881Speter const char **local_relpath, 143251881Speter svn_wc__db_t *db, 144251881Speter const char *local_abspath, 145251881Speter apr_pool_t *result_pool, 146251881Speter apr_pool_t *scratch_pool); 147251881Speter 148251881Speter 149251881Speter/* Assert that the given WCROOT is usable. 150251881Speter NOTE: the expression is multiply-evaluated!! */ 151251881Speter#define VERIFY_USABLE_WCROOT(wcroot) SVN_ERR_ASSERT( \ 152251881Speter (wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION) 153251881Speter 154251881Speter/* Check if the WCROOT is usable for light db operations such as path 155251881Speter calculations */ 156251881Speter#define CHECK_MINIMAL_WCROOT(wcroot, abspath, scratch_pool) \ 157251881Speter do \ 158251881Speter { \ 159251881Speter if (wcroot == NULL) \ 160251881Speter return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, \ 161251881Speter _("The node '%s' is not in a working copy."), \ 162251881Speter svn_dirent_local_style(wri_abspath, \ 163251881Speter scratch_pool)); \ 164251881Speter } \ 165251881Speter while (0) 166251881Speter 167251881Speter/* Calculates the depth of the relpath below "" */ 168251881SpeterAPR_INLINE static int 169251881Speterrelpath_depth(const char *relpath) 170251881Speter{ 171251881Speter int n = 1; 172251881Speter if (*relpath == '\0') 173251881Speter return 0; 174251881Speter 175251881Speter do 176251881Speter { 177251881Speter if (*relpath == '/') 178251881Speter n++; 179251881Speter } 180251881Speter while (*(++relpath)); 181251881Speter 182251881Speter return n; 183251881Speter} 184251881Speter 185251881Speter 186251881Speter/* */ 187251881Spetersvn_error_t * 188251881Spetersvn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id, 189251881Speter svn_sqlite__db_t *sdb, 190251881Speter apr_pool_t *scratch_pool); 191251881Speter 192251881Speter/* Open a connection in *SDB to the WC database found in the WC metadata 193251881Speter * directory inside DIR_ABSPATH, having the filename SDB_FNAME. 194251881Speter * 195251881Speter * SMODE is passed to svn_sqlite__open(). 196251881Speter * 197251881Speter * Register MY_STATEMENTS, or if that is null, the default set of WC DB 198251881Speter * statements, as the set of statements to be prepared now and executed 199251881Speter * later. MY_STATEMENTS (the strings and the array itself) is not duplicated 200251881Speter * internally, and should have a lifetime at least as long as RESULT_POOL. 201251881Speter * See svn_sqlite__open() for details. */ 202251881Spetersvn_error_t * 203251881Spetersvn_wc__db_util_open_db(svn_sqlite__db_t **sdb, 204251881Speter const char *dir_abspath, 205251881Speter const char *sdb_fname, 206251881Speter svn_sqlite__mode_t smode, 207251881Speter svn_boolean_t exclusive, 208251881Speter const char *const *my_statements, 209251881Speter apr_pool_t *result_pool, 210251881Speter apr_pool_t *scratch_pool); 211251881Speter 212251881Speter/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of 213251881Speter DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */ 214251881Spetersvn_error_t * 215251881Spetersvn_wc__db_read_info_internal(svn_wc__db_status_t *status, 216251881Speter svn_node_kind_t *kind, 217251881Speter svn_revnum_t *revision, 218251881Speter const char **repos_relpath, 219251881Speter apr_int64_t *repos_id, 220251881Speter svn_revnum_t *changed_rev, 221251881Speter apr_time_t *changed_date, 222251881Speter const char **changed_author, 223251881Speter svn_depth_t *depth, 224251881Speter const svn_checksum_t **checksum, 225251881Speter const char **target, 226251881Speter const char **original_repos_relpath, 227251881Speter apr_int64_t *original_repos_id, 228251881Speter svn_revnum_t *original_revision, 229251881Speter svn_wc__db_lock_t **lock, 230251881Speter svn_filesize_t *recorded_size, 231251881Speter apr_time_t *recorded_mod_time, 232251881Speter const char **changelist, 233251881Speter svn_boolean_t *conflicted, 234251881Speter svn_boolean_t *op_root, 235251881Speter svn_boolean_t *had_props, 236251881Speter svn_boolean_t *props_mod, 237251881Speter svn_boolean_t *have_base, 238251881Speter svn_boolean_t *have_more_work, 239251881Speter svn_boolean_t *have_work, 240251881Speter svn_wc__db_wcroot_t *wcroot, 241251881Speter const char *local_relpath, 242251881Speter apr_pool_t *result_pool, 243251881Speter apr_pool_t *scratch_pool); 244251881Speter 245251881Speter/* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of 246251881Speter DB+LOCAL_ABSPATH and outputting REPOS_ID instead of URL+UUID. */ 247251881Spetersvn_error_t * 248251881Spetersvn_wc__db_base_get_info_internal(svn_wc__db_status_t *status, 249251881Speter svn_node_kind_t *kind, 250251881Speter svn_revnum_t *revision, 251251881Speter const char **repos_relpath, 252251881Speter apr_int64_t *repos_id, 253251881Speter svn_revnum_t *changed_rev, 254251881Speter apr_time_t *changed_date, 255251881Speter const char **changed_author, 256251881Speter svn_depth_t *depth, 257251881Speter const svn_checksum_t **checksum, 258251881Speter const char **target, 259251881Speter svn_wc__db_lock_t **lock, 260251881Speter svn_boolean_t *had_props, 261251881Speter apr_hash_t **props, 262251881Speter svn_boolean_t *update_root, 263251881Speter svn_wc__db_wcroot_t *wcroot, 264251881Speter const char *local_relpath, 265251881Speter apr_pool_t *result_pool, 266251881Speter apr_pool_t *scratch_pool); 267251881Speter 268251881Speter/* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH 269251881Speter * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get 270251881Speter * information about, and outputting REPOS_ID instead of URL+UUID, and 271251881Speter * without the LOCK or UPDATE_ROOT outputs. 272251881Speter * 273251881Speter * OR 274251881Speter * 275251881Speter * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit 276251881Speter * op-depth OP_DEPTH of the node to get information about, and without the 277251881Speter * LOCK or UPDATE_ROOT outputs. 278251881Speter * 279251881Speter * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with 280251881Speter * svn_wc__db_depth_get_info -- common API, common implementation. 281251881Speter */ 282251881Spetersvn_error_t * 283251881Spetersvn_wc__db_depth_get_info(svn_wc__db_status_t *status, 284251881Speter svn_node_kind_t *kind, 285251881Speter svn_revnum_t *revision, 286251881Speter const char **repos_relpath, 287251881Speter apr_int64_t *repos_id, 288251881Speter svn_revnum_t *changed_rev, 289251881Speter apr_time_t *changed_date, 290251881Speter const char **changed_author, 291251881Speter svn_depth_t *depth, 292251881Speter const svn_checksum_t **checksum, 293251881Speter const char **target, 294251881Speter svn_boolean_t *had_props, 295251881Speter apr_hash_t **props, 296251881Speter svn_wc__db_wcroot_t *wcroot, 297251881Speter const char *local_relpath, 298251881Speter int op_depth, 299251881Speter apr_pool_t *result_pool, 300251881Speter apr_pool_t *scratch_pool); 301251881Speter 302251881Speter/* Look up REPOS_ID in SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID to 303251881Speter its root URL and UUID respectively. If REPOS_ID is INVALID_REPOS_ID, 304251881Speter use NULL for both URL and UUID. Either or both output parameters may be 305251881Speter NULL if not wanted. */ 306251881Spetersvn_error_t * 307251881Spetersvn_wc__db_fetch_repos_info(const char **repos_root_url, 308251881Speter const char **repos_uuid, 309251881Speter svn_sqlite__db_t *sdb, 310251881Speter apr_int64_t repos_id, 311251881Speter apr_pool_t *result_pool); 312251881Speter 313251881Speter/* Like svn_wc__db_read_conflict(), but with WCROOT+LOCAL_RELPATH instead of 314251881Speter DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */ 315251881Spetersvn_error_t * 316251881Spetersvn_wc__db_read_conflict_internal(svn_skel_t **conflict, 317251881Speter svn_wc__db_wcroot_t *wcroot, 318251881Speter const char *local_relpath, 319251881Speter apr_pool_t *result_pool, 320251881Speter apr_pool_t *scratch_pool); 321251881Speter 322251881Speter/* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of 323251881Speter DB+LOCAL_ABSPATH. */ 324251881Spetersvn_error_t * 325251881Spetersvn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot, 326251881Speter const char *local_relpath, 327251881Speter const svn_skel_t *conflict_skel, 328251881Speter apr_pool_t *scratch_pool); 329251881Speter 330251881Speter 331251881Speter/* Transaction handling */ 332251881Speter 333251881Speter/* A callback which supplies WCROOTs and LOCAL_RELPATHs. */ 334251881Spetertypedef svn_error_t *(*svn_wc__db_txn_callback_t)(void *baton, 335251881Speter svn_wc__db_wcroot_t *wcroot, 336251881Speter const char *local_relpath, 337251881Speter apr_pool_t *scratch_pool); 338251881Speter 339251881Speter 340251881Speter/* Run CB_FUNC in a SQLite transaction with CB_BATON, using WCROOT and 341251881Speter LOCAL_RELPATH. If callbacks require additional information, they may 342251881Speter provide it using CB_BATON. */ 343251881Spetersvn_error_t * 344251881Spetersvn_wc__db_with_txn(svn_wc__db_wcroot_t *wcroot, 345251881Speter const char *local_relpath, 346251881Speter svn_wc__db_txn_callback_t cb_func, 347251881Speter void *cb_baton, 348251881Speter apr_pool_t *scratch_pool); 349251881Speter 350251881Speter/* Evaluate the expression EXPR within a transaction. 351251881Speter * 352251881Speter * Begin a transaction in WCROOT's DB; evaluate the expression EXPR, which would 353251881Speter * typically be a function call that does some work in DB; finally commit 354251881Speter * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back 355251881Speter * the transaction. 356251881Speter */ 357251881Speter#define SVN_WC__DB_WITH_TXN(expr, wcroot) \ 358251881Speter SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb) 359251881Speter 360251881Speter 361251881Speter/* Return CHILDREN mapping const char * names to svn_node_kind_t * for the 362251881Speter children of LOCAL_RELPATH at OP_DEPTH. */ 363251881Spetersvn_error_t * 364251881Spetersvn_wc__db_get_children_op_depth(apr_hash_t **children, 365251881Speter svn_wc__db_wcroot_t *wcroot, 366251881Speter const char *local_relpath, 367251881Speter int op_depth, 368251881Speter apr_pool_t *result_pool, 369251881Speter apr_pool_t *scratch_pool); 370251881Speter 371251881Speter 372251881Speter/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH. 373251881Speter 374251881Speter ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm 375251881Speter discussing on dev@ whether we can let that be null for presence 376251881Speter == base-deleted. OP_DEPTH is the op-depth of what, and why? 377251881Speter It is used to select the lowest working node higher than OP_DEPTH, 378251881Speter so, in terms of the API, OP_DEPTH means ...? 379251881Speter 380251881Speter Given a wc: 381251881Speter 382251881Speter 0 1 2 3 4 383251881Speter normal 384251881Speter A normal 385251881Speter A/B normal normal 386251881Speter A/B/C not-pres normal 387251881Speter A/B/C/D normal 388251881Speter 389251881Speter That is checkout, delete A/B, copy a replacement A/B, delete copied 390251881Speter child A/B/C, add replacement A/B/C, add A/B/C/D. 391251881Speter 392251881Speter Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E 393251881Speter must extend the A/B deletion: 394251881Speter 395251881Speter 0 1 2 3 4 396251881Speter normal 397251881Speter A normal 398251881Speter A/B normal normal 399251881Speter A/B/C normal not-pres normal 400251881Speter A/B/C/D normal base-del normal 401251881Speter A/B/C/D/E normal base-del 402251881Speter 403251881Speter When adding a node if the parent has a higher working node then the 404251881Speter parent node is deleted (or replaced) and the delete must be extended 405251881Speter to cover new node. 406251881Speter 407251881Speter In the example above A/B/C/D and A/B/C/D/E are the nodes that get 408251881Speter the extended delete, A/B/C is already deleted. 409251881Speter */ 410251881Spetersvn_error_t * 411251881Spetersvn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot, 412251881Speter const char *local_relpath, 413251881Speter svn_node_kind_t kind, 414251881Speter int op_depth, 415251881Speter apr_pool_t *scratch_pool); 416251881Speter 417251881Spetersvn_error_t * 418251881Spetersvn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot, 419251881Speter const char *local_relpath, 420251881Speter int op_depth, 421251881Speter apr_pool_t *scratch_pool); 422251881Speter 423251881Spetersvn_error_t * 424251881Spetersvn_wc__db_op_depth_moved_to(const char **move_dst_relpath, 425251881Speter const char **move_dst_op_root_relpath, 426251881Speter const char **move_src_root_relpath, 427251881Speter const char **move_src_op_root_relpath, 428251881Speter int op_depth, 429251881Speter svn_wc__db_wcroot_t *wcroot, 430251881Speter const char *local_relpath, 431251881Speter apr_pool_t *result_pool, 432251881Speter apr_pool_t *scratch_pool); 433251881Speter 434251881Speter/* Do a post-drive revision bump for the moved-away destination for 435251881Speter any move sources under LOCAL_RELPATH. This is called from within 436251881Speter the revision bump transaction after the tree at LOCAL_RELPATH has 437251881Speter been bumped. */ 438251881Spetersvn_error_t * 439251881Spetersvn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot, 440251881Speter const char *local_relpath, 441251881Speter svn_depth_t depth, 442251881Speter svn_wc__db_t *db, 443251881Speter apr_pool_t *scratch_pool); 444251881Speter 445262253Speter/* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making 446262253Speter the destination a normal copy */ 447251881Spetersvn_error_t * 448251881Spetersvn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot, 449251881Speter const char *local_relpath, 450262253Speter int op_depth, 451251881Speter apr_pool_t *scratch_pool); 452251881Speter 453251881Spetersvn_error_t * 454251881Spetersvn_wc__db_update_move_list_notify(svn_wc__db_wcroot_t *wcroot, 455251881Speter svn_revnum_t old_revision, 456251881Speter svn_revnum_t new_revision, 457251881Speter svn_wc_notify_func2_t notify_func, 458251881Speter void *notify_baton, 459251881Speter apr_pool_t *scratch_pool); 460251881Speter 461251881Speter#endif /* WC_DB_PRIVATE_H */ 462