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
36 struct 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 */
69 typedef 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 */
83 typedef 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 /* */
110 svn_error_t *
111 svn_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. */
118 svn_error_t *
119 svn_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 */
140 svn_error_t *
141 svn_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 "" */
168 APR_INLINE static int
relpath_depth(const char * relpath)169 relpath_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 /* */
187 svn_error_t *
188 svn_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. */
202 svn_error_t *
203 svn_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. */
214 svn_error_t *
215 svn_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. */
247 svn_error_t *
248 svn_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 */
282 svn_error_t *
283 svn_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. */
306 svn_error_t *
307 svn_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. */
315 svn_error_t *
316 svn_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. */
324 svn_error_t *
325 svn_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. */
334 typedef 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. */
343 svn_error_t *
344 svn_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. */
363 svn_error_t *
364 svn_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 */
410 svn_error_t *
411 svn_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
417 svn_error_t *
418 svn_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
423 svn_error_t *
424 svn_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. */
438 svn_error_t *
439 svn_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 */
447 svn_error_t *
448 svn_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
453 svn_error_t *
454 svn_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