/* Body of svn_fs_fs__open_rep_cache().
   Implements svn_atomic__init_once().init_func.
 */
static svn_error_t *
open_rep_cache(void *baton,
               apr_pool_t *pool)
{
  svn_fs_t *fs = baton;
  fs_fs_data_t *ffd = fs->fsap_data;
  const char *db_path;
  int version;

  /* Open (or create) the sqlite database.  It will be automatically
     closed when fs->pool is destoyed. */
  db_path = path_rep_cache_db(fs->path, pool);
  SVN_ERR(svn_sqlite__open(&ffd->rep_cache_db, db_path,
                           svn_sqlite__mode_rwcreate, statements,
                           0, NULL,
                           fs->pool, pool));

  SVN_ERR(svn_sqlite__read_schema_version(&version, ffd->rep_cache_db, pool));
  if (version < REP_CACHE_SCHEMA_FORMAT)
    {
      /* Must be 0 -- an uninitialized (no schema) database. Create
         the schema. Results in schema version of 1.  */
      SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db,
                                          STMT_CREATE_SCHEMA));
    }

  return SVN_NO_ERROR;
}
Exemple #2
0
/* Check the schema format of the database, upgrading it if necessary.
   Return SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA if the schema format is too new,
   or SVN_ERR_SQLITE_ERROR if an sqlite error occurs during validation.
   Return SVN_NO_ERROR if everything is okay. */
static svn_error_t *
check_format(svn_sqlite__db_t *db,
             int latest_schema,
             const char * const *upgrade_sql,
             apr_pool_t *scratch_pool)
{
  int current_schema;

  /* Validate that the schema exists as expected. */
  SVN_ERR(svn_sqlite__read_schema_version(&current_schema, db, scratch_pool));

  if (current_schema == latest_schema)
    return SVN_NO_ERROR;

  if (current_schema < latest_schema)
    {
      struct upgrade_baton ub;

      ub.current_schema = current_schema;
      ub.latest_schema = latest_schema;
      ub.upgrade_sql = upgrade_sql;

      return svn_error_trace(svn_sqlite__with_transaction(
                               db, upgrade_format, &ub, scratch_pool));
    }

  return svn_error_createf(SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA, NULL,
                           _("Schema format %d not recognized"),
                           current_schema);
}
Exemple #3
0
/* Body of svn_fs_fs__open_rep_cache().
   Implements svn_atomic__init_once().init_func.
 */
static svn_error_t *
open_rep_cache(void *baton,
               apr_pool_t *pool)
{
  svn_fs_t *fs = baton;
  fs_fs_data_t *ffd = fs->fsap_data;
  svn_sqlite__db_t *sdb;
  const char *db_path;
  int version;

  /* Open (or create) the sqlite database.  It will be automatically
     closed when fs->pool is destroyed. */
  db_path = path_rep_cache_db(fs->path, pool);
#ifndef WIN32
  {
    /* We want to extend the permissions that apply to the repository
       as a whole when creating a new rep cache and not simply default
       to umask. */
    svn_boolean_t exists;

    SVN_ERR(svn_fs_fs__exists_rep_cache(&exists, fs, pool));
    if (!exists)
      {
        const char *current = svn_fs_fs__path_current(fs, pool);
        svn_error_t *err = svn_io_file_create_empty(db_path, pool);

        if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
          /* A real error. */
          return svn_error_trace(err);
        else if (err)
          /* Some other thread/process created the file. */
          svn_error_clear(err);
        else
          /* We created the file. */
          SVN_ERR(svn_io_copy_perms(current, db_path, pool));
      }
  }
#endif
  SVN_ERR(svn_sqlite__open(&sdb, db_path,
                           svn_sqlite__mode_rwcreate, statements,
                           0, NULL, 0,
                           fs->pool, pool));

  SVN_ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb, pool), sdb);
  if (version < REP_CACHE_SCHEMA_FORMAT)
    {
      /* Must be 0 -- an uninitialized (no schema) database. Create
         the schema. Results in schema version of 1.  */
      SVN_ERR_CLOSE(svn_sqlite__exec_statements(sdb, STMT_CREATE_SCHEMA), sdb);
    }

  /* This is used as a flag that the database is available so don't
     set it earlier. */
  ffd->rep_cache_db = sdb;

  return SVN_NO_ERROR;
}
Exemple #4
0
svn_error_t *
svn_sqlite__get_schema_version(int *version,
                               const char *path,
                               apr_pool_t *scratch_pool)
{
  svn_sqlite__db_t db;

  SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
                                init_sqlite, NULL, scratch_pool));
  SVN_ERR(internal_open(&db.db3, path, svn_sqlite__mode_readonly,
                        scratch_pool));
  SVN_ERR(svn_sqlite__read_schema_version(version, &db, scratch_pool));
  SQLITE_ERR(sqlite3_close(db.db3), &db);

  return SVN_NO_ERROR;
}
Exemple #5
0
/* Sqlite transaction helper for opening the db in
   svn_wc__db_wcroot_parse_local_abspath() to avoid multiple
   db operations that each obtain and release a lock */
