1251881Speter/* lock-tokens-table.c : operations on the `lock-tokens' 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#include <assert.h> 25251881Speter 26251881Speter#include "bdb_compat.h" 27251881Speter 28251881Speter#include "svn_pools.h" 29251881Speter#include "private/svn_skel.h" 30251881Speter 31251881Speter#include "dbt.h" 32251881Speter#include "../err.h" 33251881Speter#include "../fs.h" 34251881Speter#include "../util/fs_skels.h" 35251881Speter#include "../trail.h" 36251881Speter#include "../../libsvn_fs/fs-loader.h" 37251881Speter#include "bdb-err.h" 38251881Speter#include "lock-tokens-table.h" 39251881Speter#include "locks-table.h" 40251881Speter 41251881Speter#include "private/svn_fs_util.h" 42251881Speter 43251881Speter 44251881Speterint 45251881Spetersvn_fs_bdb__open_lock_tokens_table(DB **lock_tokens_p, 46251881Speter DB_ENV *env, 47251881Speter svn_boolean_t create) 48251881Speter{ 49251881Speter const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0); 50251881Speter DB *lock_tokens; 51251881Speter int error; 52251881Speter 53251881Speter BDB_ERR(svn_fs_bdb__check_version()); 54251881Speter BDB_ERR(db_create(&lock_tokens, env, 0)); 55251881Speter error = (lock_tokens->open)(SVN_BDB_OPEN_PARAMS(lock_tokens, NULL), 56251881Speter "lock-tokens", 0, DB_BTREE, 57251881Speter open_flags, 0666); 58251881Speter 59251881Speter /* Create the table if it doesn't yet exist. This is a form of 60251881Speter automagical repository upgrading. */ 61251881Speter if (error == ENOENT && (! create)) 62251881Speter { 63251881Speter BDB_ERR(lock_tokens->close(lock_tokens, 0)); 64251881Speter return svn_fs_bdb__open_lock_tokens_table(lock_tokens_p, env, TRUE); 65251881Speter } 66251881Speter BDB_ERR(error); 67251881Speter 68251881Speter *lock_tokens_p = lock_tokens; 69251881Speter return 0; 70251881Speter} 71251881Speter 72251881Speter 73251881Spetersvn_error_t * 74251881Spetersvn_fs_bdb__lock_token_add(svn_fs_t *fs, 75251881Speter const char *path, 76251881Speter const char *lock_token, 77251881Speter trail_t *trail, 78251881Speter apr_pool_t *pool) 79251881Speter{ 80251881Speter 81251881Speter base_fs_data_t *bfd = fs->fsap_data; 82251881Speter DBT key, value; 83251881Speter 84251881Speter svn_fs_base__str_to_dbt(&key, path); 85251881Speter svn_fs_base__str_to_dbt(&value, lock_token); 86251881Speter svn_fs_base__trail_debug(trail, "lock-tokens", "add"); 87251881Speter return BDB_WRAP(fs, N_("storing lock token record"), 88251881Speter bfd->lock_tokens->put(bfd->lock_tokens, trail->db_txn, 89251881Speter &key, &value, 0)); 90251881Speter} 91251881Speter 92251881Speter 93251881Spetersvn_error_t * 94251881Spetersvn_fs_bdb__lock_token_delete(svn_fs_t *fs, 95251881Speter const char *path, 96251881Speter trail_t *trail, 97251881Speter apr_pool_t *pool) 98251881Speter{ 99251881Speter base_fs_data_t *bfd = fs->fsap_data; 100251881Speter DBT key; 101251881Speter int db_err; 102251881Speter 103251881Speter svn_fs_base__str_to_dbt(&key, path); 104251881Speter svn_fs_base__trail_debug(trail, "lock-tokens", "del"); 105251881Speter db_err = bfd->lock_tokens->del(bfd->lock_tokens, trail->db_txn, &key, 0); 106251881Speter if (db_err == DB_NOTFOUND) 107251881Speter return SVN_FS__ERR_NO_SUCH_LOCK(fs, path); 108251881Speter return BDB_WRAP(fs, N_("deleting entry from 'lock-tokens' table"), db_err); 109251881Speter} 110251881Speter 111251881Speter 112251881Spetersvn_error_t * 113251881Spetersvn_fs_bdb__lock_token_get(const char **lock_token_p, 114251881Speter svn_fs_t *fs, 115251881Speter const char *path, 116251881Speter trail_t *trail, 117251881Speter apr_pool_t *pool) 118251881Speter{ 119251881Speter base_fs_data_t *bfd = fs->fsap_data; 120251881Speter DBT key, value; 121251881Speter svn_error_t *err; 122251881Speter svn_lock_t *lock; 123251881Speter const char *lock_token; 124251881Speter int db_err; 125251881Speter 126251881Speter svn_fs_base__trail_debug(trail, "lock-tokens", "get"); 127251881Speter db_err = bfd->lock_tokens->get(bfd->lock_tokens, trail->db_txn, 128251881Speter svn_fs_base__str_to_dbt(&key, path), 129251881Speter svn_fs_base__result_dbt(&value), 130251881Speter 0); 131251881Speter svn_fs_base__track_dbt(&value, pool); 132251881Speter 133251881Speter if (db_err == DB_NOTFOUND) 134251881Speter return SVN_FS__ERR_NO_SUCH_LOCK(fs, path); 135251881Speter SVN_ERR(BDB_WRAP(fs, N_("reading lock token"), db_err)); 136251881Speter 137251881Speter lock_token = apr_pstrmemdup(pool, value.data, value.size); 138251881Speter 139251881Speter /* Make sure the token still points to an existing, non-expired 140251881Speter lock, by doing a lookup in the `locks' table. */ 141251881Speter err = svn_fs_bdb__lock_get(&lock, fs, lock_token, trail, pool); 142251881Speter if (err && ((err->apr_err == SVN_ERR_FS_LOCK_EXPIRED) 143251881Speter || (err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN))) 144251881Speter { 145251881Speter /* If `locks' doesn't have the lock, then we should lose it too. */ 146251881Speter svn_error_t *delete_err; 147251881Speter delete_err = svn_fs_bdb__lock_token_delete(fs, path, trail, pool); 148251881Speter if (delete_err) 149251881Speter svn_error_compose(err, delete_err); 150251881Speter return svn_error_trace(err); 151251881Speter } 152251881Speter else if (err) 153251881Speter return svn_error_trace(err); 154251881Speter 155251881Speter *lock_token_p = lock_token; 156251881Speter return SVN_NO_ERROR; 157251881Speter} 158