1 /* checksum-reps-table.c : operations on the `checksum-reps' table
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * ====================================================================
23 #include <apr_strings.h>
25 #include "bdb_compat.h"
28 #include "../key-gen.h"
32 #include "../../libsvn_fs/fs-loader.h"
33 #include "checksum-reps-table.h"
35 #include "svn_private_config.h"
38 int svn_fs_bdb__open_checksum_reps_table(DB **checksum_reps_p,
42 const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
46 BDB_ERR(svn_fs_bdb__check_version());
47 BDB_ERR(db_create(&checksum_reps, env, 0));
48 error = (checksum_reps->open)(SVN_BDB_OPEN_PARAMS(checksum_reps, NULL),
49 "checksum-reps", 0, DB_BTREE,
52 /* Create the checksum-reps table if it doesn't exist. */
53 if (error == ENOENT && (! create))
55 BDB_ERR(checksum_reps->close(checksum_reps, 0));
56 return svn_fs_bdb__open_checksum_reps_table(checksum_reps_p, env, TRUE);
59 /* Create the initial `next-key' table entry. */
63 BDB_ERR(checksum_reps->put(checksum_reps, 0,
64 svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
65 svn_fs_base__str_to_dbt(&value, "0"), 0));
70 *checksum_reps_p = checksum_reps;
74 svn_error_t *svn_fs_bdb__get_checksum_rep(const char **rep_key,
76 svn_checksum_t *checksum,
80 base_fs_data_t *bfd = fs->fsap_data;
84 /* We only allow SHA1 checksums in this table. */
85 if (checksum->kind != svn_checksum_sha1)
86 return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
87 _("Only SHA1 checksums can be used as keys in the "
88 "checksum-reps table.\n"));
90 svn_fs_base__trail_debug(trail, "checksum-reps", "get");
91 db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
92 svn_fs_base__checksum_to_dbt(&key, checksum),
93 svn_fs_base__result_dbt(&value), 0);
94 svn_fs_base__track_dbt(&value, pool);
96 if (db_err == DB_NOTFOUND)
97 return svn_fs_base__err_no_such_checksum_rep(fs, checksum);
99 *rep_key = apr_pstrmemdup(pool, value.data, value.size);
103 svn_error_t *svn_fs_bdb__set_checksum_rep(svn_fs_t *fs,
104 svn_checksum_t *checksum,
109 base_fs_data_t *bfd = fs->fsap_data;
113 /* We only allow SHA1 checksums in this table. */
114 if (checksum->kind != svn_checksum_sha1)
115 return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
116 _("Only SHA1 checksums can be used as keys in the "
117 "checksum-reps table.\n"));
119 /* Create a key from our CHECKSUM. */
120 svn_fs_base__checksum_to_dbt(&key, checksum);
122 /* Check to see if we already have a mapping for CHECKSUM. If so,
123 and the value is the same one we were about to write, that's
124 cool -- just do nothing. If, however, the value is *different*,
125 that's a red flag! */
126 svn_fs_base__trail_debug(trail, "checksum-reps", "get");
127 db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
128 &key, svn_fs_base__result_dbt(&value), 0);
129 svn_fs_base__track_dbt(&value, pool);
130 if (db_err != DB_NOTFOUND)
132 const char *sum_str = svn_checksum_to_cstring_display(checksum, pool);
133 return svn_error_createf
134 (SVN_ERR_FS_ALREADY_EXISTS, NULL,
135 _("Representation key for checksum '%s' exists in filesystem '%s'."),
139 /* Create a value from our REP_KEY, and add this record to the table. */
140 svn_fs_base__str_to_dbt(&value, rep_key);
141 svn_fs_base__trail_debug(trail, "checksum-reps", "put");
142 SVN_ERR(BDB_WRAP(fs, N_("storing checksum-reps record"),
143 bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
148 svn_error_t *svn_fs_bdb__delete_checksum_rep(svn_fs_t *fs,
149 svn_checksum_t *checksum,
153 base_fs_data_t *bfd = fs->fsap_data;
156 /* We only allow SHA1 checksums in this table. */
157 if (checksum->kind != svn_checksum_sha1)
158 return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
159 _("Only SHA1 checksums can be used as keys in the "
160 "checksum-reps table.\n"));
162 svn_fs_base__checksum_to_dbt(&key, checksum);
163 svn_fs_base__trail_debug(trail, "checksum-reps", "del");
164 SVN_ERR(BDB_WRAP(fs, N_("deleting entry from 'checksum-reps' table"),
165 bfd->checksum_reps->del(bfd->checksum_reps,
166 trail->db_txn, &key, 0)));
170 svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p,
175 base_fs_data_t *bfd = fs->fsap_data;
178 char next_key[MAX_KEY_SIZE];
181 svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
183 /* Get the current value associated with the `next-key' key in the
184 `checksum-reps' table. */
185 svn_fs_base__trail_debug(trail, "checksum-reps", "get");
186 SVN_ERR(BDB_WRAP(fs, N_("allocating new representation reuse ID "
187 "(getting 'next-key')"),
188 bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
190 svn_fs_base__result_dbt(&result),
192 svn_fs_base__track_dbt(&result, pool);
194 /* Set our return value. */
195 *id_p = apr_pstrmemdup(pool, result.data, result.size);
197 /* Bump to future key. */
199 svn_fs_base__next_key(result.data, &len, next_key);
200 svn_fs_base__trail_debug(trail, "checksum_reps", "put");
201 db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
202 svn_fs_base__str_to_dbt(&query,
204 svn_fs_base__str_to_dbt(&result, next_key),
207 return BDB_WRAP(fs, N_("bumping next representation reuse ID"), db_err);