int
svn_fs_bdb__open_reps_table(DB **reps_p,
                            DB_ENV *env,
                            svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *reps;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&reps, env, 0));
  BDB_ERR((reps->open)(SVN_BDB_OPEN_PARAMS(reps, NULL),
                       "representations", 0, DB_BTREE,
                       open_flags, 0666));

  /* Create the `next-key' table entry.  */
  if (create)
  {
    DBT key, value;

    BDB_ERR(reps->put
            (reps, 0,
             svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
             svn_fs_base__str_to_dbt(&value, "0"), 0));
  }

  *reps_p = reps;
  return 0;
}
예제 #2
0
int
svn_fs_bdb__open_nodes_table(DB **nodes_p,
                             DB_ENV *env,
                             svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *nodes;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&nodes, env, 0));
  BDB_ERR((nodes->open)(SVN_BDB_OPEN_PARAMS(nodes, NULL),
                        "nodes", 0, DB_BTREE,
                        open_flags, 0666));

  /* Create the `next-key' table entry (use '1' because '0' is
     reserved for the root directory to use). */
  if (create)
  {
    DBT key, value;

    BDB_ERR(nodes->put(nodes, 0,
                       svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
                       svn_fs_base__str_to_dbt(&value, "1"), 0));
  }

  *nodes_p = nodes;
  return 0;
}
예제 #3
0
int svn_fs_bdb__open_checksum_reps_table(DB **checksum_reps_p,
                                         DB_ENV *env,
                                         svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *checksum_reps;
  int error;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&checksum_reps, env, 0));
  error = (checksum_reps->open)(SVN_BDB_OPEN_PARAMS(checksum_reps, NULL),
                                "checksum-reps", 0, DB_BTREE,
                                open_flags, 0666);

  /* Create the checksum-reps table if it doesn't exist. */
  if (error == ENOENT && (! create))
    {
      BDB_ERR(checksum_reps->close(checksum_reps, 0));
      return svn_fs_bdb__open_checksum_reps_table(checksum_reps_p, env, TRUE);
    }

  /* Create the initial `next-key' table entry.  */
  if (create)
    {
      DBT key, value;
      BDB_ERR(checksum_reps->put(checksum_reps, 0,
                                 svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
                                 svn_fs_base__str_to_dbt(&value, "0"), 0));
    }

  BDB_ERR(error);

  *checksum_reps_p = checksum_reps;
  return 0;
}
예제 #4
0
/* Get the current 'next-key' value and bump the record. */
static svn_error_t *
get_key_and_bump(svn_fs_t *fs,
                 const char **key,
                 trail_t *trail,
                 apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBC *cursor;
    char next_key[MAX_KEY_SIZE];
    apr_size_t key_len;
    int db_err;
    DBT query;
    DBT result;

    /* ### todo: see issue #409 for why bumping the key as part of this
       trail is problematic. */

    /* Open a cursor and move it to the 'next-key' value. We can then fetch
       the contents and use the cursor to overwrite those contents. Since
       this database allows duplicates, we can't do an arbitrary 'put' to
       write the new value -- that would append, not overwrite.  */

    svn_fs_base__trail_debug(trail, "strings", "cursor");
    SVN_ERR(BDB_WRAP(fs, N_("creating cursor for reading a string"),
                     bfd->strings->cursor(bfd->strings, trail->db_txn,
                                          &cursor, 0)));

    /* Advance the cursor to 'next-key' and read it. */

    db_err = svn_bdb_dbc_get(cursor,
                             svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
                             svn_fs_base__result_dbt(&result),
                             DB_SET);
    if (db_err)
    {
        svn_bdb_dbc_close(cursor);
        return BDB_WRAP(fs, N_("getting next-key value"), db_err);
    }

    svn_fs_base__track_dbt(&result, pool);
    *key = apr_pstrmemdup(pool, result.data, result.size);

    /* Bump to future key. */
    key_len = result.size;
    svn_fs_base__next_key(result.data, &key_len, next_key);

    /* Shove the new key back into the database, at the cursor position. */
    db_err = svn_bdb_dbc_put(cursor, &query,
                             svn_fs_base__str_to_dbt(&result, next_key),
                             DB_CURRENT);
    if (db_err)
    {
        svn_bdb_dbc_close(cursor); /* ignore the error, the original is
                                    more important. */
        return BDB_WRAP(fs, N_("bumping next string key"), db_err);
    }

    return BDB_WRAP(fs, N_("closing string-reading cursor"),
                    svn_bdb_dbc_close(cursor));
}
예제 #5
0
int
svn_fs_bdb__open_strings_table(DB **strings_p,
                               DB_ENV *env,
                               svn_boolean_t create)
{
    const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
    DB *strings;

    BDB_ERR(svn_fs_bdb__check_version());
    BDB_ERR(db_create(&strings, env, 0));

    /* Enable duplicate keys. This allows the data to be spread out across
       multiple records. Note: this must occur before ->open().  */
    BDB_ERR(strings->set_flags(strings, DB_DUP));

    BDB_ERR((strings->open)(SVN_BDB_OPEN_PARAMS(strings, NULL),
                            "strings", 0, DB_BTREE,
                            open_flags, 0666));

    if (create)
    {
        DBT key, value;

        /* Create the `next-key' table entry.  */
        BDB_ERR(strings->put
                (strings, 0,
                 svn_fs_base__str_to_dbt(&key, NEXT_KEY_KEY),
                 svn_fs_base__str_to_dbt(&value, "0"), 0));
    }

    *strings_p = strings;
    return 0;
}
예제 #6
0
svn_error_t *
svn_fs_bdb__miscellaneous_set(svn_fs_t *fs,
                              const char *key_str,
                              const char *val,
                              trail_t *trail,
                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;

  svn_fs_base__str_to_dbt(&key, key_str);
  if (val == NULL)
    {
      svn_fs_base__trail_debug(trail, "miscellaneous", "del");
      return BDB_WRAP(fs, N_("deleting record from 'miscellaneous' table"),
                      bfd->miscellaneous->del(bfd->miscellaneous,
                                              trail->db_txn, &key, 0));
    }
  else
    {
      svn_fs_base__str_to_dbt(&value, val);
      svn_fs_base__trail_debug(trail, "miscellaneous", "add");
      return BDB_WRAP(fs, N_("storing miscellaneous record"),
                      bfd->miscellaneous->put(bfd->miscellaneous,
                                              trail->db_txn,
                                              &key, &value, 0));
    }
}
예제 #7
0
파일: reps-table.c 프로젝트: vocho/openqnx
svn_error_t *
svn_fs_bdb__delete_rep(svn_fs_t *fs,
                       const char *key,
                       trail_t *trail,
                       apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  int db_err;
  DBT query;

  svn_fs_base__trail_debug(trail, "representations", "del");
  db_err = bfd->representations->del
    (bfd->representations, trail->db_txn,
     svn_fs_base__str_to_dbt(&query, key), 0);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
    return svn_error_createf
      (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0,
       _("No such representation '%s'"), key);

  /* Handle any other error conditions.  */
  SVN_ERR(BDB_WRAP(fs, _("deleting representation"), db_err));

  return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_bdb__read_rep(representation_t **rep_p,
                     svn_fs_t *fs,
                     const char *key,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *skel;
  int db_err;
  DBT query, result;

  svn_fs_base__trail_debug(trail, "representations", "get");
  db_err = bfd->representations->get(bfd->representations,
                                     trail->db_txn,
                                     svn_fs_base__str_to_dbt(&query, key),
                                     svn_fs_base__result_dbt(&result), 0);
  svn_fs_base__track_dbt(&result, pool);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
    return svn_error_createf
      (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0,
       _("No such representation '%s'"), key);

  /* Handle any other error conditions.  */
  SVN_ERR(BDB_WRAP(fs, _("reading representation"), db_err));

  /* Parse the REPRESENTATION skel.  */
  skel = svn_skel__parse(result.data, result.size, pool);

  /* Convert to a native type.  */
  return svn_fs_base__parse_representation_skel(rep_p, skel, pool);
}
예제 #9
0
파일: reps-table.c 프로젝트: vocho/openqnx
svn_error_t *
svn_fs_bdb__write_rep(svn_fs_t *fs,
                      const char *key,
                      const representation_t *rep,
                      trail_t *trail,
                      apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  skel_t *skel;

  /* Convert from native type to skel. */
  SVN_ERR(svn_fs_base__unparse_representation_skel(&skel, rep, pool));

  /* Now write the record. */
  svn_fs_base__trail_debug(trail, "representations", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing representation"),
                   bfd->representations->put
                   (bfd->representations, trail->db_txn,
                    svn_fs_base__str_to_dbt(&query, key),
                    svn_fs_base__skel_to_dbt(&result, skel, pool),
                    0)));

  return SVN_NO_ERROR;
}
예제 #10
0
svn_error_t *
svn_fs_bdb__miscellaneous_get(const char **val,
                              svn_fs_t *fs,
                              const char *key_str,
                              trail_t *trail,
                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  *val = NULL;
  svn_fs_base__trail_debug(trail, "miscellaneous", "get");
  db_err = bfd->miscellaneous->get(bfd->miscellaneous, trail->db_txn,
                                   svn_fs_base__str_to_dbt(&key, key_str),
                                   svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);

  if (db_err != DB_NOTFOUND)
    {
      SVN_ERR(BDB_WRAP(fs, N_("fetching miscellaneous record"), db_err));
      *val = apr_pstrmemdup(pool, value.data, value.size);
    }
  return SVN_NO_ERROR;
}
예제 #11
0
svn_error_t *
svn_fs_bdb__string_append(svn_fs_t *fs,
                          const char **key,
                          apr_size_t len,
                          const char *buf,
                          trail_t *trail,
                          apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBT query, result;

    /* If the passed-in key is NULL, we graciously generate a new string
       using the value of the `next-key' record in the strings table. */
    if (*key == NULL)
    {
        SVN_ERR(get_key_and_bump(fs, key, trail, pool));
    }

    /* Store a new record into the database. */
    svn_fs_base__trail_debug(trail, "strings", "put");
    return BDB_WRAP(fs, N_("appending string"),
                    bfd->strings->put
                    (bfd->strings, trail->db_txn,
                     svn_fs_base__str_to_dbt(&query, *key),
                     svn_fs_base__set_dbt(&result, buf, len),
                     0));
}
예제 #12
0
파일: reps-table.c 프로젝트: vocho/openqnx
svn_error_t *
svn_fs_bdb__write_new_rep(const char **key,
                          svn_fs_t *fs,
                          const representation_t *rep,
                          trail_t *trail,
                          apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  int db_err;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];

  /* ### todo: see issue #409 for why bumping the key as part of this
     trail is problematic. */

  /* Get the current value associated with `next-key'.  */
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__trail_debug(trail, "representations", "get");
  SVN_ERR(BDB_WRAP(fs, _("allocating new representation (getting next-key)"),
                   bfd->representations->get
                   (bfd->representations, trail->db_txn, &query,
                    svn_fs_base__result_dbt(&result), 0)));

  svn_fs_base__track_dbt(&result, pool);

  /* Store the new rep. */
  *key = apr_pstrmemdup(pool, result.data, result.size);
  SVN_ERR(svn_fs_bdb__write_rep(fs, *key, rep, trail, pool));

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "representations", "put");
  db_err = bfd->representations->put
    (bfd->representations, trail->db_txn,
     svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
     svn_fs_base__str_to_dbt(&result, next_key),
     0);

  SVN_ERR(BDB_WRAP(fs, _("bumping next representation key"), db_err));

  return SVN_NO_ERROR;
}
예제 #13
0
svn_error_t *
svn_fs_bdb__new_node_id(svn_fs_id_t **id_p,
                        svn_fs_t *fs,
                        const char *copy_id,
                        const char *txn_id,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;
  const char *next_node_id;

  SVN_ERR_ASSERT(txn_id);

  /* Get the current value associated with the `next-key' key in the table.  */
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__trail_debug(trail, "nodes", "get");
  SVN_ERR(BDB_WRAP(fs, N_("allocating new node ID (getting 'next-key')"),
                   bfd->nodes->get(bfd->nodes, trail->db_txn,
                                   &query,
                                   svn_fs_base__result_dbt(&result),
                                   0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Squirrel away our next node id value. */
  next_node_id = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "nodes", "put");
  db_err = bfd->nodes->put(bfd->nodes, trail->db_txn,
                           svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
                           svn_fs_base__str_to_dbt(&result, next_key),
                           0);
  SVN_ERR(BDB_WRAP(fs, N_("bumping next node ID key"), db_err));

  /* Create and return the new node id. */
  *id_p = svn_fs_base__id_create(next_node_id, copy_id, txn_id, pool);
  return SVN_NO_ERROR;
}
예제 #14
0
int
svn_fs_bdb__open_miscellaneous_table(DB **miscellaneous_p,
                                     DB_ENV *env,
                                     svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *miscellaneous;
  int error;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&miscellaneous, env, 0));
  error = (miscellaneous->open)(SVN_BDB_OPEN_PARAMS(miscellaneous, NULL),
                                "miscellaneous", 0, DB_BTREE,
                                open_flags, 0666);

  /* Create the table if it doesn't yet exist.  This is a form of
     automagical repository upgrading. */
  if (error == ENOENT && (! create))
    {
      BDB_ERR(miscellaneous->close(miscellaneous, 0));
      return svn_fs_bdb__open_miscellaneous_table(miscellaneous_p, env, TRUE);
    }
  BDB_ERR(error);

  /* If we're creating the table from scratch (not upgrading), record the
     upgrade rev as 0. */
  if (create)
    {
      DBT key, value;

      BDB_ERR(miscellaneous->put
              (miscellaneous, 0,
               svn_fs_base__str_to_dbt
               (&key, SVN_FS_BASE__MISC_FORWARD_DELTA_UPGRADE),
               svn_fs_base__str_to_dbt(&value, "0"), 0));
    }

  *miscellaneous_p = miscellaneous;
  return 0;
}
예제 #15
0
svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p,
                                              svn_fs_t *fs,
                                              trail_t *trail,
                                              apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;

  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);

  /* Get the current value associated with the `next-key' key in the
     `checksum-reps' table.  */
  svn_fs_base__trail_debug(trail, "checksum-reps", "get");
  SVN_ERR(BDB_WRAP(fs, _("allocating new representation reuse ID "
                         "(getting 'next-key')"),
                   bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
                                           &query,
                                           svn_fs_base__result_dbt(&result),
                                           0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Set our return value. */
  *id_p = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__trail_debug(trail, "checksum_reps", "put");
  db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
                                   svn_fs_base__str_to_dbt(&query,
                                                           NEXT_KEY_KEY),
                                   svn_fs_base__str_to_dbt(&result, next_key),
                                   0);

  return BDB_WRAP(fs, _("bumping next copy key"), db_err);
}
예제 #16
0
파일: txn-table.c 프로젝트: aosm/subversion
/* Allocate a Subversion transaction ID in FS, as part of TRAIL.  Set
   *ID_P to the new transaction ID, allocated in POOL.  */
