#include <apr_pools.h>
#include <apr_hash.h>
#include "svn_types.h"
#include "svn_error.h"
#include "svn_path.h"
#include "wc_db.h"
#include "svn_private_config.h"
struct svn_wc__db_t {
svn_wc__db_openmode_t mode;
svn_config_t *config;
apr_hash_t *dir_data;
};
struct svn_wc__db_pdh_t {
svn_wc__db_t *db;
const char *base_dir;
};
#define SVN__SKIP_SUBDIR
static svn_error_t *
get_pristine_fname(const char **path,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
svn_boolean_t create_subdir,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *hexdigest = svn_checksum_to_cstring(checksum, scratch_pool);
#ifndef SVN__SKIP_SUBDIR
char subdir[3] = { 0 };
#endif
SVN_ERR_ASSERT(hexdigest != NULL);
#ifndef SVN__SKIP_SUBDIR
subdir[0] = hexdigest[0];
subdir[1] = hexdigest[1];
if (create_subdir)
{
const char *subdir_path = svn_path_join(pdh->base_dir, subdir,
scratch_pool);
svn_error_t *err;
err = svn_io_dir_make(subdir_path, APR_OS_DEFAULT, scratch_pool);
svn_error_clear(err);
}
#endif
*path = svn_path_join_many(result_pool,
pdh->base_dir,
#ifndef SVN__SKIP_SUBDIR
subdir,
#endif
hexdigest,
NULL);
return SVN_NO_ERROR;
}
static svn_error_t *
open_one_directory(svn_wc__db_t *db,
const char *path,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_node_kind_t kind;
svn_boolean_t special;
svn_wc__db_pdh_t *pdh;
SVN_ERR(svn_io_check_special_path(path, &kind, &special, scratch_pool));
if (kind != svn_node_dir)
{
path = svn_path_dirname(path, scratch_pool);
}
pdh = apr_hash_get(db->dir_data, path, APR_HASH_KEY_STRING);
if (pdh != NULL)
return SVN_NO_ERROR;
pdh = apr_palloc(result_pool, sizeof(*pdh));
pdh->db = db;
pdh->base_dir = svn_path_join(path, ".svn/pristine", result_pool);
path = apr_pstrdup(result_pool, path);
apr_hash_set(db->dir_data, path, APR_HASH_KEY_STRING, pdh);
return SVN_NO_ERROR;
}
static svn_wc__db_t *
new_db_state(svn_wc__db_openmode_t mode,
svn_config_t *config,
apr_pool_t *result_pool)
{
svn_wc__db_t *db = apr_palloc(result_pool, sizeof(*db));
db->mode = mode;
db->config = config;
db->dir_data = apr_hash_make(result_pool);
return db;
}
svn_error_t *
svn_wc__db_open(svn_wc__db_t **db,
svn_wc__db_openmode_t mode,
const char *path,
svn_config_t *config,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
*db = new_db_state(mode, config, result_pool);
return open_one_directory(*db, path, result_pool, scratch_pool);
}
svn_error_t *
svn_wc__db_open_many(svn_wc__db_t **db,
svn_wc__db_openmode_t mode,
const apr_array_header_t *paths,
svn_config_t *config,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
int i;
*db = new_db_state(mode, config, result_pool);
for (i = 0; i < paths->nelts; ++i)
{
const char *path = APR_ARRAY_IDX(paths, i, const char *);
SVN_ERR(open_one_directory(*db, path, result_pool, scratch_pool));
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_txn_begin(svn_wc__db_t *db,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_txn_rollback(svn_wc__db_t *db,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_txn_commit(svn_wc__db_t *db,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_close(svn_wc__db_t *db,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
SVN_ERR(svn_wc__db_txn_rollback(db, result_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_pristine_dirhandle(svn_wc__db_pdh_t **pdh,
svn_wc__db_t *db,
const char *dirpath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
*pdh = apr_hash_get(db->dir_data, dirpath, APR_HASH_KEY_STRING);
if (*pdh == NULL)
{
SVN_ERR(open_one_directory(db, dirpath, result_pool, scratch_pool));
*pdh = apr_hash_get(db->dir_data, dirpath, APR_HASH_KEY_STRING);
SVN_ERR_ASSERT(*pdh != NULL);
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_pristine_read(svn_stream_t **contents,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *path;
SVN_ERR(get_pristine_fname(&path, pdh, checksum, FALSE ,
scratch_pool, scratch_pool));
return svn_stream_open_readonly(contents, path, result_pool, scratch_pool);
}
svn_error_t *
svn_wc__db_pristine_write(svn_stream_t **contents,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *path;
SVN_ERR(get_pristine_fname(&path, pdh, checksum, TRUE ,
scratch_pool, scratch_pool));
SVN_ERR(svn_stream_open_writable(contents, path, result_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_pristine_check(svn_boolean_t *present,
int *refcount,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
svn_wc__db_checkmode_t mode,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_pristine_repair(svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_pristine_incref(int *new_refcount,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}
svn_error_t *
svn_wc__db_pristine_decref(int *new_refcount,
svn_wc__db_pdh_t *pdh,
svn_checksum_t *checksum,
apr_pool_t *scratch_pool)
{
return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.");
}