]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/libsvn_fs_base/bdb/reps-table.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / subversion / subversion / libsvn_fs_base / bdb / reps-table.c
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 \f
40 /*** Creating and opening the representations table. ***/
41
42 int
43 svn_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 \f
73 /*** Storing and retrieving reps.  ***/
74
75 svn_error_t *
76 svn_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
111 svn_error_t *
112 svn_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
137 svn_error_t *
138 svn_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
181 svn_error_t *
182 svn_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 }