static svn_error_t *
allocate_txn_id(const char **id_p,
                svn_fs_t *fs,
                trail_t *trail,
                apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, result;
  apr_size_t len;
  char next_key[MAX_KEY_SIZE];
  int db_err;

  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);

  /* Get the current value associated with the `next-key' key in the table.  */
  svn_fs_base__trail_debug(trail, "transactions", "get");
  SVN_ERR(BDB_WRAP(fs, "allocating new transaction ID (getting 'next-key')",
                   bfd->transactions->get(bfd->transactions, trail->db_txn,
                                          &query,
                                          svn_fs_base__result_dbt(&result),
                                          0)));
  svn_fs_base__track_dbt(&result, pool);

  /* Set our return value. */
  *id_p = apr_pstrmemdup(pool, result.data, result.size);

  /* Bump to future key. */
  len = result.size;
  svn_fs_base__next_key(result.data, &len, next_key);
  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
  svn_fs_base__str_to_dbt(&result, next_key);
  svn_fs_base__trail_debug(trail, "transactions", "put");
  db_err = bfd->transactions->put(bfd->transactions, trail->db_txn,
                                  &query, &result, 0);

  return BDB_WRAP(fs, "bumping next transaction key", db_err);
}
예제 #17
0
svn_error_t *svn_fs_bdb__delete_node_origin(svn_fs_t *fs,
                                            const char *node_id,
                                            trail_t *trail,
                                            apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;

  svn_fs_base__str_to_dbt(&key, node_id);
  svn_fs_base__trail_debug(trail, "node-origins", "del");
  SVN_ERR(BDB_WRAP(fs, "deleting entry from 'node-origins' table",
                   bfd->node_origins->del(bfd->node_origins,
                                          trail->db_txn, &key, 0)));
  return SVN_NO_ERROR;
}
예제 #18
0
svn_error_t *
svn_fs_bdb__delete_copy(svn_fs_t *fs,
                        const char *copy_id,
                        trail_t *trail,
                        apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    DBT key;
    int db_err;

    svn_fs_base__str_to_dbt(&key, copy_id);
    svn_fs_base__trail_debug(trail, "copies", "del");
    db_err = bfd->copies->del(bfd->copies, trail->db_txn, &key, 0);
    if (db_err == DB_NOTFOUND)
        return svn_fs_base__err_no_such_copy(fs, copy_id);
    return BDB_WRAP(fs, N_("deleting entry from 'copies' table"), db_err);
}
예제 #19
0
svn_error_t *svn_fs_bdb__set_node_origin(svn_fs_t *fs,
                                         const char *node_id,
                                         const svn_fs_id_t *origin_id,
                                         trail_t *trail,
                                         apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  /* Create a key from our NODE_ID. */
  svn_fs_base__str_to_dbt(&key, node_id);

  /* Check to see if we already have a mapping for NODE_ID.  If so,
     and the value is the same one we were about to write.  That's
     cool -- just do nothing.  If, however, the value is *different*,
     that's a red flag!  */
  svn_fs_base__trail_debug(trail, "node-origins", "get");
  db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn,
                                  &key, svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);
  if (db_err != DB_NOTFOUND)
    {
      const svn_string_t *origin_id_str = svn_fs_base__id_unparse(origin_id, pool);
      const svn_string_t *old_origin_id_str =
        svn_string_ncreate(value.data, value.size, pool);

      if (! svn_string_compare(origin_id_str, old_origin_id_str))
        return svn_error_createf
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Node origin for '%s' exists in filesystem '%s' with a different "
             "value (%s) than what we were about to store (%s)"),
           node_id, fs->path, old_origin_id_str->data, origin_id_str->data);
      else
        return SVN_NO_ERROR;
    }

  /* Create a value from our ORIGIN_ID, and add this record to the table. */
  svn_fs_base__id_to_dbt(&value, origin_id, pool);
  svn_fs_base__trail_debug(trail, "node-origins", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing node-origins record"),
                   bfd->node_origins->put(bfd->node_origins, trail->db_txn,
                                          &key, &value, 0)));
  return SVN_NO_ERROR;
}
예제 #20
0
svn_error_t *
svn_fs_bdb__lock_delete(svn_fs_t *fs,
                        const char *lock_token,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;
  int db_err;

  svn_fs_base__str_to_dbt(&key, lock_token);
  svn_fs_base__trail_debug(trail, "locks", "del");
  db_err = bfd->locks->del(bfd->locks, trail->db_txn, &key, 0);

  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_bad_lock_token(fs, lock_token);
  return BDB_WRAP(fs, "deleting lock from 'locks' table", db_err);
}
예제 #21
0
svn_error_t *svn_fs_bdb__set_checksum_rep(svn_fs_t *fs,
                                          svn_checksum_t *checksum,
                                          const char *rep_key,
                                          trail_t *trail,
                                          apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  /* We only allow SHA1 checksums in this table. */
  if (checksum->kind != svn_checksum_sha1)
    return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
                            _("Only SHA1 checksums can be used as keys in the "
                              "checksum-reps table.\n"));

  /* Create a key from our CHECKSUM. */
  svn_fs_base__checksum_to_dbt(&key, checksum);

  /* Check to see if we already have a mapping for CHECKSUM.  If so,
     and the value is the same one we were about to write, that's
     cool -- just do nothing.  If, however, the value is *different*,
     that's a red flag!  */
  svn_fs_base__trail_debug(trail, "checksum-reps", "get");
  db_err = bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn,
                                   &key, svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);
  if (db_err != DB_NOTFOUND)
    {
      const char *sum_str = svn_checksum_to_cstring_display(checksum, pool);
      return svn_error_createf
        (SVN_ERR_FS_ALREADY_EXISTS, NULL,
         _("Representation key for checksum '%s' exists in filesystem '%s'."),
         sum_str, fs->path);
    }

  /* Create a value from our REP_KEY, and add this record to the table. */
  svn_fs_base__str_to_dbt(&value, rep_key);
  svn_fs_base__trail_debug(trail, "checksum-reps", "put");
  SVN_ERR(BDB_WRAP(fs, _("storing checksum-reps record"),
                   bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn,
                                           &key, &value, 0)));
  return SVN_NO_ERROR;
}
예제 #22
0
svn_error_t *
svn_fs_bdb__lock_get(svn_lock_t **lock_p,
                     svn_fs_t *fs,
                     const char *lock_token,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;
  svn_skel_t *skel;
  svn_lock_t *lock;

  svn_fs_base__trail_debug(trail, "lock", "get");
  db_err = bfd->locks->get(bfd->locks, trail->db_txn,
                           svn_fs_base__str_to_dbt(&key, lock_token),
                           svn_fs_base__result_dbt(&value),
                           0);
  svn_fs_base__track_dbt(&value, pool);

  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_bad_lock_token(fs, lock_token);
  SVN_ERR(BDB_WRAP(fs, "reading lock", db_err));

  /* Parse TRANSACTION skel */
  skel = svn_skel__parse(value.data, value.size, pool);
  if (! skel)
    return svn_fs_base__err_corrupt_lock(fs, lock_token);

  /* Convert skel to native type. */
  SVN_ERR(svn_fs_base__parse_lock_skel(&lock, skel, pool));

  /* Possibly auto-expire the lock. */
  if (lock->expiration_date && (apr_time_now() > lock->expiration_date))
    {
      SVN_ERR(svn_fs_bdb__lock_delete(fs, lock_token, trail, pool));
      return SVN_FS__ERR_LOCK_EXPIRED(fs, lock_token);
    }

  *lock_p = lock;
  return SVN_NO_ERROR;
}
예제 #23
0
svn_error_t *
svn_fs_bdb__lock_add(svn_fs_t *fs,
                     const char *lock_token,
                     svn_lock_t *lock,
                     trail_t *trail,
                     apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *lock_skel;
  DBT key, value;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_lock_skel(&lock_skel, lock, pool));

  svn_fs_base__str_to_dbt(&key, lock_token);
  svn_fs_base__skel_to_dbt(&value, lock_skel, pool);
  svn_fs_base__trail_debug(trail, "lock", "add");
  return BDB_WRAP(fs, "storing lock record",
                  bfd->locks->put(bfd->locks, trail->db_txn,
                                  &key, &value, 0));
}
예제 #24
0
svn_error_t *svn_fs_bdb__get_node_origin(const svn_fs_id_t **origin_id,
                                         svn_fs_t *fs,
                                         const char *node_id,
                                         trail_t *trail,
                                         apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  int db_err;

  svn_fs_base__trail_debug(trail, "node-origins", "get");
  db_err = bfd->node_origins->get(bfd->node_origins, trail->db_txn,
                                  svn_fs_base__str_to_dbt(&key, node_id),
                                  svn_fs_base__result_dbt(&value), 0);
  svn_fs_base__track_dbt(&value, pool);

  if (db_err == DB_NOTFOUND)
    return svn_fs_base__err_no_such_node_origin(fs, node_id);

  *origin_id = svn_fs_base__id_parse(value.data, value.size, pool);
  return SVN_NO_ERROR;
}
예제 #25
0
svn_error_t *
svn_fs_bdb__changes_add(svn_fs_t *fs,
                        const char *key,
                        change_t *change,
                        trail_t *trail,
                        apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT query, value;
  svn_skel_t *skel;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_change_skel(&skel, change, pool));

  /* Store a new record into the database. */
  svn_fs_base__str_to_dbt(&query, key);
  svn_fs_base__skel_to_dbt(&value, skel, pool);
  svn_fs_base__trail_debug(trail, "changes", "put");
  return BDB_WRAP(fs, N_("creating change"),
                  bfd->changes->put(bfd->changes, trail->db_txn,
                                    &query, &value, 0));
}
예제 #26
0
파일: txn-table.c 프로젝트: aosm/subversion
svn_error_t *
svn_fs_bdb__delete_txn(svn_fs_t *fs,
                       const char *txn_name,
                       trail_t *trail,
                       apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key;
  transaction_t *txn;

  /* Make sure TXN is dead. */
  SVN_ERR(svn_fs_bdb__get_txn(&txn, fs, txn_name, trail, pool));
  if (is_committed(txn))
    return svn_fs_base__err_txn_not_mutable(fs, txn_name);

  /* Delete the transaction from the `transactions' table. */
  svn_fs_base__str_to_dbt(&key, txn_name);
  svn_fs_base__trail_debug(trail, "transactions", "del");
  return BDB_WRAP(fs, "deleting entry from 'transactions' table",
                  bfd->transactions->del(bfd->transactions,
                                         trail->db_txn, &key, 0));
}
예제 #27
0
svn_error_t *
svn_fs_bdb__string_size(svn_filesize_t *size,
                        svn_fs_t *fs,
                        const char *key,
                        trail_t *trail,
                        apr_pool_t *pool)
{
    int db_err;
    DBT query;
    DBC *cursor;
    apr_size_t length;
    svn_filesize_t total;

    svn_fs_base__str_to_dbt(&query, key);

    SVN_ERR(locate_key(&length, &cursor, &query, fs, trail, pool));

    total = length;
    while (1)
    {
        /* Remember, if any error happens, our cursor has been closed
           for us. */
        db_err = get_next_length(&length, cursor, &query);

        /* No more records? Then return the total length. */
        if (db_err == DB_NOTFOUND)
        {
            *size = total;
            return SVN_NO_ERROR;
        }
        if (db_err)
            return BDB_WRAP(fs, N_("fetching string length"), db_err);

        total += length;
    }

    /* NOTREACHED */
}
예제 #28
0
svn_error_t *
svn_fs_bdb__string_delete(svn_fs_t *fs,
                          const char *key,
                          trail_t *trail,
                          apr_pool_t *pool)
{
    base_fs_data_t *bfd = fs->fsap_data;
    int db_err;
    DBT query;

    svn_fs_base__trail_debug(trail, "strings", "del");
    db_err = bfd->strings->del(bfd->strings, trail->db_txn,
                               svn_fs_base__str_to_dbt(&query, key), 0);

    /* If there's no such node, return an appropriately specific error.  */
    if (db_err == DB_NOTFOUND)
        return svn_error_createf
               (SVN_ERR_FS_NO_SUCH_STRING, 0,
                "No such string '%s'", key);

    /* Handle any other error conditions.  */
    return BDB_WRAP(fs, N_("deleting string"), db_err);
}
예제 #29
0
svn_error_t *
svn_fs_bdb__changes_delete(svn_fs_t *fs,
                           const char *key,
                           trail_t *trail,
                           apr_pool_t *pool)
{
  int db_err;
  DBT query;
  base_fs_data_t *bfd = fs->fsap_data;

  svn_fs_base__trail_debug(trail, "changes", "del");
  db_err = bfd->changes->del(bfd->changes, trail->db_txn,
                             svn_fs_base__str_to_dbt(&query, key), 0);

  /* If there're no changes for KEY, that is acceptable.  Any other
     error should be propagated to the caller, though.  */
  if ((db_err) && (db_err != DB_NOTFOUND))
    {
      SVN_ERR(BDB_WRAP(fs, N_("deleting changes"), db_err));
    }

  return SVN_NO_ERROR;
}
예제 #30
0
파일: txn-table.c 프로젝트: aosm/subversion
svn_error_t *
svn_fs_bdb__put_txn(svn_fs_t *fs,
                    const transaction_t *txn,
                    const char *txn_name,
                    trail_t *trail,
                    apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  svn_skel_t *txn_skel;
  DBT key, value;

  /* Convert native type to skel. */
  SVN_ERR(svn_fs_base__unparse_transaction_skel(&txn_skel, txn, pool));

  /* Only in the context of this function do we know that the DB call
     will not attempt to modify txn_name, so the cast belongs here.  */
  svn_fs_base__str_to_dbt(&key, txn_name);
  svn_fs_base__skel_to_dbt(&value, txn_skel, pool);
  svn_fs_base__trail_debug(trail, "transactions", "put");
  return BDB_WRAP(fs, _("storing transaction record"),
                  bfd->transactions->put(bfd->transactions, trail->db_txn,
                                         &key, &value, 0));
}