Fix compiler warning due to missing function prototype.
[svn.git] / subversion / libsvn_fs_base / bdb / nodes-table.c
blobd898296bf8793bdf316fe26153ea405ebcd88166
1 /* nodes-table.c : working with the `nodes' table
3 * ====================================================================
4 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
18 #include <string.h>
19 #include <assert.h>
20 #include "bdb_compat.h"
22 #include "svn_fs.h"
24 #include "../fs.h"
25 #include "../err.h"
26 #include "dbt.h"
27 #include "../util/skel.h"
28 #include "../util/fs_skels.h"
29 #include "../trail.h"
30 #include "../key-gen.h"
31 #include "../id.h"
32 #include "../../libsvn_fs/fs-loader.h"
33 #include "bdb-err.h"
34 #include "nodes-table.h"
37 #include "svn_private_config.h"
40 /* Opening/creating the `nodes' table. */
43 int
44 svn_fs_bdb__open_nodes_table(DB **nodes_p,
45 DB_ENV *env,
46 svn_boolean_t create)
48 const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
49 DB *nodes;
51 BDB_ERR(svn_fs_bdb__check_version());
52 BDB_ERR(db_create(&nodes, env, 0));
53 BDB_ERR((nodes->open)(SVN_BDB_OPEN_PARAMS(nodes, NULL),
54 "nodes", 0, DB_BTREE,
55 open_flags, 0666));
57 /* Create the `next-key' table entry (use '1' because '0' is
58 reserved for the root directory to use). */
59 if (create)
61 DBT key, value;
63 BDB_ERR(nodes->put(nodes, 0,
64 svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
65 svn_fs_base__str_to_dbt(&value, "1"), 0));
68 *nodes_p = nodes;
69 return 0;
74 /* Choosing node revision ID's. */
76 svn_error_t *
77 svn_fs_bdb__new_node_id(svn_fs_id_t **id_p,
78 svn_fs_t *fs,
79 const char *copy_id,
80 const char *txn_id,
81 trail_t *trail,
82 apr_pool_t *pool)
84 base_fs_data_t *bfd = fs->fsap_data;
85 DBT query, result;
86 apr_size_t len;
87 char next_key[MAX_KEY_SIZE];
88 int db_err;
89 const char *next_node_id;
91 /* TXN_ID is required! */
92 assert(txn_id);
94 /* Get the current value associated with the `next-key' key in the table. */
95 svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
96 svn_fs_base__trail_debug(trail, "nodes", "get");
97 SVN_ERR(BDB_WRAP(fs, _("allocating new node ID (getting 'next-key')"),
98 bfd->nodes->get(bfd->nodes, trail->db_txn,
99 &query,
100 svn_fs_base__result_dbt(&result),
101 0)));
102 svn_fs_base__track_dbt(&result, pool);
104 /* Squirrel away our next node id value. */
105 next_node_id = apr_pstrmemdup(pool, result.data, result.size);
107 /* Bump to future key. */
108 len = result.size;
109 svn_fs_base__next_key(result.data, &len, next_key);
110 svn_fs_base__trail_debug(trail, "nodes", "put");
111 db_err = bfd->nodes->put(bfd->nodes, trail->db_txn,
112 svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
113 svn_fs_base__str_to_dbt(&result, next_key),
115 SVN_ERR(BDB_WRAP(fs, _("bumping next node ID key"), db_err));
117 /* Create and return the new node id. */
118 *id_p = svn_fs_base__id_create(next_node_id, copy_id, txn_id, pool);
119 return SVN_NO_ERROR;
123 svn_error_t *
124 svn_fs_bdb__new_successor_id(svn_fs_id_t **successor_p,
125 svn_fs_t *fs,
126 const svn_fs_id_t *id,
127 const char *copy_id,
128 const char *txn_id,
129 trail_t *trail,
130 apr_pool_t *pool)
132 svn_fs_id_t *new_id;
133 svn_error_t *err;
135 /* TXN_ID is required! */
136 assert(txn_id);
138 /* Create and return the new successor ID. */
139 new_id = svn_fs_base__id_create(svn_fs_base__id_node_id(id),
140 copy_id ? copy_id
141 : svn_fs_base__id_copy_id(id),
142 txn_id, pool);
144 /* Now, make sure this NEW_ID doesn't already exist in FS. */
145 err = svn_fs_bdb__get_node_revision(NULL, fs, new_id, trail, trail->pool);
146 if ((! err) || (err->apr_err != SVN_ERR_FS_ID_NOT_FOUND))
148 svn_string_t *id_str = svn_fs_base__id_unparse(id, pool);
149 svn_string_t *new_id_str = svn_fs_base__id_unparse(new_id, pool);
150 return svn_error_createf
151 (SVN_ERR_FS_ALREADY_EXISTS, err,
152 _("Successor id '%s' (for '%s') already exists in filesystem '%s'"),
153 new_id_str->data, id_str->data, fs->path);
156 /* err is SVN_ERR_FS_ID_NOT_FOUND, meaning the ID is available. But
157 we don't want this error. */
158 svn_error_clear(err);
160 /* Return the new node revision ID. */
161 *successor_p = new_id;
162 return SVN_NO_ERROR;
167 /* Removing node revisions. */
168 svn_error_t *
169 svn_fs_bdb__delete_nodes_entry(svn_fs_t *fs,
170 const svn_fs_id_t *id,
171 trail_t *trail,
172 apr_pool_t *pool)
174 base_fs_data_t *bfd = fs->fsap_data;
175 DBT key;
177 svn_fs_base__trail_debug(trail, "nodes", "del");
178 SVN_ERR(BDB_WRAP(fs, _("deleting entry from 'nodes' table"),
179 bfd->nodes->del(bfd->nodes,
180 trail->db_txn,
181 svn_fs_base__id_to_dbt(&key, id, pool),
182 0)));
184 return SVN_NO_ERROR;
190 /* Storing and retrieving NODE-REVISIONs. */
193 svn_error_t *
194 svn_fs_bdb__get_node_revision(node_revision_t **noderev_p,
195 svn_fs_t *fs,
196 const svn_fs_id_t *id,
197 trail_t *trail,
198 apr_pool_t *pool)
200 base_fs_data_t *bfd = fs->fsap_data;
201 node_revision_t *noderev;
202 skel_t *skel;
203 int db_err;
204 DBT key, value;
206 svn_fs_base__trail_debug(trail, "nodes", "get");
207 db_err = bfd->nodes->get(bfd->nodes, trail->db_txn,
208 svn_fs_base__id_to_dbt(&key, id, pool),
209 svn_fs_base__result_dbt(&value),
211 svn_fs_base__track_dbt(&value, pool);
213 /* If there's no such node, return an appropriately specific error. */
214 if (db_err == DB_NOTFOUND)
215 return svn_fs_base__err_dangling_id(fs, id);
217 /* Handle any other error conditions. */
218 SVN_ERR(BDB_WRAP(fs, _("reading node revision"), db_err));
220 /* If our caller doesn't really care about the return value here,
221 just return successfully. */
222 if (! noderev_p)
223 return SVN_NO_ERROR;
225 /* Parse and the NODE-REVISION skel. */
226 skel = svn_fs_base__parse_skel(value.data, value.size, pool);
228 /* Convert to a native FS type. */
229 SVN_ERR(svn_fs_base__parse_node_revision_skel(&noderev, skel, pool));
230 *noderev_p = noderev;
231 return SVN_NO_ERROR;
235 svn_error_t *
236 svn_fs_bdb__put_node_revision(svn_fs_t *fs,
237 const svn_fs_id_t *id,
238 node_revision_t *noderev,
239 trail_t *trail,
240 apr_pool_t *pool)
242 base_fs_data_t *bfd = fs->fsap_data;
243 DB_TXN *db_txn = trail->db_txn;
244 DBT key, value;
245 skel_t *skel;
247 /* Convert from native type into skel */
248 SVN_ERR(svn_fs_base__unparse_node_revision_skel(&skel, noderev,
249 bfd->format, pool));
250 svn_fs_base__trail_debug(trail, "nodes", "put");
251 return BDB_WRAP(fs, _("storing node revision"),
252 bfd->nodes->put(bfd->nodes, db_txn,
253 svn_fs_base__id_to_dbt(&key, id, pool),
254 svn_fs_base__skel_to_dbt(&value, skel,
255 pool),
256 0));