Skip to content

Commit 82ca91d

Browse files
authored
Merge pull request #67 from JuliaDatabases/tb/julia_api
Improvements to new Julia API
2 parents 8e5494b + ba9faa0 commit 82ca91d

32 files changed

Lines changed: 572 additions & 565 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ LMDB.jl exposes the same database through three surfaces:
2222
`AbstractDict{K,V}` over a single LMDB file. Standard library
2323
machinery (`merge!`, `filter!`, `pairs`, iteration, …) works out
2424
of the box. Reach for this when you want a persistent `Dict`.
25-
- Julia wrappers: `Environment`, `Transaction`, `DBI`, `Cursor`.
25+
- Julia wrappers: `Environment`, `Transaction`, `Database`, `Cursor`.
2626
Julia-shaped wrappers around handles, transactions, and cursors,
2727
with finalizers, `do`-block forms, and so on. Use these when you
2828
want explicit transactions.

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LMDB.jl exposes the same database through three surfaces:
1818
| Surface | What it offers | When to use |
1919
|---------|----------------|-------------|
2020
| High-level interface | `LMDBDict <: AbstractDict{K,V}` | When you want a persistent `Dict`. |
21-
| Julia wrappers | `Environment`, `Transaction`, `DBI`, `Cursor` | When you want explicit transactions and cursors with Julia-shaped wrappers. |
21+
| Julia wrappers | `Environment`, `Transaction`, `Database`, `Cursor` | When you want explicit transactions and cursors with Julia-shaped wrappers. |
2222
| 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. |
2323

2424
`MDBValue`, `MDBArg`, and the [`MDBValueIO`](@ref LMDB.MDBValueIO)

docs/src/lib/cursors.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
CurrentModule = LMDB
55
```
66

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

1010
## Construction
1111

1212
```@docs
1313
Cursor
14-
Base.open(::Transaction, ::DBI)
14+
Cursor(::Transaction, ::Database)
1515
Base.close(::Cursor)
1616
Base.isopen(::Cursor)
1717
renew(::Transaction, ::Cursor)

docs/src/lib/databases.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
1-
# [Databases](@id API-DBI)
1+
# [Databases](@id API-Database)
22

33
```@meta
44
CurrentModule = LMDB
55
```
66

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

1212
## Construction
1313

1414
```@docs
15-
DBI
16-
Base.open(::Transaction, ::String)
17-
Base.close(::Environment, ::DBI)
18-
Base.isopen(::DBI)
15+
Database
16+
Database(::Transaction, ::AbstractString)
17+
Base.close(::Environment, ::Database)
18+
Base.isopen(::Database)
1919
flags
2020
drop
21-
Base.stat(::Transaction, ::DBI)
21+
Base.stat(::Transaction, ::Database)
2222
```
2323

2424
## Reads
2525

2626
```@docs
27-
Base.get(::Transaction, ::DBI, ::Any, ::Type{T}) where T
28-
Base.get(::Transaction, ::DBI, ::Any, ::Type{T}, ::Any) where T
29-
tryget
27+
Base.get(::Transaction, ::Database, ::Any, ::Type{T}) where T
28+
Base.get(::Transaction, ::Database, ::Any, ::Type{T}, ::Any) where T
3029
```
3130

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

3736
```@docs
38-
Base.put!(::Transaction, ::DBI, ::Any, ::Any)
37+
Base.put!(::Transaction, ::Database, ::Any, ::Any)
3938
put_reserved!
40-
Base.delete!(::Transaction, ::DBI, ::Any)
41-
Base.replace!(::Transaction, ::DBI, ::Any, ::Any)
42-
Base.pop!(::Transaction, ::DBI, ::Any, ::Type)
39+
Base.delete!(::Transaction, ::Database, ::Any)
40+
Base.replace!(::Transaction, ::Database, ::Any, ::Any)
41+
Base.pop!(::Transaction, ::Database, ::Any, ::Type)
4342
```
4443

4544
## Write flags

docs/src/lib/dict.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Everything `AbstractDict` derives (`merge!`, `merge`, `mergewith!`,
3232

3333
## Lifecycle
3434

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

3838
## Prefix-scan helpers

docs/src/lib/environments.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@ cursor lives inside one env.
1313
```@docs
1414
Environment
1515
Environment(::AbstractString)
16-
create
17-
environment
1816
```
1917

2018
## Lifecycle
2119

2220
```@docs
23-
Base.open(::Environment, ::String)
2421
Base.close(::Environment)
2522
Base.isopen(::Environment)
2623
sync

docs/src/lib/errors.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ the `unchecked_*` companion returns the raw `Cint` so the caller can
3939
branch on `MDB_NOTFOUND`/`MDB_KEYEXIST` and friends.
4040

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

4747
At the high-level interface, missing keys produce `KeyError` (matching
4848
`Base.Dict`), and `pop!(d)` on an empty dict throws `ArgumentError`.

docs/src/lib/lowlevel.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ since there is nothing to check.
3939

4040
## Customisation point: `MDBValueIO`
4141

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

110-
### Database (DBI)
110+
### Database (Database)
111111

112112
```julia
113113
mdb_dbi_open

docs/src/lib/transactions.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrent readers but only one writer at a time.
1212

1313
```@docs
1414
Transaction
15-
start
15+
Transaction(::Environment)
1616
```
1717

1818
## Lifecycle
@@ -36,7 +36,7 @@ renew(::Transaction)
3636

3737
## Sub-transactions
3838

39-
Pass `parent = txn` to [`start`](@ref) to nest a child write transaction
40-
inside an open write transaction. The child sees the parent's uncommitted
41-
state; on `commit` the child's changes are folded into the parent, on
42-
`abort` they are discarded.
39+
Pass `parent = txn` to [`Transaction`](@ref) to nest a child write
40+
transaction inside an open write transaction. The child sees the
41+
parent's uncommitted state; on `commit` the child's changes are folded
42+
into the parent, on `abort` they are discarded.

docs/src/man/cursors.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
CurrentModule = LMDB
55
```
66

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

1111
## Opening a cursor
1212

1313
```julia
14-
start(env; flags = LMDB.MDB_RDONLY) do txn
15-
open(txn) do dbi
16-
open(txn, dbi) do cur
14+
Transaction(env; flags = LMDB.MDB_RDONLY) do txn
15+
Database(txn) do dbi
16+
Cursor(txn, dbi) do cur
1717
# use cur
1818
end
1919
end
@@ -66,9 +66,9 @@ A typical pattern for "all keys with a given prefix":
6666

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

120121
## Cursor mutation
121122

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

135136
## Custom value decoding
136137

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

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

176177
```julia
177-
txn = start(env; flags = LMDB.MDB_RDONLY)
178-
cur = open(txn, dbi)
178+
txn = Transaction(env; flags = LMDB.MDB_RDONLY)
179+
cur = Cursor(txn, dbi)
179180
while running
180181
... # use cur
181182
reset(txn)

0 commit comments

Comments
 (0)