1/* reps-table.c : operations on the `representations' table 2 * 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 */ 22 23#include "bdb_compat.h" 24#include "svn_fs.h" 25#include "../fs.h" 26#include "../util/fs_skels.h" 27#include "../err.h" 28#include "dbt.h" 29#include "../trail.h" 30#include "../key-gen.h" 31#include "../../libsvn_fs/fs-loader.h" 32#include "bdb-err.h" 33#include "reps-table.h" 34#include "strings-table.h" 35 36 37#include "svn_private_config.h" 38 39 40/*** Creating and opening the representations table. ***/ 41 42int 43svn_fs_bdb__open_reps_table(DB **reps_p, 44 DB_ENV *env, 45 svn_boolean_t create) 46{ 47 const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0); 48 DB *reps; 49 50 BDB_ERR(svn_fs_bdb__check_version()); 51 BDB_ERR(db_create(&reps, env, 0)); 52 BDB_ERR((reps->open)(SVN_BDB_OPEN_PARAMS(reps, NULL), 53 "representations", 0, DB_BTREE, 54 open_flags, 0666)); 55 56 /* Create the `next-key' table entry. */ 57 if (create) 58 { 59 DBT key, value; 60 61 BDB_ERR(reps->put 62 (reps, 0, 63 svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY), 64 svn_fs_base__str_to_dbt(&value, "0"), 0)); 65 } 66 67 *reps_p = reps; 68 return 0; 69} 70 71 72 73/*** Storing and retrieving reps. ***/ 74 75svn_error_t * 76svn_fs_bdb__read_rep(representation_t **rep_p, 77 svn_fs_t *fs, 78 const char *key, 79 trail_t *trail, 80 apr_pool_t *pool) 81{ 82 base_fs_data_t *bfd = fs->fsap_data; 83 svn_skel_t *skel; 84 int db_err; 85 DBT query, result; 86 87 svn_fs_base__trail_debug(trail, "representations", "get"); 88 db_err = bfd->representations->get(bfd->representations, 89 trail->db_txn, 90 svn_fs_base__str_to_dbt(&query, key), 91 svn_fs_base__result_dbt(&result), 0); 92 svn_fs_base__track_dbt(&result, pool); 93 94 /* If there's no such node, return an appropriately specific error. */ 95 if (db_err == DB_NOTFOUND) 96 return svn_error_createf 97 (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0, 98 _("No such representation '%s'"), key); 99 100 /* Handle any other error conditions. */ 101 SVN_ERR(BDB_WRAP(fs, N_("reading representation"), db_err)); 102 103 /* Parse the REPRESENTATION skel. */ 104 skel = svn_skel__parse(result.data, result.size, pool); 105 106 /* Convert to a native type. */ 107 return svn_fs_base__parse_representation_skel(rep_p, skel, pool); 108} 109 110 111svn_error_t * 112svn_fs_bdb__write_rep(svn_fs_t *fs, 113 const char *key, 114 const representation_t *rep, 115 trail_t *trail, 116 apr_pool_t *pool) 117{ 118 base_fs_data_t *bfd = fs->fsap_data; 119 DBT query, result; 120 svn_skel_t *skel; 121 122 /* Convert from native type to skel. */ 123 SVN_ERR(svn_fs_base__unparse_representation_skel(&skel, rep, 124 bfd->format, pool)); 125 126 /* Now write the record. */ 127 svn_fs_base__trail_debug(trail, "representations", "put"); 128 return BDB_WRAP(fs, N_("storing representation"), 129 bfd->representations->put 130 (bfd->representations, trail->db_txn, 131 svn_fs_base__str_to_dbt(&query, key), 132 svn_fs_base__skel_to_dbt(&result, skel, pool), 133 0)); 134} 135 136 137svn_error_t * 138svn_fs_bdb__write_new_rep(const char **key, 139 svn_fs_t *fs, 140 const representation_t *rep, 141 trail_t *trail, 142 apr_pool_t *pool) 143{ 144 base_fs_data_t *bfd = fs->fsap_data; 145 DBT query, result; 146 int db_err; 147 apr_size_t len; 148 char next_key[MAX_KEY_SIZE]; 149 150 /* ### todo: see issue #409 for why bumping the key as part of this 151 trail is problematic. */ 152 153 /* Get the current value associated with `next-key'. */ 154 svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); 155 svn_fs_base__trail_debug(trail, "representations", "get"); 156 SVN_ERR(BDB_WRAP(fs, N_("allocating new representation (getting next-key)"), 157 bfd->representations->get 158 (bfd->representations, trail->db_txn, &query, 159 svn_fs_base__result_dbt(&result), 0))); 160 161 svn_fs_base__track_dbt(&result, pool); 162 163 /* Store the new rep. */ 164 *key = apr_pstrmemdup(pool, result.data, result.size); 165 SVN_ERR(svn_fs_bdb__write_rep(fs, *key, rep, trail, pool)); 166 167 /* Bump to future key. */ 168 len = result.size; 169 svn_fs_base__next_key(result.data, &len, next_key); 170 svn_fs_base__trail_debug(trail, "representations", "put"); 171 db_err = bfd->representations->put 172 (bfd->representations, trail->db_txn, 173 svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), 174 svn_fs_base__str_to_dbt(&result, next_key), 175 0); 176 177 return BDB_WRAP(fs, N_("bumping next representation key"), db_err); 178} 179 180 181svn_error_t * 182svn_fs_bdb__delete_rep(svn_fs_t *fs, 183 const char *key, 184 trail_t *trail, 185 apr_pool_t *pool) 186{ 187 base_fs_data_t *bfd = fs->fsap_data; 188 int db_err; 189 DBT query; 190 191 svn_fs_base__trail_debug(trail, "representations", "del"); 192 db_err = bfd->representations->del 193 (bfd->representations, trail->db_txn, 194 svn_fs_base__str_to_dbt(&query, key), 0); 195 196 /* If there's no such node, return an appropriately specific error. */ 197 if (db_err == DB_NOTFOUND) 198 return svn_error_createf 199 (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0, 200 _("No such representation '%s'"), key); 201 202 /* Handle any other error conditions. */ 203 return BDB_WRAP(fs, N_("deleting representation"), db_err); 204} 205