Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ LMDB.jl exposes the same database through three surfaces:
`AbstractDict{K,V}` over a single LMDB file. Standard library
machinery (`merge!`, `filter!`, `pairs`, iteration, …) works out
of the box. Reach for this when you want a persistent `Dict`.
- Julia wrappers: `Environment`, `Transaction`, `DBI`, `Cursor`.
- Julia wrappers: `Environment`, `Transaction`, `Database`, `Cursor`.
Julia-shaped wrappers around handles, transactions, and cursors,
with finalizers, `do`-block forms, and so on. Use these when you
want explicit transactions.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ LMDB.jl exposes the same database through three surfaces:
| Surface | What it offers | When to use |
|---------|----------------|-------------|
| High-level interface | `LMDBDict <: AbstractDict{K,V}` | When you want a persistent `Dict`. |
| Julia wrappers | `Environment`, `Transaction`, `DBI`, `Cursor` | When you want explicit transactions and cursors with Julia-shaped wrappers. |
| Julia wrappers | `Environment`, `Transaction`, `Database`, `Cursor` | When you want explicit transactions and cursors with Julia-shaped wrappers. |
| C API | `LMDB.mdb_*`, `LMDB.MDB_*` | Raw `ccall` bindings and status-code constants, for custom data layouts or when you want to skip allocations on hot paths. |

`MDBValue`, `MDBArg`, and the [`MDBValueIO`](@ref LMDB.MDBValueIO)
Expand Down
4 changes: 2 additions & 2 deletions docs/src/lib/cursors.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
CurrentModule = LMDB
```

A `Cursor` is a positioned iterator over the entries in a `DBI`. Cursors
A `Cursor` is a positioned iterator over the entries in a `Database`. Cursors
are bound to a transaction. Closing the txn invalidates the cursor.

## Construction

```@docs
Cursor
Base.open(::Transaction, ::DBI)
Cursor(::Transaction, ::Database)
Base.close(::Cursor)
Base.isopen(::Cursor)
renew(::Transaction, ::Cursor)
Expand Down
31 changes: 15 additions & 16 deletions docs/src/lib/databases.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
# [Databases](@id API-DBI)
# [Databases](@id API-Database)

```@meta
CurrentModule = LMDB
```

A `DBI` (database identifier) is a handle to one B-tree inside an
A `Database` (database identifier) is a handle to one B-tree inside an
environment. By default an env has a single anonymous database (the
"main DB"); pass `maxdbs > 0` to `Environment` and a name to `open` to
work with multiple named sub-databases.
"main DB"); pass `maxdbs > 0` to `Environment` and a name to the `Database`
constructor to work with multiple named sub-databases.

## Construction

```@docs
DBI
Base.open(::Transaction, ::String)
Base.close(::Environment, ::DBI)
Base.isopen(::DBI)
Database
Database(::Transaction, ::AbstractString)
Base.close(::Environment, ::Database)
Base.isopen(::Database)
flags
drop
Base.stat(::Transaction, ::DBI)
Base.stat(::Transaction, ::Database)
```

## Reads

```@docs
Base.get(::Transaction, ::DBI, ::Any, ::Type{T}) where T
Base.get(::Transaction, ::DBI, ::Any, ::Type{T}, ::Any) where T
tryget
Base.get(::Transaction, ::Database, ::Any, ::Type{T}) where T
Base.get(::Transaction, ::Database, ::Any, ::Type{T}, ::Any) where T
```

`get(txn, dbi, key, T, default)` falls back to `default` if `key` is
Expand All @@ -35,11 +34,11 @@ missing, matching `Base.get(dict, key, default)`.
## Writes

```@docs
Base.put!(::Transaction, ::DBI, ::Any, ::Any)
Base.put!(::Transaction, ::Database, ::Any, ::Any)
put_reserved!
Base.delete!(::Transaction, ::DBI, ::Any)
Base.replace!(::Transaction, ::DBI, ::Any, ::Any)
Base.pop!(::Transaction, ::DBI, ::Any, ::Type)
Base.delete!(::Transaction, ::Database, ::Any)
Base.replace!(::Transaction, ::Database, ::Any, ::Any)
Base.pop!(::Transaction, ::Database, ::Any, ::Type)
```

