#define SVN_WC__I_AM_WC_DB
#include "svn_dirent_uri.h"
#include "private/svn_sqlite.h"
#include "wc.h"
#include "adm_files.h"
#include "wc_db_private.h"
#include "wc-queries.h"
#include "svn_private_config.h"
WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
svn_error_t *
svn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id,
svn_sqlite__db_t *sdb,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WCROOT_NULL));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (!have_row)
return svn_error_createf(SVN_ERR_WC_CORRUPT, svn_sqlite__reset(stmt),
_("Missing a row in WCROOT."));
SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 0));
*wc_id = svn_sqlite__column_int64(stmt, 0);
return svn_error_trace(svn_sqlite__reset(stmt));
}
static svn_error_t *
relpath_depth(svn_sqlite__context_t *sctx,
int argc,
svn_sqlite__value_t *values[],
apr_pool_t *scratch_pool)
{
const char *path = NULL;
apr_int64_t depth;
if (argc == 1 && svn_sqlite__value_type(values[0]) == SVN_SQLITE__TEXT)
path = svn_sqlite__value_text(values[0]);
if (!path)
{
svn_sqlite__result_null(sctx);
return SVN_NO_ERROR;
}
depth = *path ? 1 : 0;
while (*path)
{
if (*path == '/')
++depth;
++path;
}
svn_sqlite__result_int64(sctx, depth);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_util_open_db(svn_sqlite__db_t **sdb,
const char *dir_abspath,
const char *sdb_fname,
svn_sqlite__mode_t smode,
const char *const *my_statements,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *sdb_abspath = svn_wc__adm_child(dir_abspath, sdb_fname,
scratch_pool);
if (smode != svn_sqlite__mode_rwcreate)
{
svn_node_kind_t kind;
SVN_ERR(svn_io_check_path(sdb_abspath, &kind, scratch_pool));
if (kind != svn_node_file)
return svn_error_createf(APR_ENOENT, NULL,
_("Working copy database '%s' not found"),
svn_dirent_local_style(sdb_abspath,
scratch_pool));
}
SVN_ERR(svn_sqlite__open(sdb, sdb_abspath, smode,
my_statements ? my_statements : statements,
0, NULL, result_pool, scratch_pool));
SVN_ERR(svn_sqlite__create_scalar_function(*sdb, "relpath_depth", 1,
relpath_depth, NULL));
return SVN_NO_ERROR;
}
typedef svn_error_t *(*db_txn_callback_t)(void *baton,
svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
apr_pool_t *scratch_pool);
struct txn_baton_t
{
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
db_txn_callback_t cb_func;
void *cb_baton;
};
static svn_error_t *
run_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool)
{
struct txn_baton_t *tb = baton;
return svn_error_trace(
tb->cb_func(tb->cb_baton, tb->wcroot, tb->local_relpath, scratch_pool));
}
svn_error_t *
svn_wc__db_with_txn(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
svn_wc__db_txn_callback_t cb_func,
void *cb_baton,
apr_pool_t *scratch_pool)
{
struct txn_baton_t tb;
tb.wcroot = wcroot;
tb.local_relpath = local_relpath;
tb.cb_func = cb_func;
tb.cb_baton = cb_baton;
return svn_error_trace(
svn_sqlite__with_lock(wcroot->sdb, run_txn, &tb, scratch_pool));
}