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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * ====================================================================
24 /* This file is not for general consumption; it should only be used by
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 */
30 #ifndef WC_DB_PRIVATE_H
31 #define WC_DB_PRIVATE_H
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. */
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;
45 /* Should we ensure the WORK_QUEUE is empty when a DB is locked
47 svn_boolean_t enforce_empty_wq;
49 /* Should we open Sqlite databases EXCLUSIVE */
50 svn_boolean_t exclusive;
52 /* Busy timeout in ms., 0 for the libsvn_subr default. */
55 /* Map a given working copy directory to its relevant data.
56 const char *local_abspath -> svn_wc__db_wcroot_t *wcroot */
59 /* A few members to assist with caching of kind values for paths. See
60 get_path_kind() for use. */
63 svn_stringbuf_t *abspath;
67 /* As we grow the state of this DB, allocate that state here. */
68 apr_pool_t *state_pool;
72 /* Hold information about an owned lock */
73 typedef struct svn_wc__db_wclock_t
75 /* Relative path of the lock root */
76 const char *local_relpath;
78 /* Number of levels locked (0 for infinity) */
80 } svn_wc__db_wclock_t;
83 /** Hold information about a WCROOT.
85 * This structure is referenced by all per-directory handles underneath it.
87 typedef struct svn_wc__db_wcroot_t {
88 /* Location of this wcroot in the filesystem. */
91 /* The SQLite database containing the metadata for everything in
93 svn_sqlite__db_t *sdb;
95 /* The WCROOT.id for this directory (and all its children). */
98 /* The format of this wcroot's metadata storage (see wc.h). If the
99 format has not (yet) been determined, this will be UNKNOWN_FORMAT. */
102 /* Array of svn_wc__db_wclock_t structures (not pointers!).
103 Typically just one or two locks maximum. */
104 apr_array_header_t *owned_locks;
106 /* Map a working copy directory to a cached adm_access baton.
107 const char *local_abspath -> svn_wc_adm_access_t *adm_access */
108 apr_hash_t *access_cache;
110 } svn_wc__db_wcroot_t;
115 svn_wc__db_close_many_wcroots(apr_hash_t *roots,
116 apr_pool_t *state_pool,
117 apr_pool_t *scratch_pool);
120 /* Construct a new svn_wc__db_wcroot_t. The WCROOT_ABSPATH and SDB parameters
121 must have lifetime of at least RESULT_POOL. */
123 svn_wc__db_pdh_create_wcroot(svn_wc__db_wcroot_t **wcroot,
124 const char *wcroot_abspath,
125 svn_sqlite__db_t *sdb,
128 svn_boolean_t verify_format,
129 apr_pool_t *result_pool,
130 apr_pool_t *scratch_pool);
133 /* For a given LOCAL_ABSPATH, figure out what sqlite database (WCROOT) to
134 use and the RELPATH within that wcroot.
136 *LOCAL_RELPATH will be allocated within RESULT_POOL. Temporary allocations
137 will be made in SCRATCH_POOL.
139 *WCROOT will be allocated within DB->STATE_POOL.
141 Certain internal structures will be allocated in DB->STATE_POOL.
144 svn_wc__db_wcroot_parse_local_abspath(svn_wc__db_wcroot_t **wcroot,
145 const char **local_relpath,
147 const char *local_abspath,
148 apr_pool_t *result_pool,
149 apr_pool_t *scratch_pool);
151 /* Return an error if the work queue in SDB is non-empty. */
153 svn_wc__db_verify_no_work(svn_sqlite__db_t *sdb);
155 /* Assert that the given WCROOT is usable.
156 NOTE: the expression is multiply-evaluated!! */
157 #define VERIFY_USABLE_WCROOT(wcroot) SVN_ERR_ASSERT( \
158 (wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION)
160 /* Check if the WCROOT is usable for light db operations such as path
162 #define CHECK_MINIMAL_WCROOT(wcroot, abspath, scratch_pool) \
165 if (wcroot == NULL) \
166 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, \
167 _("The node '%s' is not in a working copy."), \
168 svn_dirent_local_style(wri_abspath, \
173 /* Calculates the depth of the relpath below "" */
174 APR_INLINE static int
175 relpath_depth(const char *relpath)
178 if (*relpath == '\0')
186 while (*(++relpath));
194 svn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id,
195 svn_sqlite__db_t *sdb,
196 apr_pool_t *scratch_pool);
198 /* Open a connection in *SDB to the WC database found in the WC metadata
199 * directory inside DIR_ABSPATH, having the filename SDB_FNAME.
201 * SMODE, EXCLUSIVE and TIMEOUT are passed to svn_sqlite__open().
203 * Register MY_STATEMENTS, or if that is null, the default set of WC DB
204 * statements, as the set of statements to be prepared now and executed
205 * later. MY_STATEMENTS (the strings and the array itself) is not duplicated
206 * internally, and should have a lifetime at least as long as RESULT_POOL.
207 * See svn_sqlite__open() for details. */
209 svn_wc__db_util_open_db(svn_sqlite__db_t **sdb,
210 const char *dir_abspath,
211 const char *sdb_fname,
212 svn_sqlite__mode_t smode,
213 svn_boolean_t exclusive,
215 const char *const *my_statements,
216 apr_pool_t *result_pool,
217 apr_pool_t *scratch_pool);
219 /* Like svn_wc__db_wq_add() but taking WCROOT */
221 svn_wc__db_wq_add_internal(svn_wc__db_wcroot_t *wcroot,
222 const svn_skel_t *work_item,
223 apr_pool_t *scratch_pool);
226 /* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
227 DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
229 svn_wc__db_read_info_internal(svn_wc__db_status_t *status,
230 svn_node_kind_t *kind,
231 svn_revnum_t *revision,
232 const char **repos_relpath,
233 apr_int64_t *repos_id,
234 svn_revnum_t *changed_rev,
235 apr_time_t *changed_date,
236 const char **changed_author,
238 const svn_checksum_t **checksum,
240 const char **original_repos_relpath,
241 apr_int64_t *original_repos_id,
242 svn_revnum_t *original_revision,
243 svn_wc__db_lock_t **lock,
244 svn_filesize_t *recorded_size,
245 apr_time_t *recorded_mod_time,
246 const char **changelist,
247 svn_boolean_t *conflicted,
248 svn_boolean_t *op_root,
249 svn_boolean_t *had_props,
250 svn_boolean_t *props_mod,
251 svn_boolean_t *have_base,
252 svn_boolean_t *have_more_work,
253 svn_boolean_t *have_work,
254 svn_wc__db_wcroot_t *wcroot,
255 const char *local_relpath,
256 apr_pool_t *result_pool,
257 apr_pool_t *scratch_pool);
259 /* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of
260 DB+LOCAL_ABSPATH and outputting REPOS_ID instead of URL+UUID. */
262 svn_wc__db_base_get_info_internal(svn_wc__db_status_t *status,
263 svn_node_kind_t *kind,
264 svn_revnum_t *revision,
265 const char **repos_relpath,
266 apr_int64_t *repos_id,
267 svn_revnum_t *changed_rev,
268 apr_time_t *changed_date,
269 const char **changed_author,
271 const svn_checksum_t **checksum,
273 svn_wc__db_lock_t **lock,
274 svn_boolean_t *had_props,
276 svn_boolean_t *update_root,
277 svn_wc__db_wcroot_t *wcroot,
278 const char *local_relpath,
279 apr_pool_t *result_pool,
280 apr_pool_t *scratch_pool);
282 /* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH
283 * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get
284 * information about, and outputting REPOS_ID instead of URL+UUID, and
285 * without the LOCK or UPDATE_ROOT outputs.
289 * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit
290 * op-depth OP_DEPTH of the node to get information about, and without the
291 * LOCK or UPDATE_ROOT outputs.
293 * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with
294 * svn_wc__db_depth_get_info -- common API, common implementation.
297 svn_wc__db_depth_get_info(svn_wc__db_status_t *status,
298 svn_node_kind_t *kind,
299 svn_revnum_t *revision,
300 const char **repos_relpath,
301 apr_int64_t *repos_id,
302 svn_revnum_t *changed_rev,
303 apr_time_t *changed_date,
304 const char **changed_author,
306 const svn_checksum_t **checksum,
308 svn_boolean_t *had_props,
310 svn_wc__db_wcroot_t *wcroot,
311 const char *local_relpath,
313 apr_pool_t *result_pool,
314 apr_pool_t *scratch_pool);
317 svn_wc__db_scan_addition_internal(
318 svn_wc__db_status_t *status,
319 const char **op_root_relpath_p,
320 const char **repos_relpath,
321 apr_int64_t *repos_id,
322 const char **original_repos_relpath,
323 apr_int64_t *original_repos_id,
324 svn_revnum_t *original_revision,
325 svn_wc__db_wcroot_t *wcroot,
326 const char *local_relpath,
327 apr_pool_t *result_pool,
328 apr_pool_t *scratch_pool);
331 svn_wc__db_scan_deletion_internal(
332 const char **base_del_relpath,
333 const char **moved_to_relpath,
334 const char **work_del_relpath,
335 const char **moved_to_op_root_relpath,
336 svn_wc__db_wcroot_t *wcroot,
337 const char *local_relpath,
338 apr_pool_t *result_pool,
339 apr_pool_t *scratch_pool);
342 /* Look up REPOS_ID in WCROOT->SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID
343 to its root URL and UUID respectively. If REPOS_ID is INVALID_REPOS_ID,
344 use NULL for both URL and UUID. Either or both output parameters may be
345 NULL if not wanted. */
347 svn_wc__db_fetch_repos_info(const char **repos_root_url,
348 const char **repos_uuid,
349 svn_wc__db_wcroot_t *wcroot,
350 apr_int64_t repos_id,
351 apr_pool_t *result_pool);
353 /* Like svn_wc__db_read_conflict(), but with WCROOT+LOCAL_RELPATH instead of
354 DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */
356 svn_wc__db_read_conflict_internal(svn_skel_t **conflict,
357 svn_node_kind_t *kind,
359 svn_wc__db_wcroot_t *wcroot,
360 const char *local_relpath,
361 apr_pool_t *result_pool,
362 apr_pool_t *scratch_pool);
364 /* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of
367 svn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot,
368 const char *local_relpath,
369 const svn_skel_t *conflict_skel,
370 apr_pool_t *scratch_pool);
373 /* Transaction handling */
375 /* Evaluate the expression EXPR within a transaction.
377 * Begin a transaction in WCROOT's DB; evaluate the expression EXPR, which would
378 * typically be a function call that does some work in DB; finally commit
379 * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
382 #define SVN_WC__DB_WITH_TXN(expr, wcroot) \
383 SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb)
386 /* Evaluate the expressions EXPR1..EXPR4 within a transaction, returning the
387 * first error if an error occurs.
389 * Begin a transaction in WCROOT's DB; evaluate the expressions, which would
390 * typically be function calls that do some work in DB; finally commit
391 * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
394 #define SVN_WC__DB_WITH_TXN4(expr1, expr2, expr3, expr4, wcroot) \
395 SVN_SQLITE__WITH_LOCK4(expr1, expr2, expr3, expr4, (wcroot)->sdb)
397 /* Update the single op-depth layer in the move destination subtree
398 rooted at DST_RELPATH to make it match the move source subtree
399 rooted at SRC_RELPATH. */
401 svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
402 const char *src_op_relpath,
404 const char *dst_op_relpath,
405 svn_skel_t *conflict,
406 svn_skel_t *work_items,
407 apr_pool_t *scratch_pool);
409 /* Like svn_wc__db_op_make_copy but with wcroot, local_relpath */
411 svn_wc__db_op_make_copy_internal(svn_wc__db_wcroot_t *wcroot,
412 const char *local_relpath,
413 svn_boolean_t move_move_info,
414 const svn_skel_t *conflicts,
415 const svn_skel_t *work_items,
416 apr_pool_t *scratch_pool);
419 /* Extract the moved-to information for LOCAL_RELPATH as it existed
420 at OP-DEPTH. The output paths are optional and set to NULL
421 if there is no move, otherwise:
423 *MOVE_SRC_RELPATH: the path that was moved (LOCAL_RELPATH or one
426 *MOVE_DST_RELPATH: The path *MOVE_SRC_RELPATH was moved to.
428 *DELETE_RELPATH: The path at which LOCAL_RELPATH was removed (
429 *MOVE_SRC_RELPATH or one of its ancestors)
431 Given a path A/B/C with A/B moved to X and A deleted then for A/B/C:
433 MOVE_SRC_RELPATH is A/B
434 MOVE_DST_RELPATH is X
437 X/C can be calculated if necessesary, like with the other
440 This function returns SVN_ERR_WC_PATH_NOT_FOUND if LOCAL_RELPATH didn't
441 exist at OP_DEPTH, or when it is not shadowed.
443 ### Think about combining with scan_deletion? Also with
444 ### scan_addition to get moved-to for replaces? Do we need to
445 ### return the op-root of the move source, i.e. A/B in the example
448 svn_wc__db_scan_moved_to_internal(const char **move_src_relpath,
449 const char **move_dst_relpath,
450 const char **delete_relpath,
451 svn_wc__db_wcroot_t *wcroot,
452 const char *local_relpath,
454 apr_pool_t *result_pool,
455 apr_pool_t *scratch_pool);
457 /* Like svn_wc__db_op_set_props, but updates ACTUAL_NODE directly without
458 comparing with the pristine properties, etc.
461 svn_wc__db_op_set_props_internal(svn_wc__db_wcroot_t *wcroot,
462 const char *local_relpath,
464 svn_boolean_t clear_recorded_info,
465 apr_pool_t *scratch_pool);
468 svn_wc__db_read_props_internal(apr_hash_t **props,
469 svn_wc__db_wcroot_t *wcroot,
470 const char *local_relpath,
471 apr_pool_t *result_pool,
472 apr_pool_t *scratch_pool);
474 /* Like svn_wc__db_wclock_owns_lock() but taking WCROOT+LOCAL_RELPATH instead
475 of DB+LOCAL_ABSPATH. */
477 svn_wc__db_wclock_owns_lock_internal(svn_boolean_t *own_lock,
478 svn_wc__db_wcroot_t *wcroot,
479 const char *local_relpath,
481 apr_pool_t *scratch_pool);
483 /* Do a post-drive revision bump for the moved-away destination for
484 any move sources under LOCAL_RELPATH. This is called from within
485 the revision bump transaction after the tree at LOCAL_RELPATH has
488 svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot,
489 const char *local_relpath,
492 apr_pool_t *scratch_pool);
494 /* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making
495 the destination DST_RELPATH a normal copy. SRC_OP_DEPTH is the op-depth
496 where the move_to information is stored */
498 svn_wc__db_op_break_move_internal(svn_wc__db_wcroot_t *wcroot,
499 const char *src_relpath,
501 const char *dst_relpath,
502 const svn_skel_t *work_items,
503 apr_pool_t *scratch_pool);
506 svn_wc__db_op_mark_resolved_internal(svn_wc__db_wcroot_t *wcroot,
507 const char *local_relpath,
509 svn_boolean_t resolved_text,
510 svn_boolean_t resolved_props,
511 svn_boolean_t resolved_tree,
512 const svn_skel_t *work_items,
513 apr_pool_t *scratch_pool);
515 /* op_depth is the depth at which the node is added. */
517 svn_wc__db_op_raise_moved_away_internal(
518 svn_wc__db_wcroot_t *wcroot,
519 const char *local_relpath,
522 svn_wc_operation_t operation,
523 svn_wc_conflict_action_t action,
524 const svn_wc_conflict_version_t *old_version,
525 const svn_wc_conflict_version_t *new_version,
526 apr_pool_t *scratch_pool);
529 svn_wc__db_update_move_list_notify(svn_wc__db_wcroot_t *wcroot,
530 svn_revnum_t old_revision,
531 svn_revnum_t new_revision,
532 svn_wc_notify_func2_t notify_func,
534 apr_pool_t *scratch_pool);
537 svn_wc__db_verify_db_full_internal(svn_wc__db_wcroot_t *wcroot,
538 svn_wc__db_verify_cb_t callback,
540 apr_pool_t *scratch_pool);
542 #endif /* WC_DB_PRIVATE_H */