## Write flags
Expand Down
2 changes: 1 addition & 1 deletion docs/src/lib/dict.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Everything `AbstractDict` derives (`merge!`, `merge`, `mergewith!`,

## Lifecycle

`close(::LMDBDict)` closes the underlying env (and the default DBI).
`close(::LMDBDict)` closes the underlying env (and the default Database).
Idempotent, and also called from the finalizer.

## Prefix-scan helpers
Expand Down
3 changes: 0 additions & 3 deletions docs/src/lib/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ cursor lives inside one env.
```@docs
Environment
Environment(::AbstractString)
create
environment
```

## Lifecycle

```@docs
Base.open(::Environment, ::String)
Base.close(::Environment)
Base.isopen(::Environment)
sync
Expand Down
8 changes: 4 additions & 4 deletions docs/src/lib/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ the `unchecked_*` companion returns the raw `Cint` so the caller can
branch on `MDB_NOTFOUND`/`MDB_KEYEXIST` and friends.

At the Julia wrappers, handle methods that wrap status-returning
bindings let `LMDBError` propagate. `tryget` and `get(..., default)`
swallow `MDB_NOTFOUND` and return `nothing` or `default`.
`delete!(txn, dbi, key)` likewise swallows `MDB_NOTFOUND` and returns
`false`.
bindings let `LMDBError` propagate. `get(..., default)` swallows
`MDB_NOTFOUND` and returns `default` (use `nothing` for the
`Union{T,Nothing}` shape). `delete!(txn, dbi, key)` likewise swallows
`MDB_NOTFOUND` and returns `false`.

At the high-level interface, missing keys produce `KeyError` (matching
`Base.Dict`), and `pop!(d)` on an empty dict throws `ArgumentError`.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/lib/lowlevel.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ since there is nothing to check.

## Customisation point: `MDBValueIO`

`tryget`, `get`, `key`, `value`, `item`, typed `walk`, `pop!`, and
`get`, `key`, `value`, `item`, typed `walk`, `pop!`, and
`replace!` all go through `read(::MDBValueIO, T)` to decode an
`MDB_val` into a Julia value. Define a `Base.read` method on
`MDBValueIO` to plug in a custom representation. See [Cursors](@ref)
Expand Down Expand Up @@ -107,7 +107,7 @@ mdb_txn_reset
mdb_txn_renew
```

### Database (DBI)
### Database (Database)

```julia
mdb_dbi_open
Expand Down
10 changes: 5 additions & 5 deletions docs/src/lib/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrent readers but only one writer at a time.

```@docs
Transaction
start
Transaction(::Environment)
```

## Lifecycle
Expand All @@ -36,7 +36,7 @@ renew(::Transaction)

## Sub-transactions

Pass `parent = txn` to [`start`](@ref) to nest a child write transaction
inside an open write transaction. The child sees the parent's uncommitted
state; on `commit` the child's changes are folded into the parent, on
`abort` they are discarded.
Pass `parent = txn` to [`Transaction`](@ref) to nest a child write
transaction inside an open write transaction. The child sees the
parent's uncommitted state; on `commit` the child's changes are folded
into the parent, on `abort` they are discarded.
29 changes: 15 additions & 14 deletions docs/src/man/cursors.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
CurrentModule = LMDB
```

A `Cursor` is a positioned iterator over a `DBI`. Use it for ordered
A `Cursor` is a positioned iterator over a `Database`. Use it for ordered
scans, range queries, or to amortise the per-lookup overhead of
`mdb_get` across many keys.

## Opening a cursor

```julia
start(env; flags = LMDB.MDB_RDONLY) do txn
open(txn) do dbi
open(txn, dbi) do cur
Transaction(env; flags = LMDB.MDB_RDONLY) do txn
Database(txn) do dbi
Cursor(txn, dbi) do cur
# use cur
end
end
Expand Down Expand Up @@ -66,9 +66,9 @@ A typical pattern for "all keys with a given prefix":

```julia
prefix = "users/"
start(env; flags = LMDB.MDB_RDONLY) do txn
open(txn) do dbi
open(txn, dbi) do cur
Transaction(env; flags = LMDB.MDB_RDONLY) do txn
Database(txn) do dbi
Cursor(txn, dbi) do cur
k = seek_range!(cur, prefix, String)
while k !== nothing && startswith(k, prefix)
v = LMDB.value(cur, String)
Expand Down Expand Up @@ -113,9 +113,10 @@ Use the untyped form when you want to inspect raw byte sizes, copy
slices, or feed a custom decoder. The data pointers are into LMDB's
mmap and are valid only inside the callback (and only for the
surrounding txn). The typed form is the iteration analogue of
`tryget(..., T)` and works for any `T` for which `Base.read(io::IO,
::Type{T})` (or `Base.read(io::LMDB.MDBValueIO, ::Type{T})`) is
defined. See [Custom value decoding](@ref).
`get(..., T, nothing)` and works for any `T` for which
`Base.read(io::IO, ::Type{T})` (or
`Base.read(io::LMDB.MDBValueIO, ::Type{T})`) is defined. See
[Custom value decoding](@ref).

## Cursor mutation

Expand All @@ -134,7 +135,7 @@ key (1 in non-DUPSORT databases).

## Custom value decoding

`tryget`, `get`, `key`, `value`, `item`, and typed `walk` all funnel
`get`, `key`, `value`, `item`, and typed `walk` all funnel
through `Base.read(io::IO, ::Type{T})` against an
[`MDBValueIO`](@ref LMDB.MDBValueIO). The defaults cover Base's
primitive numeric types (`Int8`/…/`Float64`, `Bool`, `Char`, `Ptr`),
Expand All @@ -153,7 +154,7 @@ function Base.read(io::IO, ::Type{PrefixedBlob})
end

# now usable everywhere a value-type parameter is accepted:
LMDB.tryget(txn, dbi, key, PrefixedBlob)
LMDB.get(txn, dbi, key, PrefixedBlob, nothing)
walk(cur, String, PrefixedBlob) do k, blob
handle(k, blob)
end
Expand All @@ -174,8 +175,8 @@ expensive. Park the txn with [`reset`](@ref Base.reset(::LMDB.Transaction))
and refresh both the txn and the cursor with `renew(txn, cur)`:

```julia
txn = start(env; flags = LMDB.MDB_RDONLY)
cur = open(txn, dbi)
txn = Transaction(env; flags = LMDB.MDB_RDONLY)
cur = Cursor(txn, dbi)
while running
... # use cur
reset(txn)
Expand Down
37 changes: 18 additions & 19 deletions docs/src/man/databases.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@
CurrentModule = LMDB
```

A `DBI` is a handle to one B-tree inside an environment. By default an
A `Database` is a handle to one B-tree inside an environment. By default an
env has a single anonymous database (the "main DB"); pass `maxdbs > 0`
to `Environment` to support multiple named sub-databases.

## Opening a DBI
## Opening a Database

```julia
dbi = open(txn) # main (unnamed) DB
dbi = open(txn, "users") # named sub-DB; needs maxdbs >= 1
dbi = open(txn, "edges"; flags = LMDB.MDB_CREATE | LMDB.MDB_DUPSORT)
dbi = Database(txn) # main (unnamed) DB
dbi = Database(txn, "users") # named sub-DB; needs maxdbs >= 1
dbi = Database(txn, "edges"; flags = LMDB.MDB_CREATE | LMDB.MDB_DUPSORT)
```

The do-block form closes the DBI on the way out:
The do-block form closes the Database on the way out:

```julia
open(txn, "users") do dbi
Database(txn, "users") do dbi
put!(txn, dbi, "1", "Ada")
end
```

In practice you'll rarely *want* to close a DBI handle explicitly. The
In practice you'll rarely *want* to close a Database handle explicitly. The
env owns it, and `mdb_dbi_close` is documented as rarely useful. The
env's finalizer cascades through any open DBI handles.
env's finalizer cascades through any open Database handles.

## DBI flags
## Database flags

`flags` accepts a bitwise-or of:

Expand All @@ -44,25 +44,24 @@ env's finalizer cascades through any open DBI handles.

## Reads

Every read takes a value-type parameter `T`. The default forms are:
Every read takes a value-type parameter `T`. The two shapes are:

```julia
get(txn, dbi, key, T) # throws LMDBError(MDB_NOTFOUND) on miss
tryget(txn, dbi, key, T) # nothing on miss
get(txn, dbi, key, T, default) # default on miss
get(txn, dbi, key, T, default) # returns `default` on miss
```

`T` is anything `read(::LMDB.MDBValueIO, ::Type{T})` knows how to
decode: `String`, `Vector{E}` for any bitstype `E`, or any bitstype
scalar.

```julia
tryget(txn, dbi, "name", String) # → Union{String, Nothing}
tryget(txn, dbi, key, Vector{Float32}) # → Union{Vector{Float32}, Nothing}
tryget(txn, dbi, key, UInt64) # → Union{UInt64, Nothing}
get(txn, dbi, "name", String, nothing) # → Union{String, Nothing}
get(txn, dbi, key, Vector{Float32}, nothing) # → Union{Vector{Float32}, Nothing}
get(txn, dbi, key, UInt64, zero(UInt64)) # → UInt64
```

`tryget` is the cheap one: it inspects the raw status code and swallows
The default-form `get` inspects the raw status code and swallows
`MDB_NOTFOUND` without throwing.

## Writes
Expand All @@ -86,8 +85,8 @@ Useful write flags:

```julia
# Bulk import in sorted order:
start(env) do txn
open(txn) do dbi
Transaction(env) do txn
Database(txn) do dbi
for (k, v) in sorted_pairs
put!(txn, dbi, k, v; flags = LMDB.MDB_APPEND)
end
Expand Down
2 changes: 1 addition & 1 deletion docs/src/man/dict.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CurrentModule = LMDB
```

`LMDBDict{K,V}` is a persistent `AbstractDict{K,V}` backed by a single
LMDB environment plus the default DBI. Open it, treat it like a `Dict`,
LMDB environment plus the default Database. Open it, treat it like a `Dict`,
close it.

## Construction
Expand Down
4 changes: 2 additions & 2 deletions docs/src/man/dupsort.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ values" patterns.

```julia
env = Environment("/tmp/edges"; mapsize = 1 << 30, maxdbs = 1)
start(env) do txn
dbi = open(txn, "edges"; flags = LMDB.MDB_CREATE | LMDB.MDB_DUPSORT)
Transaction(env) do txn
dbi = Database(txn, "edges"; flags = LMDB.MDB_CREATE | LMDB.MDB_DUPSORT)
put!(txn, dbi, "a", "b")
put!(txn, dbi, "a", "c")
put!(txn, dbi, "a", "d")
Expand Down
Loading
Loading