static svn_error_t *
fetch_sdb_info(apr_int64_t *wc_id,
               int *format,
               svn_sqlite__db_t *sdb,
               apr_pool_t *scratch_pool)
{
  *wc_id = -1;
  *format = -1;

  SVN_SQLITE__WITH_LOCK4(
        svn_wc__db_util_fetch_wc_id(wc_id, sdb, scratch_pool),
        svn_sqlite__read_schema_version(format, sdb, scratch_pool),
        verify_stats_table(sdb, *format, scratch_pool),
        SVN_NO_ERROR,
        sdb);

  return SVN_NO_ERROR;
}
Exemple #6
0
svn_error_t *
svn_wc__db_pdh_create_wcroot(svn_wc__db_wcroot_t **wcroot,
                             const char *wcroot_abspath,
                             svn_sqlite__db_t *sdb,
                             apr_int64_t wc_id,
                             int format,
                             svn_boolean_t verify_format,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  if (sdb && format == FORMAT_FROM_SDB)
    SVN_ERR(svn_sqlite__read_schema_version(&format, sdb, scratch_pool));

  /* If we construct a wcroot, then we better have a format.  */
  SVN_ERR_ASSERT(format >= 1);

  /* If this working copy is PRE-1.0, then simply bail out.  */
  if (format < 4)
    {
      return svn_error_createf(
        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
        _("Working copy format of '%s' is too old (%d); "
          "please check out your working copy again"),
        svn_dirent_local_style(wcroot_abspath, scratch_pool), format);
    }

  /* If this working copy is from a future version, then bail out.  */
  if (format > SVN_WC__VERSION)
    {
      return svn_error_createf(
        SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
        _("This client is too old to work with the working copy at\n"
          "'%s' (format %d).\n"
          "You need to get a newer Subversion client. For more details, see\n"
          "  http://subversion.apache.org/faq.html#working-copy-format-change\n"
          ),
        svn_dirent_local_style(wcroot_abspath, scratch_pool),
        format);
    }

  /* Verify that no work items exists. If they do, then our integrity is
     suspect and, thus, we cannot upgrade this database.  */
  if (format >= SVN_WC__HAS_WORK_QUEUE &&
      format < SVN_WC__VERSION && verify_format)
    {
      svn_error_t *err = svn_wc__db_verify_no_work(sdb);
      if (err)
        {
          /* Special message for attempts to upgrade a 1.7-dev wc with
             outstanding workqueue items. */
          if (err->apr_err == SVN_ERR_WC_CLEANUP_REQUIRED
              && format < SVN_WC__VERSION && verify_format)
            err = svn_error_quick_wrap(err, _("Cleanup with an older 1.7 "
                                              "client before upgrading with "
                                              "this client"));
          return svn_error_trace(err);
        }
    }

  /* Auto-upgrade the SDB if possible.  */
  if (format < SVN_WC__VERSION && verify_format)
    {
      return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
                               _("The working copy at '%s'\nis too old "
                                 "(format %d) to work with client version "
                                 "'%s' (expects format %d). You need to "
                                 "upgrade the working copy first.\n"),
                               svn_dirent_local_style(wcroot_abspath,
                                                      scratch_pool),
                               format, SVN_VERSION, SVN_WC__VERSION);
    }

  *wcroot = apr_palloc(result_pool, sizeof(**wcroot));

  (*wcroot)->abspath = wcroot_abspath;
  (*wcroot)->sdb = sdb;
  (*wcroot)->wc_id = wc_id;
  (*wcroot)->format = format;
  /* 8 concurrent locks is probably more than a typical wc_ng based svn client
     uses. */
  (*wcroot)->owned_locks = apr_array_make(result_pool, 8,
                                          sizeof(svn_wc__db_wclock_t));
  (*wcroot)->access_cache = apr_hash_make(result_pool);

  /* SDB will be NULL for pre-NG working copies. We only need to run a
     cleanup when the SDB is present.  */
  if (sdb != NULL)
    apr_pool_cleanup_register(result_pool, *wcroot, close_wcroot,
                              apr_pool_cleanup_null);
  return SVN_NO_ERROR;
}