Main Page | Modules | Data Structures | File List | Data Fields | Globals

svn_repos.h

Go to the documentation of this file.
00001 /**
00002  * @copyright
00003  * ====================================================================
00004  * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
00005  *
00006  * This software is licensed as described in the file COPYING, which
00007  * you should have received as part of this distribution.  The terms
00008  * are also available at http://subversion.tigris.org/license-1.html.
00009  * If newer versions of this license are posted there, you may use a
00010  * newer version instead, at your option.
00011  *
00012  * This software consists of voluntary contributions made by many
00013  * individuals.  For exact contribution history, see the revision
00014  * history and logs, available at http://subversion.tigris.org/.
00015  * ====================================================================
00016  * @endcopyright
00017  *
00018  * @file svn_repos.h
00019  * @brief tools built on top of the filesystem.
00020  */
00021 
00022 
00023 #ifndef SVN_REPOS_H
00024 #define SVN_REPOS_H
00025 
00026 #include <apr_pools.h>
00027 #include <apr_hash.h>
00028 #include "svn_fs.h"
00029 #include "svn_delta.h"
00030 #include "svn_types.h"
00031 #include "svn_error.h"
00032 
00033 
00034 #ifdef __cplusplus
00035 extern "C" {
00036 #endif /* __cplusplus */
00037 
00038 /* ---------------------------------------------------------------*/
00039 
00040 
00041 /** Callback type for checking authorization on paths produced by (at
00042  * least) svn_repos_dir_delta().
00043  *
00044  * Set @a *allowed to TRUE to indicate that some operation is
00045  * authorized for @a path in @a root, or set it to FALSE to indicate
00046  * unauthorized (presumably according to state stored in @a baton).
00047  * 
00048  * Do not assume @a pool has any lifetime beyond this call.
00049  *
00050  * The exact operation being authorized depends on the callback
00051  * implementation.  For read authorization, for example, the caller
00052  * would implement an instance that does read checking, and pass it as
00053  * a parameter named [perhaps] 'authz_read_func'.  The receiver of
00054  * that parameter might also take another parameter named
00055  * 'authz_write_func', which although sharing this type, would be a
00056  * different implementation.
00057  *
00058  * Note: If someday we want more sophisticated authorization states
00059  * than just yes/no, @a allowed can become an enum type.
00060  */
00061 typedef svn_error_t *(*svn_repos_authz_func_t) (svn_boolean_t *allowed,
00062                                                 svn_fs_root_t *root,
00063                                                 const char *path,
00064                                                 void *baton,
00065                                                 apr_pool_t *pool);
00066 
00067 
00068 
00069 /** The repository object. */
00070 typedef struct svn_repos_t svn_repos_t;
00071 
00072 /* Opening and creating repositories. */
00073 
00074 
00075 /** Find the root path of the repository that contains @a path.
00076  *
00077  * If a repository was found, the path to the root of the repository
00078  * is returned, else @c NULL. The pointer to the returned path may be
00079  * equal to @a path argument.
00080  */
00081 const char *svn_repos_find_root_path (const char *path,
00082                                       apr_pool_t *pool);
00083 
00084 /** Set @a *repos_p to a repository object for the repository at @a path.
00085  *
00086  * Allocate @a *repos_p in @a pool.
00087  *
00088  * Acquires a shared lock on the repository, and attaches a cleanup
00089  * function to @a pool to remove the lock.  If no lock can be acquired,
00090  * returns error, with undefined effect on @a *repos_p.  If an exclusive
00091  * lock is present, this blocks until it's gone.
00092  */
00093 svn_error_t *svn_repos_open (svn_repos_t **repos_p,
00094                              const char *path,
00095                              apr_pool_t *pool);
00096 
00097 /** Create a new Subversion repository at @a path, building the necessary
00098  * directory structure, creating the Berkeley DB filesystem environment, 
00099  * and so on.  Return the (open) repository object in @a *repos_p,
00100  * allocated in @a pool.
00101  *
00102  * @a config is a client configuration hash of @c svn_config_t * items
00103  * keyed on config category names, and may be NULL.
00104  *
00105  * @a fs_config is passed to the filesystem, and may be NULL.
00106  *
00107  * @a unused_1 and @a unused_2 are not used and should be NULL.
00108  */
00109 svn_error_t *svn_repos_create (svn_repos_t **repos_p, 
00110                                const char *path,
00111                                const char *unused_1,
00112                                const char *unused_2,
00113                                apr_hash_t *config,
00114                                apr_hash_t *fs_config,
00115                                apr_pool_t *pool);
00116 
00117 /** Destroy the Subversion repository found at @a path, using @a pool for any
00118  * necessary allocations.
00119  */
00120 svn_error_t *svn_repos_delete (const char *path, apr_pool_t *pool);
00121 
00122 /** Return the filesystem associated with repository object @a repos. */
00123 svn_fs_t *svn_repos_fs (svn_repos_t *repos);
00124 
00125 
00126 /** Make a hot copy of the Subversion repository found at @a src_path 
00127  * to @a dst_path. 
00128  *
00129  * @copydoc svn_fs_hotcopy_berkeley()
00130  */
00131 svn_error_t * svn_repos_hotcopy (const char *src_path,
00132                                  const char *dst_path,
00133                                  svn_boolean_t clean_logs,
00134                                  apr_pool_t *pool);
00135 
00136 /** Run database recovery procedures on the repository at @a path,
00137  * returning the database to a consistent state.  Use @a pool for all
00138  * allocation.
00139  *
00140  * Acquires an @a exclusive lock on the repository, recovers the
00141  * database, and releases the lock.  If an exclusive lock can't be
00142  * acquired, returns error.
00143  */
00144 svn_error_t *svn_repos_recover (const char *path, apr_pool_t *pool);
00145 
00146 
00147 /** This function is a wrapper around svn_fs_berkeley_logfiles(),
00148  * returning log file paths relative to the root of the repository.
00149  *
00150  * @copydoc svn_fs_berkeley_logfiles()
00151  */
00152 svn_error_t *svn_repos_db_logfiles (apr_array_header_t **logfiles,
00153                                     const char *path,
00154                                     svn_boolean_t only_unused,
00155                                     apr_pool_t *pool);
00156 
00157 
00158 
00159 /* Repository Paths */
00160 
00161 /** Return the top-level repository path allocated in @a pool. */
00162 const char *svn_repos_path (svn_repos_t *repos, apr_pool_t *pool);
00163 
00164 /** Return the path to @a repos's Berkeley DB environment, allocated in
00165  * @a pool.
00166  */
00167 const char *svn_repos_db_env (svn_repos_t *repos, apr_pool_t *pool);
00168 
00169 /** Return path to @a repos's config directory, allocated in @a pool. */
00170 const char *svn_repos_conf_dir (svn_repos_t *repos, apr_pool_t *pool);
00171 
00172 /** Return path to @a repos's svnserve.conf, allocated in @a pool. */
00173 const char *svn_repos_svnserve_conf (svn_repos_t *repos, apr_pool_t *pool);
00174 
00175 /** Return path to @a repos's lock directory, allocated in @a pool. */
00176 const char *svn_repos_lock_dir (svn_repos_t *repos, apr_pool_t *pool);
00177 
00178 /** Return path to @a repos's db lockfile, allocated in @a pool. */
00179 const char *svn_repos_db_lockfile (svn_repos_t *repos, apr_pool_t *pool);
00180 
00181 /** Return path to @a repos's db logs lockfile, allocated in @a pool. */
00182 const char *svn_repos_db_logs_lockfile (svn_repos_t *repos, apr_pool_t *pool);
00183 
00184 /** Return the path to @a repos's hook directory, allocated in @a pool. */
00185 const char *svn_repos_hook_dir (svn_repos_t *repos, apr_pool_t *pool);
00186 
00187 /** Return the path to @a repos's start-commit hook, allocated in @a pool. */
00188 const char *svn_repos_start_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00189 
00190 /** Return the path to @a repos's pre-commit hook, allocated in @a pool. */
00191 const char *svn_repos_pre_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00192 
00193 /** Return the path to @a repos's post-commit hook, allocated in @a pool. */
00194 const char *svn_repos_post_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00195 
00196 /** Return the path to @a repos's pre-revprop-change hook, allocated in 
00197  * @a pool.
00198  */
00199 const char *svn_repos_pre_revprop_change_hook (svn_repos_t *repos,
00200                                                apr_pool_t *pool);
00201 
00202 /** Return the path to @a repos's post-revprop-change hook, allocated in 
00203  * @a pool.
00204  */
00205 const char *svn_repos_post_revprop_change_hook (svn_repos_t *repos,
00206                                                 apr_pool_t *pool);
00207 
00208 
00209 
00210 /* ---------------------------------------------------------------*/
00211 
00212 /* Reporting the state of a working copy, for updates. */
00213 
00214 
00215 /** Construct and return a @a report_baton that will be paired with some
00216  * @c svn_ra_reporter_t table.  The table and baton are used to build a
00217  * transaction in the system;  when the report is finished,
00218  * @c svn_repos_dir_delta is called on the transaction, driving
00219  * @a editor/@a edit_baton. 
00220  *
00221  * Specifically, the report will create a transaction made by @a username, 
00222  * relative to @a fs_base in the filesystem.  @a target is a single path 
00223  * component, used to limit the scope of the report to a single entry of 
00224  * @a fs_base, or "" if all of @a fs_base itself is the main subject of
00225  * the report.
00226  *
00227  * @a tgt_path and @a revnum is the fs path/revision pair that is the
00228  * "target" of @c dir_delta.  In other words, a tree delta will be
00229  * returned that transforms the transaction into @a tgt_path/@a revnum.
00230  * @a tgt_path may (indeed, should) be @c NULL when the source and target
00231  * paths of the report are the same.  That is, @a tgt_path should *only*
00232  * be specified when specifying that the resultant editor drive be one
00233  * that transforms the reported hierarchy into a pristine tree of
00234  * @a tgt_path at revision @a revnum.  Else, a @c NULL value for @a tgt_path 
00235  * will indicate that the editor should be driven in such a way as to
00236  * transform the reported hierarchy to revision @a revnum, preserving the
00237  * reported hierarchy.
00238  *
00239  * @a text_deltas instructs the driver of the @a editor to enable
00240  * the generation of text deltas.
00241  *
00242  * @a recurse instructs the driver of the @a editor to send a recursive
00243  * delta (or not.)
00244  *
00245  * @a ignore_ancestry instructs the driver to ignore node ancestry
00246  * when determining how to transmit differences.
00247  *
00248  * The @a authz_read_func and @a authz_read_baton are passed along to
00249  * @c svn_repos_dir_delta(); see that function for how they are used.
00250  *
00251  * All allocation for the context and collected state will occur in
00252  * @a pool.
00253  */
00254 svn_error_t *
00255 svn_repos_begin_report (void **report_baton,
00256                         svn_revnum_t revnum,
00257                         const char *username,
00258                         svn_repos_t *repos,
00259                         const char *fs_base,
00260                         const char *target,
00261                         const char *tgt_path,
00262                         svn_boolean_t text_deltas,
00263                         svn_boolean_t recurse,
00264                         svn_boolean_t ignore_ancestry,
00265                         const svn_delta_editor_t *editor,
00266                         void *edit_baton,
00267                         svn_repos_authz_func_t authz_read_func,
00268                         void *authz_read_baton,
00269                         apr_pool_t *pool);
00270 
00271 
00272 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), this
00273  * routine will build @a revision:@a path into the current transaction.
00274  * This routine is called multiple times to create a transaction that
00275  * is a "mirror" of a working copy.
00276  *
00277  * The first call of this in a given report usually passes an empty
00278  * @a path; that allows the reporter to set up the correct root revision
00279  * (useful when creating a txn, for example).
00280  *
00281  * If @a start_empty is set and @a path is a directory, then remove
00282  * all children and props of the freshly-linked directory.  This is
00283  * for 'low confidence' client reporting.
00284  * 
00285  * All temporary allocations are done in @a pool.
00286  */
00287 svn_error_t *svn_repos_set_path (void *report_baton,
00288                                  const char *path,
00289                                  svn_revnum_t revision,
00290                                  svn_boolean_t start_empty,
00291                                  apr_pool_t *pool);
00292 
00293 
00294 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), 
00295  * this routine will build @a revision:@a link_path into the current 
00296  * transaction at @a path.  Note that while @a path is relative to the 
00297  * anchor/target used in the creation of the @a report_baton, @a link_path 
00298  * is an absolute filesystem path!
00299  *
00300  * If @a start_empty is set and @a path is a directory, then remove
00301  * all children and props of the freshly-linked directory.  This is
00302  * for 'low confidence' client reporting.
00303  *
00304  * All temporary allocations are done in @a pool.
00305  */
00306 svn_error_t *svn_repos_link_path (void *report_baton,
00307                                   const char *path,
00308                                   const char *link_path,
00309                                   svn_revnum_t revision,
00310                                   svn_boolean_t start_empty,
00311                                   apr_pool_t *pool);
00312 
00313 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), 
00314  * this routine will remove @a path from the current fs transaction. 
00315  *
00316  * (This allows the reporter's driver to describe missing pieces of a
00317  * working copy, so that 'svn up' can recreate them.)
00318  *
00319  * All temporary allocations are done in @a pool.
00320  */
00321 svn_error_t *svn_repos_delete_path (void *report_baton,
00322                                     const char *path,
00323                                     apr_pool_t *pool);
00324 
00325 /** Make the filesystem compare the transaction to a revision and have
00326  * it drive an update editor (using @c svn_repos_delta_dirs()), then
00327  * abort the transaction.  If an error occurs during the driving of
00328  * the editor, we do NOT abort the edit; that responsibility belongs
00329  * to the caller, if it happens at all.  The fs transaction will be
00330  * aborted even if the editor drive fails, so the caller does not need
00331  * to clean up.
00332  */
00333 svn_error_t *svn_repos_finish_report (void *report_baton,
00334                                       apr_pool_t *pool);
00335 
00336 
00337 /** The report-driver is bailing, so abort the fs transaction.  This
00338  * function can be called anytime before @c svn_repos_finish_report() is
00339  * called.  No other reporting functions should be called after calling
00340  * this function.
00341  */
00342 svn_error_t *svn_repos_abort_report (void *report_baton,
00343                                      apr_pool_t *pool);
00344 
00345 
00346 /* ---------------------------------------------------------------*/
00347 
00348 /* The magical dir_delta update routines. */
00349 
00350 /** Use the provided @a editor and @a edit_baton to describe the changes
00351  * necessary for making a given node (and its descendants, if it is a
00352  * directory) under @a src_root look exactly like @a tgt_path under
00353  * @a tgt_root.  @a src_entry is the node to update.  If @a src_entry
00354  * is empty, then compute the difference between the entire tree
00355  * anchored at @a src_parent_dir under @a src_root and @a tgt_path
00356  * under @a target_root.  Else, describe the changes needed to update
00357  * only that entry in @a src_parent_dir.  Typically, callers of this
00358  * function will use a @a tgt_path that is the concatenation of @a
00359  * src_parent_dir and @a src_entry.
00360  *
00361  * @a src_root and @a tgt_root can both be either revision or transaction
00362  * roots.  If @a tgt_root is a revision, @a editor's @c set_target_revision()
00363  * will be called with the @a tgt_root's revision number, else it will
00364  * not be called at all.
00365  *
00366  * If @a authz_read_func is non-null, invoke it before any call to
00367  *
00368  *    @a editor->open_root
00369  *    @a editor->add_directory
00370  *    @a editor->open_directory
00371  *    @a editor->add_file
00372  *    @a editor->open_file
00373  *
00374  * passing @a tgt_root, the same path that would be passed to the
00375  * editor function in question, and @a authz_read_baton.  If the
00376  * @a *allowed parameter comes back TRUE, then proceed with the planned
00377  * editor call; else if FALSE, then invoke @a editor->absent_file or
00378  * @a editor->absent_directory as appropriate, except if the planned
00379  * editor call was open_root, throw SVN_ERR_AUTHZ_ROOT_UNREADABLE.
00380  *
00381  * If @a text_deltas is @c FALSE, send a single @c NULL txdelta window to 
00382  * the window handler returned by @a editor->apply_textdelta().
00383  *
00384  * If @a entry_props is @c TRUE, accompany each opened/added entry with
00385  * propchange editor calls that relay special "entry props" (this
00386  * is typically used only for working copy updates).
00387  *
00388  * @a ignore_ancestry instructs the function to ignore node ancestry
00389  * when determining how to transmit differences.
00390  *
00391  * Before completing successfully, this function calls @a editor's
00392  * @c close_edit(), so the caller should expect its @a edit_baton to be
00393  * invalid after its use with this function.
00394  *
00395  * Do any allocation necessary for the delta computation in @a pool.
00396  * This function's maximum memory consumption is at most roughly
00397  * proportional to the greatest depth of the tree under @a tgt_root, not
00398  * the total size of the delta.
00399  */
00400 svn_error_t *
00401 svn_repos_dir_delta (svn_fs_root_t *src_root,
00402                      const char *src_parent_dir,
00403                      const char *src_entry,
00404                      svn_fs_root_t *tgt_root,
00405                      const char *tgt_path,
00406                      const svn_delta_editor_t *editor,
00407                      void *edit_baton,
00408                      svn_repos_authz_func_t authz_read_func,
00409                      void *authz_read_baton,
00410                      svn_boolean_t text_deltas,
00411                      svn_boolean_t recurse,
00412                      svn_boolean_t entry_props,
00413                      svn_boolean_t ignore_ancestry,
00414                      apr_pool_t *pool);
00415 
00416 /** Use the provided @a editor and @a edit_baton to describe the
00417  * skeletal changes made in a particular filesystem @a root
00418  * (revision or transaction).
00419  *
00420  * The @a editor passed to this function should be aware of the fact
00421  * that calls to its change_dir_prop(), change_file_prop(), and
00422  * apply_textdelta() functions will not contain meaningful data, and
00423  * merely serve as indications that properties or textual contents
00424  * were changed. 
00425  *
00426  * NOTE: this editor driver passes SVN_INVALID_REVNUM for all
00427  * revision parameters in the editor interface except the copyfrom
00428  * parameter of the add_file() and add_directory() editor functions.
00429  *
00430  * ### TODO: This ought to take an svn_repos_authz_func_t too.
00431  * The only reason it doesn't yet is the difficulty of implementing
00432  * that correctly, plus lack of strong present need -- it's currently
00433  * only used in creating a DAV MERGE response, in 'svnadmin dump', and
00434  * in svnlook.
00435  */
00436 svn_error_t *
00437 svn_repos_replay (svn_fs_root_t *root,
00438                   const svn_delta_editor_t *editor,
00439                   void *edit_baton,
00440                   apr_pool_t *pool);
00441 
00442 
00443 /* ---------------------------------------------------------------*/
00444 
00445 /* Making commits. */
00446 
00447 /** Return an @a editor and @a edit_baton to commit changes to @a session->fs,
00448  * beginning at location 'rev:@a base_path', where "rev" is the argument
00449  * given to @c open_root().  Store @a user as the author of the commit and
00450  * @a log_msg as the commit message.
00451  *
00452  * @a repos is a previously opened repository.  @a repos_url is the decoded
00453  * URL to the base of the repository, and is used to check copyfrom paths.
00454  *
00455  * Calling @a (*editor)->close_edit completes the commit.  Before
00456  * @c close_edit returns, but after the commit has succeeded, it will
00457  * invoke @a callback with the new revision number, the commit date (as a
00458  * <tt>const char *</tt>), commit author (as a <tt>const char *</tt>), and
00459  * @a callback_baton as arguments.  If @a callback returns an error, that
00460  * error will be returned from @c close_edit, otherwise if there was a
00461  * post-commit hook failure, then that error will be returned and will
00462  * have code SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED.
00463  */
00464 svn_error_t *svn_repos_get_commit_editor (const svn_delta_editor_t **editor,
00465                                           void **edit_baton,
00466                                           svn_repos_t *repos,
00467                                           const char *repos_url,
00468                                           const char *base_path,
00469                                           const char *user,
00470                                           const char *log_msg,
00471                                           svn_commit_callback_t callback,
00472                                           void *callback_baton,
00473                                           apr_pool_t *pool);
00474 
00475 
00476 /* ---------------------------------------------------------------*/
00477 
00478 /* Finding particular revisions. */
00479 
00480 /** Set @a *revision to the revision number in @a repos's filesystem that was
00481  * youngest at time @a tm.
00482  */
00483 svn_error_t *
00484 svn_repos_dated_revision (svn_revnum_t *revision,
00485                           svn_repos_t *repos,
00486                           apr_time_t tm,
00487                           apr_pool_t *pool);
00488                           
00489 
00490 /** Given a @a root/@a path within some filesystem, return three pieces of
00491  * information allocated in @a pool:
00492  *
00493  *    - set @a *committed_rev to the revision in which the object was
00494  *      last modified.  (In fs parlance, this is the revision in which
00495  *      the particular node-rev-id was 'created'.)
00496  *  
00497  *    - set @a *committed_date to the date of said revision, or @c NULL
00498  *      if not available.
00499  *
00500  *    - set @a *last_author to the author of said revision, or @c NULL
00501  *      if not available.
00502  */
00503 svn_error_t *
00504 svn_repos_get_committed_info (svn_revnum_t *committed_rev,
00505                               const char **committed_date,
00506                               const char **last_author,
00507                               svn_fs_root_t *root,
00508                               const char *path,
00509                               apr_pool_t *pool);
00510 
00511 
00512 /** Callback type for use with svn_repos_history().  @a path and @a
00513  * revision represent interesting history locations in the lifetime
00514  * of the path passed to svn_repos_history().  @a baton is the same
00515  * baton given to svn_repos_history().  @a pool is provided for the
00516  * convenience of the implementor, who should not expect it to live
00517  * longer than a single callback call.
00518  */
00519 typedef svn_error_t *(*svn_repos_history_func_t) (void *baton,
00520                                                   const char *path,
00521                                                   svn_revnum_t revision,
00522                                                   apr_pool_t *pool);
00523 
00524 /** Call @a history_func (with @a history_baton) for each interesting
00525  * history location in the lifetime of @a path in @a fs, from the
00526  * youngest of @a end and @ start to the oldest.  Only cross
00527  * filesystem copy history if @a cross_copies is @c TRUE.  And do all
00528  * of this in @a pool.
00529  */
00530 svn_error_t *
00531 svn_repos_history (svn_fs_t *fs,
00532                    const char *path,
00533                    svn_repos_history_func_t history_func,
00534                    void *history_baton,
00535                    svn_revnum_t start,
00536                    svn_revnum_t end,
00537                    svn_boolean_t cross_copies,
00538                    apr_pool_t *pool);
00539 
00540 /* ### other queries we can do someday --
00541 
00542      * fetch the last revision created by <user>
00543          (once usernames become revision properties!)
00544      * fetch the last revision where <path> was modified
00545      
00546 */
00547 
00548 
00549 
00550 /* ---------------------------------------------------------------*/
00551 
00552 /* Retrieving log messages. */
00553 
00554 
00555 /** Invoke @a receiver with @a receiver_baton on each log message from 
00556  * @a start to @a end in @a repos's filesystem.  @a start may be greater 
00557  * or less than @a end; this just controls whether the log messages are 
00558  * processed in descending or ascending revision number order.
00559  *
00560  * If @a start or @a end is @c SVN_INVALID_REVNUM, it defaults to youngest.
00561  *
00562  * If @a paths is non-null and has one or more elements, then only show
00563  * revisions in which at least one of @a paths was changed (i.e., if
00564  * file, text or props changed; if dir, props changed or an entry was
00565  * added or deleted).  Each path is an <tt>const char *</tt> representing 
00566  * an absolute path in the repository.
00567  *
00568  * ### todo: need to consider whether the above directory behavior is
00569  * most useful, or if we should actually treat _any_ node change in a
00570  * directory as a visible change for purposes of log... i.e., show
00571  * bubble-up.  The reason this might be useful is so that running log
00572  * on a directory would give a msg for every change under that dir,
00573  * no matter how far down.  See the thread started on the dev list by
00574  * Lars Kellogg-Stedman <lars@larsshack.org> with the subject
00575  * "Single repository, multiple projects?" for more.  We may simple
00576  * need to offer a few different semantics for @a paths.
00577  *
00578  * If @a discover_changed_paths, then each call to @a receiver passes a
00579  * <tt>const apr_hash_t *</tt> for the receiver's @a changed_paths 
00580  * argument; the hash's keys are all the paths committed in that revision.
00581  * Otherwise, each call to @a receiver passes null for @a changed_paths.
00582  *
00583  * If @a strict_node_history is set, copy history (if any exists) will
00584  * not be traversed while harvesting revision logs for each path.
00585  *
00586  * If any invocation of @a receiver returns error, return that error
00587  * immediately and without wrapping it.
00588  *
00589  * If @a start or @a end is a non-existent revision, return the error
00590  * @c SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a receiver.
00591  *
00592  * See also the documentation for @c svn_log_message_receiver_t.
00593  *
00594  * Use @a pool for temporary allocations.
00595  */
00596 svn_error_t *
00597 svn_repos_get_logs (svn_repos_t *repos,
00598                     const apr_array_header_t *paths,
00599                     svn_revnum_t start,
00600                     svn_revnum_t end,
00601                     svn_boolean_t discover_changed_paths,
00602                     svn_boolean_t strict_node_history,
00603                     svn_log_message_receiver_t receiver,
00604                     void *receiver_baton,
00605                     apr_pool_t *pool);
00606 
00607 
00608 /* ---------------------------------------------------------------*/
00609 
00610 /**
00611  * @defgroup svn_repos_hook_wrappers Hook-sensitive wrappers for libsvn_fs 
00612  * routines.
00613  * @{
00614  */
00615 
00616 /** Like @c svn_fs_commit_txn(), but invoke the @a repos's pre- and
00617  * post-commit hooks around the commit.  Use @a pool for any necessary
00618  * allocations.
00619  *
00620  * If the pre-commit hook or svn_fs_commit_txn() fails, throw the
00621  * original error to caller.  If an error occurs when running the
00622  * post-commit hook, return the original error wrapped with
00623  * SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED.  If the caller sees this
00624  * error, it knows that the commit succeeded anyway.
00625  *
00626  * @a conflict_p, @a new_rev, and @a txn are as in @c svn_fs_commit_txn().
00627  */
00628 svn_error_t *svn_repos_fs_commit_txn (const char **conflict_p,
00629                                       svn_repos_t *repos,
00630                                       svn_revnum_t *new_rev,
00631                                       svn_fs_txn_t *txn,
00632                                       apr_pool_t *pool);
00633 
00634 /** Like @c svn_fs_begin_txn(), but use @a author and @a log_msg to set the
00635  * corresponding properties on transaction @a *txn_p.  @a repos is the
00636  * repository object which contains the filesystem.  @a rev, @a *txn_p, and
00637  * @a pool are as in @c svn_fs_begin_txn().
00638  *
00639  * Before a txn is created, the repository's start-commit hooks are
00640  * run; if any of them fail, no txn is created, @a *txn_p is unaffected, 
00641  * and @c SVN_ERR_REPOS_HOOK_FAILURE is returned.
00642  *
00643  * @a log_msg may be @c NULL to indicate the message is not (yet) available.
00644  * The caller will need to attach it to the transaction at a later time.
00645  */
00646 svn_error_t *svn_repos_fs_begin_txn_for_commit (svn_fs_txn_t **txn_p,
00647                                                 svn_repos_t *repos,
00648                                                 svn_revnum_t rev,
00649                                                 const char *author,
00650                                                 const char *log_msg,
00651                                                 apr_pool_t *pool);
00652 
00653 
00654 /** Like @c svn_fs_begin_txn(), but use @a author to set the corresponding
00655  * property on transaction @a *txn_p.  @a repos is the repository object
00656  * which contains the filesystem.  @a rev, @a *txn_p, and @a pool are as in
00657  * @c svn_fs_begin_txn().
00658  *
00659  * ### Someday: before a txn is created, some kind of read-hook could
00660  *              be called here.
00661  */
00662 svn_error_t *svn_repos_fs_begin_txn_for_update (svn_fs_txn_t **txn_p,
00663                                                 svn_repos_t *repos,
00664                                                 svn_revnum_t rev,
00665                                                 const char *author,
00666                                                 apr_pool_t *pool);
00667 
00668 
00669 /** Like @c svn_fs_change_rev_prop(), but invoke the @a repos's pre- and
00670  * post-revprop-change hooks around the change.  Use @a pool for
00671  * temporary allocations.
00672  *
00673  * @a rev is the revision whose property to change, @a name is the
00674  * name of the property, and @a new_value is the new value of the
00675  * property.   @a author is the authenticated username of the person
00676  * changing the property value, or null if not available.
00677  */
00678 svn_error_t *svn_repos_fs_change_rev_prop (svn_repos_t *repos,
00679                                            svn_revnum_t rev,
00680                                            const char *author,
00681                                            const char *name,
00682                                            const svn_string_t *new_value,
00683                                            apr_pool_t *pool);
00684 
00685 
00686 /* ---------------------------------------------------------------*/
00687 
00688 /* Prop-changing wrappers for libsvn_fs routines. */
00689 
00690 /* NOTE: svn_repos_fs_change_rev_prop() also exists, but is located
00691    above with the hook-related functions. */
00692 
00693 
00694 /** Validating wrapper for @c svn_fs_change_node_prop() (which see for
00695  * argument descriptions).
00696  */
00697 svn_error_t *svn_repos_fs_change_node_prop (svn_fs_root_t *root,
00698                                             const char *path,
00699                                             const char *name,
00700                                             const svn_string_t *value,
00701                                             apr_pool_t *pool);
00702 
00703 /** Validating wrapper for @c svn_fs_change_txn_prop() (which see for
00704  * argument descriptions).
00705  */
00706 svn_error_t *svn_repos_fs_change_txn_prop (svn_fs_txn_t *txn,
00707                                            const char *name,
00708                                            const svn_string_t *value,
00709                                            apr_pool_t *pool);
00710 
00711 /** @} */
00712 
00713 /* ---------------------------------------------------------------*/
00714 
00715 /**
00716  * @defgroup svn_repos_inspection Data structures and editor things for 
00717  * repository inspection.
00718  * @{
00719  *
00720  * As it turns out, the @c svn_repos_dir_delta() interface can be
00721  * extremely useful for examining the repository, or more exactly,
00722  * changes to the repository.  @c svn_repos_dir_delta() allows for
00723  * differences between two trees to be described using an editor.
00724  *
00725  * By using the specific editor found below in conjunction with
00726  * @c svn_repos_dir_delta(), the description of how to transform one tree
00727  * into another can be used to build an in-memory linked-list tree,
00728  * which each node representing a repository node that was changed as a
00729  * result of having @c svn_repos_dir_delta() drive that editor.
00730  */
00731 
00732 /** A node in the repository. */
00733 typedef struct svn_repos_node_t
00734 {
00735   /** Node type (file, dir, etc.) */
00736   svn_node_kind_t kind;
00737 
00738   /** How this node entered the node tree: 'A'dd, 'D'elete, 'R'eplace */
00739   char action; 
00740 
00741   /** Were there any textual mods? (files only) */
00742   svn_boolean_t text_mod;
00743 
00744   /** Where there any property mods? */
00745   svn_boolean_t prop_mod;
00746 
00747   /** The name of this node as it appears in its parent's entries list */
00748   const char *name;
00749 
00750   /** The filesystem revision where this was copied from (if any) */
00751   svn_revnum_t copyfrom_rev;
00752 
00753   /** The filesystem path where this was copied from (if any) */
00754   const char *copyfrom_path;
00755 
00756   /** Pointer to the next sibling of this node */
00757   struct svn_repos_node_t *sibling;
00758 
00759   /** Pointer to the first child of this node */
00760   struct svn_repos_node_t *child;
00761 
00762   /** Pointer to the parent of this node */
00763   struct svn_repos_node_t *parent;
00764 
00765 } svn_repos_node_t;
00766 
00767 
00768 /** Set @a *editor and @a *edit_baton to an editor that, when driven by
00769  * @c svn_repos_dir_delta(), builds an <tt>svn_repos_node_t *</tt> tree
00770  * representing the delta from @a base_root to @a root in @a repos's 
00771  * filesystem.
00772  *  
00773  * Invoke @c svn_repos_node_from_baton() on @a edit_baton to obtain the root
00774  * node afterwards.
00775  *
00776  * Note that the delta includes "bubbled-up" directories; that is,
00777  * many of the directory nodes will have no prop_mods.
00778  *
00779  * Allocate the tree and its contents in @a node_pool; do all other
00780  * allocation in @a pool.
00781  */
00782 svn_error_t *svn_repos_node_editor (const svn_delta_editor_t **editor,
00783                                     void **edit_baton,
00784                                     svn_repos_t *repos,
00785                                     svn_fs_root_t *base_root,
00786                                     svn_fs_root_t *root,
00787                                     apr_pool_t *node_pool,
00788                                     apr_pool_t *pool);
00789 
00790 /** Return the root node of the linked-list tree generated by driving
00791  * the editor created by @c svn_repos_node_editor() with
00792  * @c svn_repos_dir_delta(), which is stored in @a edit_baton.  This is 
00793  * only really useful if used *after* the editor drive is completed.
00794  */
00795 svn_repos_node_t *svn_repos_node_from_baton (void *edit_baton);
00796 
00797 /** @} */
00798 
00799 /* ---------------------------------------------------------------*/
00800 
00801 /**
00802  * @defgroup svn_repos_dump_load Dumping and loading filesystem data
00803  * @{
00804  *
00805  * The filesystem 'dump' format contains nothing but the abstract
00806  * structure of the filesystem -- independent of any internal node-id
00807  * schema or database back-end.  All of the data in the dumpfile is
00808  * acquired by public function calls into svn_fs.h.  Similarly, the
00809  * parser which reads the dumpfile is able to reconstruct the
00810  * filesystem using only public svn_fs.h routines.
00811  *
00812  * Thus the dump/load feature's main purpose is for *migrating* data
00813  * from one svn filesystem to another -- presumably two filesystems
00814  * which have different internal implementations.
00815  *
00816  * If you simply want to backup your filesystem, you're probably
00817  * better off using the built-in facilities of the DB backend (using
00818  * Berkeley DB's hot-backup feature, for example.)
00819  * 
00820  * For a description of the dumpfile format, see
00821  * /trunk/notes/fs_dumprestore.txt.
00822  */
00823 
00824 /* The RFC822-style headers in our dumpfile format. */
00825 #define SVN_REPOS_DUMPFILE_MAGIC_HEADER            "SVN-fs-dump-format-version"
00826 #define SVN_REPOS_DUMPFILE_FORMAT_VERSION           2
00827 #define SVN_REPOS_DUMPFILE_UUID                      "UUID"
00828 #define SVN_REPOS_DUMPFILE_CONTENT_LENGTH            "Content-length"
00829 
00830 #define SVN_REPOS_DUMPFILE_REVISION_NUMBER           "Revision-number"
00831 
00832 #define SVN_REPOS_DUMPFILE_NODE_PATH                 "Node-path"
00833 #define SVN_REPOS_DUMPFILE_NODE_KIND                 "Node-kind"
00834 #define SVN_REPOS_DUMPFILE_NODE_ACTION               "Node-action"
00835 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH        "Node-copyfrom-path"
00836 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV         "Node-copyfrom-rev"
00837 #define SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM "Text-copy-source-md5"
00838 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM     "Text-content-md5"
00839 
00840 #define SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH       "Prop-content-length"
00841 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH       "Text-content-length"
00842 
00843 /** The different "actions" attached to nodes in the dumpfile. */
00844 enum svn_node_action
00845 {
00846   svn_node_action_change,
00847   svn_node_action_add,
00848   svn_node_action_delete,
00849   svn_node_action_replace
00850 };
00851 
00852 /** The different policies for processing the UUID in the dumpfile. */
00853 enum svn_repos_load_uuid
00854 {
00855   svn_repos_load_uuid_default,
00856   svn_repos_load_uuid_ignore,
00857   svn_repos_load_uuid_force
00858 };
00859 
00860 /** Dump the contents of the filesystem within already-open @a repos into
00861  * writable @a dumpstream.  Begin at revision @a start_rev, and dump every
00862  * revision up through @a end_rev.  Use @a pool for all allocation.  If
00863  * non-@c NULL, send feedback to @a feedback_stream. @a dumpstream can be
00864  * @c NULL for the purpose of verifying the repository.
00865  *
00866  * If @a start_rev is @c SVN_INVALID_REVNUM, then start dumping at revision 
00867  * 0.  If @a end_rev is @c SVN_INVALID_REVNUM, then dump through the @c HEAD 
00868  * revision.
00869  *
00870  * If @a incremental is @c TRUE, the first revision dumped will be a diff
00871  * against the previous revision (usually it looks like a full dump of
00872  * the tree).
00873  *
00874  * If @a cancel_func is not @c NULL, it is called periodically with
00875  * @a cancel_baton as argument to see if the client wishes to cancel
00876  * the dump.
00877  */
00878 svn_error_t *svn_repos_dump_fs (svn_repos_t *repos,
00879                                 svn_stream_t *dumpstream,
00880                                 svn_stream_t *feedback_stream,
00881                                 svn_revnum_t start_rev,
00882                                 svn_revnum_t end_rev,
00883                                 svn_boolean_t incremental,
00884                                 svn_cancel_func_t cancel_func,
00885                                 void *cancel_baton,
00886                                 apr_pool_t *pool);
00887 
00888 
00889 /** Read and parse dumpfile-formatted @a dumpstream, reconstructing
00890  * filesystem revisions in already-open @a repos, handling uuids
00891  * in accordance with @a uuid_action.
00892  *
00893  * Read and parse dumpfile-formatted @a dumpstream, reconstructing
00894  * filesystem revisions in already-open @a repos.  Use @a pool for all
00895  * allocation.  If non-@c NULL, send feedback to @a feedback_stream.
00896  *
00897  * If the dumpstream contains copy history that is unavailable in the
00898  * repository, an error will be thrown.
00899  *
00900  * The repository's UUID will be updated iff
00901  *   the dumpstream contains a UUID and
00902  *   @a uuid_action is not equal to @c svn_repos_load_uuid_ignore and
00903  *   either the repository contains no revisions or
00904  *          @a uuid_action is equal to @c svn_repos_load_uuid_force.
00905  *
00906  * If the dumpstream contains no UUID, then @a uuid_action is
00907  * ignored and the repository UUID is not touched.
00908  *
00909  * If @a cancel_func is not @c NULL, it is called periodically with
00910  * @a cancel_baton as argument to see if the client wishes to cancel
00911  * the load.
00912  */
00913 svn_error_t *svn_repos_load_fs (svn_repos_t *repos,
00914                                 svn_stream_t *dumpstream,
00915                                 svn_stream_t *feedback_stream,
00916                                 enum svn_repos_load_uuid uuid_action,
00917                                 const char *parent_dir,
00918                                 svn_cancel_func_t cancel_func,
00919                                 void *cancel_baton,
00920                                 apr_pool_t *pool);
00921 
00922 
00923 /** A vtable that is driven by @c svn_repos_parse_dumpstream. */
00924 typedef struct svn_repos_parse_fns_t
00925 {
00926   /** The parser has discovered a new revision record within the
00927    * parsing session represented by @a parse_baton.  All the headers are
00928    * placed in @a headers (allocated in @a pool), which maps <tt>const 
00929    * char *</tt> header-name ==> <tt>const char *</tt> header-value.  
00930    * The @a revision_baton received back (also allocated in @a pool) 
00931    * represents the revision.
00932    */
00933   svn_error_t *(*new_revision_record) (void **revision_baton,
00934                                        apr_hash_t *headers,
00935                                        void *parse_baton,
00936                                        apr_pool_t *pool);
00937 
00938   /** The parser has discovered a new uuid record within the parsing
00939    * session represented by @a parse_baton.  The uuid's value is
00940    * @a uuid, and it is allocated in @a pool.
00941    */
00942   svn_error_t *(*uuid_record) (const char *uuid,
00943                                void *parse_baton,
00944                                apr_pool_t *pool);
00945 
00946   /** The parser has discovered a new node record within the current
00947    * revision represented by @a revision_baton.  All the headers are
00948    * placed in @a headers as above, allocated in @a pool.  The 
00949    * @a node_baton received back is allocated in @a pool and represents 
00950    * the node.
00951    */
00952   svn_error_t *(*new_node_record) (void **node_baton,
00953                                    apr_hash_t *headers,
00954                                    void *revision_baton,
00955                                    apr_pool_t *pool);
00956 
00957   /** For a given @a revision_baton, set a property @a name to @a value. */
00958   svn_error_t *(*set_revision_property) (void *revision_baton,
00959                                          const char *name,
00960                                          const svn_string_t *value);
00961 
00962   /** For a given @a node_baton, set a property @a name to @a value. */
00963   svn_error_t *(*set_node_property) (void *node_baton,
00964                                      const char *name,
00965                                      const svn_string_t *value);
00966 
00967   /** For a given @a node_baton, remove all properties. */
00968   svn_error_t *(*remove_node_props) (void *node_baton);
00969 
00970   /** For a given @a node_baton, receive a writable @a stream capable of
00971    * receiving the node's fulltext.  After writing the fulltext, call
00972    * the stream's @c close() function.
00973    *
00974    * If a @c NULL is returned instead of a stream, the vtable is
00975    * indicating that no text is desired, and the parser will not
00976    * attempt to send it.
00977    */
00978   svn_error_t *(*set_fulltext) (svn_stream_t **stream,
00979                                 void *node_baton);
00980 
00981   /** The parser has reached the end of the current node represented by
00982    * @a node_baton, it can be freed.
00983    */
00984   svn_error_t *(*close_node) (void *node_baton);
00985 
00986   /** The parser has reached the end of the current revision
00987    * represented by @a revision_baton.  In other words, there are no more
00988    * changed nodes within the revision.  The baton can be freed.
00989    */
00990   svn_error_t *(*close_revision) (void *revision_baton);
00991 
00992 } svn_repos_parser_fns_t;
00993 
00994 
00995 
00996 /** Read and parse dumpfile-formatted @a stream, calling callbacks in
00997  * @a parse_fns/@a parse_baton, and using @a pool for allocations.
00998  *
00999  * If @a cancel_func is not @c NULL, it is called periodically with
01000  * @a cancel_baton as argument to see if the client wishes to cancel
01001  * the dump.
01002  *
01003  * This parser has built-in knowledge of the dumpfile format, but only
01004  * in a general sense:
01005  *
01006  *    * it recognizes revision and node records by looking for either
01007  *      a REVISION_NUMBER or NODE_PATH headers.
01008  *
01009  *    * it recognizes the CONTENT-LENGTH headers, so it knows if and
01010  *      how to suck up the content body.
01011  *
01012  *    * it knows how to parse a content body into two parts:  props
01013  *      and text, and pass the pieces to the vtable.
01014  *
01015  * This is enough knowledge to make it easy on vtable implementors,
01016  * but still allow expansion of the format:  most headers are ignored.
01017  */
01018 svn_error_t *
01019 svn_repos_parse_dumpstream (svn_stream_t *stream,
01020                             const svn_repos_parser_fns_t *parse_fns,
01021                             void *parse_baton,
01022                             svn_cancel_func_t cancel_func,
01023                             void *cancel_baton,
01024                             apr_pool_t *pool);
01025 
01026 
01027 /** Set @a *parser and @a *parse_baton to a vtable parser which commits new
01028  * revisions to the fs in @a repos.  The constructed parser will treat
01029  * UUID records in a manner consistent with @a uuid_action.  Use @a pool
01030  * to operate on the fs.
01031  *
01032  * If @a use_history is set, then the parser will require relative
01033  * 'copyfrom' history to exist in the repository when it encounters
01034  * nodes that are added-with-history.
01035  *
01036  * If @a parent_dir is not null, then the parser will reparent all the
01037  * loaded nodes, from root to @a parent_dir.  The directory @a parent_dir
01038  * must be an existing directory in the repository.
01039  *
01040  * Print all parsing feedback to @a outstream (if non-@c NULL).
01041  *
01042  */
01043 svn_error_t *
01044 svn_repos_get_fs_build_parser (const svn_repos_parser_fns_t **parser,
01045                                void **parse_baton,
01046                                svn_repos_t *repos,
01047                                svn_boolean_t use_history,
01048                                enum svn_repos_load_uuid uuid_action,
01049                                svn_stream_t *outstream,
01050                                const char *parent_dir,
01051                                apr_pool_t *pool);
01052 /** @} */
01053 
01054 #ifdef __cplusplus
01055 }
01056 #endif /* __cplusplus */
01057 
01058 #endif /* SVN_REPOS_H */

Generated on Mon Oct 18 17:33:13 2004 for Subversion by doxygen 1.3.5