1251881Speter/* copies-table.c : operations on the `copies' table 2251881Speter * 3251881Speter * ==================================================================== 4251881Speter * Licensed to the Apache Software Foundation (ASF) under one 5251881Speter * or more contributor license agreements. See the NOTICE file 6251881Speter * distributed with this work for additional information 7251881Speter * regarding copyright ownership. The ASF licenses this file 8251881Speter * to you under the Apache License, Version 2.0 (the 9251881Speter * "License"); you may not use this file except in compliance 10251881Speter * with the License. You may obtain a copy of the License at 11251881Speter * 12251881Speter * http://www.apache.org/licenses/LICENSE-2.0 13251881Speter * 14251881Speter * Unless required by applicable law or agreed to in writing, 15251881Speter * software distributed under the License is distributed on an 16251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17251881Speter * KIND, either express or implied. See the License for the 18251881Speter * specific language governing permissions and limitations 19251881Speter * under the License. 20251881Speter * ==================================================================== 21251881Speter */ 22251881Speter 23251881Speter#include <string.h> 24251881Speter 25251881Speter#include "bdb_compat.h" 26251881Speter 27251881Speter#include "private/svn_skel.h" 28251881Speter 29251881Speter#include "../fs.h" 30251881Speter#include "../err.h" 31251881Speter#include "../key-gen.h" 32251881Speter#include "dbt.h" 33251881Speter#include "../util/fs_skels.h" 34251881Speter#include "../trail.h" 35251881Speter#include "../../libsvn_fs/fs-loader.h" 36251881Speter#include "bdb-err.h" 37251881Speter#include "copies-table.h" 38251881Speter#include "rev-table.h" 39251881Speter 40251881Speter#include "svn_private_config.h" 41251881Speter 42251881Speter 43251881Speterint 44251881Spetersvn_fs_bdb__open_copies_table(DB **copies_p, 45251881Speter DB_ENV *env, 46251881Speter svn_boolean_t create) 47251881Speter{ 48251881Speter const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0); 49251881Speter DB *copies; 50251881Speter 51251881Speter BDB_ERR(svn_fs_bdb__check_version()); 52251881Speter BDB_ERR(db_create(&copies, env, 0)); 53251881Speter BDB_ERR((copies->open)(SVN_BDB_OPEN_PARAMS(copies, NULL), 54251881Speter "copies", 0, DB_BTREE, 55251881Speter open_flags, 0666)); 56251881Speter 57251881Speter /* Create the initial `next-key' table entry. */ 58251881Speter if (create) 59251881Speter { 60251881Speter DBT key, value; 61251881Speter BDB_ERR(copies->put(copies, 0, 62251881Speter svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY), 63251881Speter svn_fs_base__str_to_dbt(&value, "0"), 0)); 64251881Speter } 65251881Speter 66251881Speter *copies_p = copies; 67251881Speter return 0; 68251881Speter} 69251881Speter 70251881Speter 71251881Speter/* Store COPY as a copy named COPY_ID in FS as part of TRAIL. */ 72251881Speter/* ### only has one caller; might not need to be abstracted */ 73251881Speterstatic svn_error_t * 74251881Speterput_copy(svn_fs_t *fs, 75251881Speter const copy_t *copy, 76251881Speter const char *copy_id, 77251881Speter trail_t *trail, 78251881Speter apr_pool_t *pool) 79251881Speter{ 80251881Speter base_fs_data_t *bfd = fs->fsap_data; 81251881Speter svn_skel_t *copy_skel; 82251881Speter DBT key, value; 83251881Speter 84251881Speter /* Convert native type to skel. */ 85251881Speter SVN_ERR(svn_fs_base__unparse_copy_skel(©_skel, copy, pool)); 86251881Speter 87251881Speter /* Only in the context of this function do we know that the DB call 88251881Speter will not attempt to modify COPY_ID, so the cast belongs here. */ 89251881Speter svn_fs_base__str_to_dbt(&key, copy_id); 90251881Speter svn_fs_base__skel_to_dbt(&value, copy_skel, pool); 91251881Speter svn_fs_base__trail_debug(trail, "copies", "put"); 92251881Speter return BDB_WRAP(fs, N_("storing copy record"), 93251881Speter bfd->copies->put(bfd->copies, trail->db_txn, 94251881Speter &key, &value, 0)); 95251881Speter} 96251881Speter 97251881Speter 98251881Spetersvn_error_t * 99251881Spetersvn_fs_bdb__reserve_copy_id(const char **id_p, 100251881Speter svn_fs_t *fs, 101251881Speter trail_t *trail, 102251881Speter apr_pool_t *pool) 103251881Speter{ 104251881Speter base_fs_data_t *bfd = fs->fsap_data; 105251881Speter DBT query, result; 106251881Speter apr_size_t len; 107251881Speter char next_key[MAX_KEY_SIZE]; 108251881Speter int db_err; 109251881Speter 110251881Speter svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); 111251881Speter 112251881Speter /* Get the current value associated with the `next-key' key in the 113251881Speter copies table. */ 114251881Speter svn_fs_base__trail_debug(trail, "copies", "get"); 115251881Speter SVN_ERR(BDB_WRAP(fs, N_("allocating new copy ID (getting 'next-key')"), 116251881Speter bfd->copies->get(bfd->copies, trail->db_txn, &query, 117251881Speter svn_fs_base__result_dbt(&result), 118251881Speter 0))); 119251881Speter svn_fs_base__track_dbt(&result, pool); 120251881Speter 121251881Speter /* Set our return value. */ 122251881Speter *id_p = apr_pstrmemdup(pool, result.data, result.size); 123251881Speter 124251881Speter /* Bump to future key. */ 125251881Speter len = result.size; 126251881Speter svn_fs_base__next_key(result.data, &len, next_key); 127251881Speter svn_fs_base__trail_debug(trail, "copies", "put"); 128251881Speter db_err = bfd->copies->put(bfd->copies, trail->db_txn, 129251881Speter svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), 130251881Speter svn_fs_base__str_to_dbt(&result, next_key), 131251881Speter 0); 132251881Speter 133251881Speter return BDB_WRAP(fs, N_("bumping next copy key"), db_err); 134251881Speter} 135251881Speter 136251881Speter 137251881Spetersvn_error_t * 138251881Spetersvn_fs_bdb__create_copy(svn_fs_t *fs, 139251881Speter const char *copy_id, 140251881Speter const char *src_path, 141251881Speter const char *src_txn_id, 142251881Speter const svn_fs_id_t *dst_noderev_id, 143251881Speter copy_kind_t kind, 144251881Speter trail_t *trail, 145251881Speter apr_pool_t *pool) 146251881Speter{ 147251881Speter copy_t copy; 148251881Speter copy.kind = kind; 149251881Speter copy.src_path = src_path; 150251881Speter copy.src_txn_id = src_txn_id; 151251881Speter copy.dst_noderev_id = dst_noderev_id; 152251881Speter return put_copy(fs, ©, copy_id, trail, pool); 153251881Speter} 154251881Speter 155251881Speter 156251881Spetersvn_error_t * 157251881Spetersvn_fs_bdb__delete_copy(svn_fs_t *fs, 158251881Speter const char *copy_id, 159251881Speter trail_t *trail, 160251881Speter apr_pool_t *pool) 161251881Speter{ 162251881Speter base_fs_data_t *bfd = fs->fsap_data; 163251881Speter DBT key; 164251881Speter int db_err; 165251881Speter 166251881Speter svn_fs_base__str_to_dbt(&key, copy_id); 167251881Speter svn_fs_base__trail_debug(trail, "copies", "del"); 168251881Speter db_err = bfd->copies->del(bfd->copies, trail->db_txn, &key, 0); 169251881Speter if (db_err == DB_NOTFOUND) 170251881Speter return svn_fs_base__err_no_such_copy(fs, copy_id); 171251881Speter return BDB_WRAP(fs, N_("deleting entry from 'copies' table"), db_err); 172251881Speter} 173251881Speter 174251881Speter 175251881Spetersvn_error_t * 176251881Spetersvn_fs_bdb__get_copy(copy_t **copy_p, 177251881Speter svn_fs_t *fs, 178251881Speter const char *copy_id, 179251881Speter trail_t *trail, 180251881Speter apr_pool_t *pool) 181251881Speter{ 182251881Speter base_fs_data_t *bfd = fs->fsap_data; 183251881Speter DBT key, value; 184251881Speter int db_err; 185251881Speter svn_skel_t *skel; 186251881Speter copy_t *copy; 187251881Speter 188251881Speter /* Only in the context of this function do we know that the DB call 189251881Speter will not attempt to modify copy_id, so the cast belongs here. */ 190251881Speter svn_fs_base__trail_debug(trail, "copies", "get"); 191251881Speter db_err = bfd->copies->get(bfd->copies, trail->db_txn, 192251881Speter svn_fs_base__str_to_dbt(&key, copy_id), 193251881Speter svn_fs_base__result_dbt(&value), 194251881Speter 0); 195251881Speter svn_fs_base__track_dbt(&value, pool); 196251881Speter 197251881Speter if (db_err == DB_NOTFOUND) 198251881Speter return svn_fs_base__err_no_such_copy(fs, copy_id); 199251881Speter SVN_ERR(BDB_WRAP(fs, N_("reading copy"), db_err)); 200251881Speter 201251881Speter /* Unparse COPY skel */ 202251881Speter skel = svn_skel__parse(value.data, value.size, pool); 203251881Speter if (! skel) 204251881Speter return svn_fs_base__err_corrupt_copy(fs, copy_id); 205251881Speter 206251881Speter /* Convert skel to native type. */ 207251881Speter SVN_ERR(svn_fs_base__parse_copy_skel(©, skel, pool)); 208251881Speter *copy_p = copy; 209251881Speter return SVN_NO_ERROR; 210251881Speter} 211