Start blocking out some documentation.

- Fix some C rdoc so it is parsed correctly.
  - Fill out transaction testing.
  - Populate docs for DB options.

FossilOrigin-Name: f54dbfacf2dda100a116fdcc856ca5231e249f23238ca9d4355618e3a380a8f8
This commit is contained in:
Mahlon E. Smith 2021-02-14 09:47:04 +00:00
parent 81ee69295c
commit a54c286a75
11 changed files with 345 additions and 43 deletions

118
README.md
View file

@ -1,4 +1,5 @@
# Ruby MDBX
# Ruby::MDBX
home
: https://code.martini.nu/ruby-mdbx
@ -99,7 +100,7 @@ development.
## License
Copyright (c) 2020, Mahlon E. Smith
Copyright (c) 2020-2021 Mahlon E. Smith
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -127,3 +128,116 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ruby MDBX
=========
https://erthink.github.io/libmdbx/intro.html
Notes on the libmdbx environment for ruby:
- A **database** is contained in a file, normally wrapped in directory for it's associated lock.
- Each database can contain multiple named **collections**.
- Each collection can contain any number of **keys**, and their associated **values**. A collection may optionally support multiple values per key (or duplicate keys, which is the same thing).
- A **cursor** lets you iterate a collection's keys and values in order.
(Note, this should be enumerable and built in to the Ruby interface)
- A **snapshot** is a self-consistent read-only view of the database. It stays the same even if some other thread or process makes changes. *The only way to access keys and values is within a snapshot*.
- A **transaction** is a writable snapshot. Changes made within a transaction are private until committed. *The only way to modify the database is within a transaction*.
Example Usage
----------------
### Create database handle
```ruby
db = MDBX::Database.create( "/path/to/file", options )
db = MDBX::Database.open( "/path/to/file", options )
# perhaps a block mode that yields the handle, closing on block exit?
MDBX::Database.open( 'database' ) do |db|
puts db[ 'key1' ]
end
```
### Access data
```ruby
db[ 'key1' ] #=> val
# In the backend, automatically creates the snapshot, retrieves the value, and removes the snapshot before returning.
# read-only block
db.snapshot do
db[ 'key1' ] #=> val
...
end
# This is much faster for retrieving many values
# Maybe have a snapshot object that acts like a DB while it exists?
snap = db.snapshot
snap[ 'whatever' ] #=> data
snap.close
```
### Write data
```ruby
db[ 'key1' ] = val
# In the backend, automatically creates a transaction, stores the value, and closes the transaction before returning.
# writable block
db.transaction do
db[ 'key1' ] = val
end
# Much faster for writing many values, should commit on success or abort on any exception
# Maybe have a transaction object that acts like a DB while it exists?
# ALL OTHER TRANSACTIONS will block until this is closed
txn = db.transaction
txn[ 'whatever' ] = data
txn.commit # or txn.abort
```
### Collections
Identical interface to top-level databases. Just have to pull the collection first.
```ruby
collection = db.collection( 'stuff' ) # raise if nonexistent
# This now works just like the main db object
collection.transaction.do
...
end
```
### Cleaning up
```ruby
db.close
```
### Stats!
TODO
-------
gem install mdbx -- --with-opt-dir=/usr/local
- [ ] Multiple value per key -- .insert, .delete? iterator for multi-val keys
- [ ] each_pair?
- [ ] document how serialization works
- [ ] document everything, really
- [x] transaction/snapshot blocks
- [ ] Arbitrary keys instead of forcing to strings?
- [ ] Disallow collection switching if there is an open transaction