# `Slap.SlateDB.Admin`
[🔗](https://github.com/mjrusso/slap/blob/slap_slatedb-v0.2.0/slap_slatedb/lib/slap/slatedb/admin.ex#L1)

Checkpoints, clones, garbage collection and other work on a database's
files, without opening the database.

An admin handle only reads and updates the manifest in object storage, so
it can be used while a writer has the database open, here or elsewhere.

    {:ok, admin} = Slap.SlateDB.Admin.open("my-db", store: store)
    {:ok, %{id: id}} = Slap.SlateDB.Admin.create_checkpoint(admin, name: "nightly")
    {:ok, [%{id: ^id, name: "nightly"}]} = Slap.SlateDB.Admin.list_checkpoints(admin)

# `checkpoint`

```elixir
@type checkpoint() :: %{
  id: String.t(),
  manifest_id: non_neg_integer(),
  created_at: DateTime.t(),
  expires_at: DateTime.t() | nil,
  name: String.t() | nil
}
```

# `t`

```elixir
@opaque t()
```

# `clone`

```elixir
@spec clone(t(), String.t(), keyword()) :: :ok | {:error, Slap.SlateDB.Error.t()}
```

Creates the database at `clone_path` as a clone of this one, as of a
checkpoint or of its latest state. The clone shares the source's files
instead of copying them, and then changes independently.

The clone is in the same store (and under the same URL prefix). Open it
with `Slap.SlateDB.open/2`. For a `:memory` store this only works while the
store is shared, which it is not across separate `open` calls, so use a
local or object store.

## Options

  * `:checkpoint` - the checkpoint id to clone from. By default, SlateDB
    makes a checkpoint of the latest state.
  * `:timeout` - see `Slap.SlateDB`.

# `compact`

```elixir
@spec compact(t(), keyword()) ::
  {:ok, String.t() | nil} | {:error, Slap.SlateDB.Error.t()}
```

Asks the database's compactor to merge all sorted runs into one.

This rewrites every sorted run, which is how a `Slap.SlateDB.CompactionFilter`
reaches data that was compacted before its prefix was added. It is the same
plan as SlateDB's own full compaction: L0 SSTs are left to the normal
schedule. A compactor must be running, for example in the process that has
the database open.

Returns `{:ok, compaction_id}`, or `{:ok, nil}` when there are no sorted
runs yet. The compaction runs in the background; it may be rejected if it
conflicts with a compaction already running.

# `create_checkpoint`

```elixir
@spec create_checkpoint(t(), keyword()) ::
  {:ok, %{id: String.t(), manifest_id: non_neg_integer()}}
  | {:error, Slap.SlateDB.Error.t()}
```

Creates a checkpoint of the database's latest manifest. Unlike
`Slap.SlateDB.create_checkpoint/2`, it does not need the database open, and it
only covers what the writer has already written to the manifest.

Takes the `:lifetime`, `:name`, `:source` and `:timeout` options of
`Slap.SlateDB.create_checkpoint/2`.

# `delete_checkpoint`

```elixir
@spec delete_checkpoint(t(), String.t(), keyword()) ::
  :ok | {:error, Slap.SlateDB.Error.t()}
```

Deletes a checkpoint. Garbage collection can then remove its files.

# `list_checkpoints`

```elixir
@spec list_checkpoints(t(), keyword()) ::
  {:ok, [checkpoint()]} | {:error, Slap.SlateDB.Error.t()}
```

Lists checkpoints, oldest first. Pass `name: name` to list only those with
that name.

# `open`

```elixir
@spec open(String.t(), keyword()) :: {:ok, t()} | {:error, Slap.SlateDB.Error.t()}
```

Opens an admin handle for the database at `path`. Takes the `:store` and
`:timeout` options of `Slap.SlateDB.open/2`.

# `refresh_checkpoint`

```elixir
@spec refresh_checkpoint(t(), String.t(), non_neg_integer() | nil, keyword()) ::
  :ok | {:error, Slap.SlateDB.Error.t()}
```

Sets a checkpoint to expire `lifetime` milliseconds from now, or never when
`lifetime` is `nil`.

# `run_gc`

```elixir
@spec run_gc(t(), keyword()) :: :ok | {:error, Slap.SlateDB.Error.t()}
```

Runs the garbage collector once, deleting files that no manifest or
checkpoint needs any more.

## Options

  * `:settings` - a map merged over SlateDB's default garbage collector
    options, for example
    `%{compacted_options: %{min_age: "1h"}, wal_options: %{min_age: "1h"}}`.
  * `:timeout` - see `Slap.SlateDB`.

# `seq_for_timestamp`

```elixir
@spec seq_for_timestamp(t(), DateTime.t(), keyword()) ::
  {:ok, non_neg_integer() | nil} | {:error, Slap.SlateDB.Error.t()}
```

Returns the sequence number of the write at `datetime`, from SlateDB's
sequence tracker, or `nil` if it has no record. Approximate, like
`timestamp_for_seq/3`, and takes the same `:round_up` option.

# `timestamp_for_seq`

```elixir
@spec timestamp_for_seq(t(), non_neg_integer(), keyword()) ::
  {:ok, DateTime.t() | nil} | {:error, Slap.SlateDB.Error.t()}
```

Returns when the write with sequence number `seq` happened, as recorded by
SlateDB's sequence tracker, or `nil` if it has no record. The tracker
keeps a sample of points, so the result is approximate. With
`round_up: true`, it rounds to the next recorded point instead of the
previous one.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
