1251881Speter/* 2251881Speter * wc_db_util.c : Various util functions for wc_db(_pdh) 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter/* About this file: 25251881Speter This file is meant to be a stash of fairly low-level functions used by both 26251881Speter wc_db.c and wc_db_pdh.c. In breaking stuff out of the monolithic wc_db.c, 27251881Speter I have discovered that some utility functions are used by bits in both 28251881Speter files. Rather than shoehorn those functions into one file or the other, or 29251881Speter create circular dependencies between the files, I felt a third file, with 30251881Speter a well-defined scope, would be sensible. History will judge its effect. 31251881Speter 32251881Speter The goal of it file is simple: just execute SQLite statements. That is, 33251881Speter functions in this file should have no knowledge of pdh's or db's, and 34251881Speter should just operate on the raw sdb object. If a function requires more 35251881Speter information than that, it shouldn't be in here. -hkw 36251881Speter */ 37251881Speter 38251881Speter#define SVN_WC__I_AM_WC_DB 39251881Speter 40251881Speter#include "svn_dirent_uri.h" 41251881Speter#include "private/svn_sqlite.h" 42251881Speter 43251881Speter#include "wc.h" 44251881Speter#include "adm_files.h" 45251881Speter#include "wc_db_private.h" 46251881Speter#include "wc-queries.h" 47251881Speter 48251881Speter#include "svn_private_config.h" 49251881Speter 50251881SpeterWC_QUERIES_SQL_DECLARE_STATEMENTS(statements); 51251881Speter 52251881Speter 53251881Speter 54251881Speter/* */ 55251881Spetersvn_error_t * 56251881Spetersvn_wc__db_util_fetch_wc_id(apr_int64_t *wc_id, 57251881Speter svn_sqlite__db_t *sdb, 58251881Speter apr_pool_t *scratch_pool) 59251881Speter{ 60251881Speter svn_sqlite__stmt_t *stmt; 61251881Speter svn_boolean_t have_row; 62251881Speter 63251881Speter /* ### cheat. we know there is just one WORKING_COPY row, and it has a 64251881Speter ### NULL value for local_abspath. */ 65251881Speter SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WCROOT_NULL)); 66251881Speter SVN_ERR(svn_sqlite__step(&have_row, stmt)); 67251881Speter if (!have_row) 68251881Speter return svn_error_createf(SVN_ERR_WC_CORRUPT, svn_sqlite__reset(stmt), 69251881Speter _("Missing a row in WCROOT.")); 70251881Speter 71251881Speter SVN_ERR_ASSERT(!svn_sqlite__column_is_null(stmt, 0)); 72251881Speter *wc_id = svn_sqlite__column_int64(stmt, 0); 73251881Speter 74251881Speter return svn_error_trace(svn_sqlite__reset(stmt)); 75251881Speter} 76251881Speter 77251881Speter 78251881Speter 79251881Speter 80251881Speter/* An SQLite application defined function that allows SQL queries to 81251881Speter use "relpath_depth(local_relpath)". */ 82251881Speterstatic svn_error_t * 83251881Speterrelpath_depth_sqlite(svn_sqlite__context_t *sctx, 84251881Speter int argc, 85251881Speter svn_sqlite__value_t *values[], 86299742Sdim void *baton) 87251881Speter{ 88251881Speter const char *path = NULL; 89251881Speter apr_int64_t depth; 90251881Speter 91251881Speter if (argc == 1 && svn_sqlite__value_type(values[0]) == SVN_SQLITE__TEXT) 92251881Speter path = svn_sqlite__value_text(values[0]); 93251881Speter if (!path) 94251881Speter { 95251881Speter svn_sqlite__result_null(sctx); 96251881Speter return SVN_NO_ERROR; 97251881Speter } 98251881Speter 99251881Speter depth = *path ? 1 : 0; 100251881Speter while (*path) 101251881Speter { 102251881Speter if (*path == '/') 103251881Speter ++depth; 104251881Speter ++path; 105251881Speter } 106251881Speter svn_sqlite__result_int64(sctx, depth); 107251881Speter 108251881Speter return SVN_NO_ERROR; 109251881Speter} 110251881Speter 111251881Speter 112251881Spetersvn_error_t * 113251881Spetersvn_wc__db_util_open_db(svn_sqlite__db_t **sdb, 114251881Speter const char *dir_abspath, 115251881Speter const char *sdb_fname, 116251881Speter svn_sqlite__mode_t smode, 117251881Speter svn_boolean_t exclusive, 118299742Sdim apr_int32_t timeout, 119251881Speter const char *const *my_statements, 120251881Speter apr_pool_t *result_pool, 121251881Speter apr_pool_t *scratch_pool) 122251881Speter{ 123251881Speter const char *sdb_abspath = svn_wc__adm_child(dir_abspath, sdb_fname, 124251881Speter scratch_pool); 125251881Speter 126251881Speter if (smode != svn_sqlite__mode_rwcreate) 127251881Speter { 128251881Speter svn_node_kind_t kind; 129251881Speter 130251881Speter /* A file stat is much cheaper then a failed database open handled 131251881Speter by SQLite. */ 132251881Speter SVN_ERR(svn_io_check_path(sdb_abspath, &kind, scratch_pool)); 133251881Speter 134251881Speter if (kind != svn_node_file) 135251881Speter return svn_error_createf(APR_ENOENT, NULL, 136251881Speter _("Working copy database '%s' not found"), 137251881Speter svn_dirent_local_style(sdb_abspath, 138251881Speter scratch_pool)); 139251881Speter } 140251881Speter 141251881Speter SVN_ERR(svn_sqlite__open(sdb, sdb_abspath, smode, 142251881Speter my_statements ? my_statements : statements, 143299742Sdim 0, NULL, timeout, result_pool, scratch_pool)); 144251881Speter 145251881Speter if (exclusive) 146251881Speter SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_PRAGMA_LOCKING_MODE)); 147251881Speter 148251881Speter SVN_ERR(svn_sqlite__create_scalar_function(*sdb, "relpath_depth", 1, 149299742Sdim TRUE /* deterministic */, 150251881Speter relpath_depth_sqlite, NULL)); 151251881Speter 152251881Speter return SVN_NO_ERROR; 153251881Speter} 154251881Speter 155