#### `Ethdb` package hold's bouquet of objects to access DB
Words "KV" and "DB" have special meaning here:
- KV - key-value-style API to access data: let developer manage transactions, stateful cursors.
- DB - object-oriented-style API to access data: Get/Put/Delete/WalkOverTable/MultiPut, managing transactions internally.
So, DB abstraction fits 95% times and leads to more maintainable code - because it's looks stateless.
About "key-value-style": Modern key-value databases don't provide Get/Put/Delete methods,
because it's very hard-drive-unfriendly - it pushes developers do random-disk-access which is [order of magnitude slower than sequential read](https://www.seagate.com/sg/en/tech-insights/lies-damn-lies-and-ssd-benchmark-master-ti/).
To enforce sequential-reads - introduced stateful cursors/iterators - they intentionally look as file-api: open_cursor/seek/write_data_from_current_position/move_to_end/step_back/step_forward/delete_key_on_current_position/append.
## Class diagram:
```asciiflow.com
// This is not call graph, just show classes from low-level to high-level.
// And show which classes satisfy which interfaces.
defer tx.Rollback() // important to avoid transactions leak at panic or early return
// ... code which uses database in transaction
err := tx.Commit()
if err != nil {
return err
}
```
- No internal copies/allocations. It means: 1. app must copy keys/values before put to database. 2. Data after read from db - valid only during current transaction - copy it if plan use data after transaction Commit/Rollback.
- Bucket and Cursor - are interfaces - means different classes can satisfy it: for example `LmdbCursor`, `LmdbDupSortCursor`, `LmdbDupFixedCursor` classes satisfy it.
If your are not familiar with "DupSort" concept, please read [indices.md](./../docs/programmers_guide/indices.md) first.
- If Cursor returns err!=nil then key SHOULD be != nil (can be []byte{} for example).
Then traversal code look as:
```go
for k, v, err := c.First(); k != nil; k, v, err = c.Next() {
if err != nil {
return err
}
// logic
}
```
- Move cursor: `cursor.Seek(key)`
## ethdb.Database design:
- Allows pass multiple implementations
- Allows traversal tables by `db.Walk` and `db.MultiWalk`
## ethdb.TxDb design:
- holds inside 1 long-running transaction and 1 cursor per table