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(&copy_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, 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(&copy, skel, pool));
208251881Speter  *copy_p = copy;
209251881Speter  return SVN_NO_ERROR;
210251881Speter}
211