Breaking Changes
-
The Minimum Supported Rust Version (MSRV) has been changed to 1.70.
-
All features in the
bonsaidbcrate have been updated to support the new
features in Rust 1.60. Instead of needing separate flags for
client-websocketsandserver-websockets, a single feature flag
websocketsis now able to work in conjunction with theclient/server
features to ensure everything works correctly.The net change is fewer feature flags. If you find that a feature flag is
missing on upgrade, try removing "local-", "client-", or "server-" from the
beginning of the feature and recompiling. -
The
Keyimplementation forOption<T>has changed. If you wish to preserve
backwards compatibility, wrap the key type withOptionKeyV1.The old behavior was broken in two ways:
- The length of the key was improperly always reported as a constant length.
This only affects code that was using composite keys. - When using a type that can encode itself as 0 bytes, there was no way to
distinguish between a 0-length contained value and None. Thus,Some("")
would panic as a precaution. However, this type of lurking panic in an
esoteric edge case is exactly the behavior a database should never exhibit.
- The length of the key was improperly always reported as a constant length.
-
The
Keyimplementation for tuples (e.g.,(T1, T2)) has changed. If you
wish to preserve backwards compatibility, wrap the key type withTupleKeyV1.The old behavior had an incorrect sort order for the generated bytes. Instead
of sorting only by the values themselves, the lengths of the variable-length
Keytypes were taking precedence over the values. For more information, see
issue #240.This change also deprecates
encode_composite_key()/decode_composite_key()
in favor of two new types:CompositeKeyEncoderandCompositeKeyDecoder. -
Collection's get/list/list_with_prefix/insert/overwrite and View's
with_key_range/with_key_prefix have all been updated to accept borrowed
representations of keys. For example, when a Collection'sPrimaryKeyis
String,&strcan now be supplied to these functions.For most users, adding
&in front of the argument will generally fix the
compiler error upon upgrade. -
DocumentIdis no longerCopy, and now can support up to 64kb of data.
Previously, the type was limited to 64 total bytes of stack space. -
[Async]StorageConnection::schematic()have been moved to its own trait,
HasSchema. -
[Async]StorageConnection::authenticate()no longer takes a username or user
id directly. This has been moved to theAuthenticationtype. -
AuthenticationMethodhas moved frombonsaidb::core::permissions::bonsaito
bonsaidb::core::connection -
ApiNamehas been moved frombonsaidb::core::schemato
bonsaidb::core::api. -
Various error variants that were simply
Stringrepresentations have been
consoldiated intobonsaidb::core::Error::Other. -
bonsaidb::server::Backendnow takes a&selfparameter in all functions
exceptconfigure(). ImplementingDefaultfor yourBackendimplementor
will allow all existing code to continue working. -
Client::effective_permissions()is no longer async. -
CustomServer::connected_clients()is no longer async. -
CustomServer::broadcast()is no longer async. -
CustomServer::listen_onnow takesimpl Into<BonsaiListenConfig>instead of
just a u16 parameter specifying the port.BonsaiListenConfigimplements
From<u16>to minimize code breakage. -
The command-line
Servetype has had itslisten-onfield changed to a
SocketAddrtype to reflect the support forBonsaiListenConfig. The full
address and port must be specified when providing alisten-onargument now. -
Clienthas been renamed toAsyncClient, and a new type,BlockingClient
has been added. This splits theClientinto two separate parts: anasync
version and a blocking version. This makes it less likely to accidentally call
a blocking method in an async context.Client::send_api_request_asynchas been renamed tosend_api_request.This change has also been introduced to
RemoteDatabaseand
RemoteSubscriber: both async and blocking versions are available. -
#254
Key::from_ord_byteshas had its&'k [u8]parameter changed to a new type
with an additional lifetime:ByteSource<'k, 'e>. This new type allows
from_ord_bytesto be called with an ownedVec<u8>, aKey-lifetime bound
byte slice (&'k [u8]), or an ephemeral byte slice (&'e [u8]).This change allows code paths that can pass an owned
Vec<u8>in for decoding
to not require allocations in some cases -- for example, when using
Vec<u8>::from_ord_bytes.This change also means that
Keyimplementors should expect to be called with
any of the three variants ofByteSource, because BonsaiDb's internal code
only passes borrowed slices in some code paths.Thank you to @asonix for the request and help on implementation!
-
KeyEncoding::describeis a new function that allows a key encoder to
document the data contained within the encoded representation. The goal of
this is to allow tools to generically operate on key types used within
BonsaiDb. This function is automatically implemented when using theKey
derive.The new
KeyDescriptiontype uses this function to create a nested
representation of the contained information.Types that utilize a custom encoding format can use
KeyDescription::Otherto
uniquely identify the key. -
Schematichas had several methods changed toimpl Iteratorof the original
type being returned to avoid extra unnecessary allocations. These methods are:Schematic::views_in_collectionSchematic::eager_views_in_collectionSchematic::collections
-
StorageConnection::list_available_schemas/AsyncStorageConnection::list_available_schemas
now return aVec<SchemaSummary>. TheSchemaSummarytype contains
additional information such as what collections and views each schema
contains. -
bonsaidb::cli::Commandnow flattens theservercommand rather than
in-lining theadmincommand. This introduces additional top-level commands
that were previously hidden underneath theservercommand. -
ConnectedClient::all_sessions()is a new function that returns all of the
active sessions for the given client. -
View schemas are now partially deriveble, and have had their map/reduce
functionality split into their own traits. The following notes all apply to
this refactoring:ViewSchema::map()andViewSchema::reduce()have been moved to a new
trait:MapReduce.CollectionViewSchemahas been removed, and themap()andreduce()
functions have been moved to a new trait:CollectionMapReduce.ViewSchema::unique()andViewSchema::lazy()have been replaced with
ViewSchema::update_policy(), which returns a new enum:ViewUpdatePolicy.
This enum contains three variants: Lazy, Eager, and Unique, allowing the same
options that the previous two methods supported without any ambiguities.ViewSchemais now implementable/derivable for all views, regardless of
whether the map/reduce functionality utilizesSerializedCollections or
not.
-
ViewSchema::MappedKey<'doc>is a new associated type with a generic
associated lifetime that enablesmap()/reduce()to utilize borrowed data
for the view's key type. This has caused themap()andreduce()functions
to have new lifetime annotations added. These changes are part of an effort to
support more flows where borrowing data is possible to minimize allocations
while indexing and querying views.For all existing users, setting this associated type to the view's Key type
will work, or pasting this associated type definition in:type MappedKey<'doc> = <Self::View as View>::Key
-
natural_idsupport in theCollectionderive macro has been changed. The
attribute now expects an expression rather than a closure. The expression can
referenceself. This was done to avoid the required type annotations that
the closure approach required.Alternatively,
#[natural_id]can be annotated directly on a field to have it
become the natural id automatically. -
bonsaidb::server::api::Handlerhas had its generic arguments order reversed,
which allows the type to specify a defaultBackendofNoBackend. -
View query APIs now return
CollectionMaptypes instead ofMaptypes. The
change allows for theCollection::PrimaryKeytype to be used instead of
DocumentId. The affected APIs are:bonsaidb::core::connection::View::query()bonsaidb::core::connection::View::query_with_docs()bonsaidb::core::connection::AsyncView::query()bonsaidb::core::connection::AsyncView::query_with_docs()bonsaidb::core::connection::LowLevelConnection::query()bonsaidb::core::connection::LowLevelConnection::query_with_docs()bonsaidb::core::connection::AsyncLowLevelConnection::query()bonsaidb::core::connection::AsyncLowLevelConnection::query_with_docs()MappedDocuments: Bothmappingsanddocumentshave had their types
updated.MappedSerialiedSocuments::deserialized()
Deprecated
bonsaidb::core::connection::ViewMappingsas been moved to
bonsaidb::core::schema::view::ViewMappings. A deprecated re-export has been
provided to minimize code breakage when upgrading.
Added
-
#239
Keycan now be derived on enums and structs, allowing an easier way
to use composite keys. Theprimary-keysexample has been updated to use the
derive macro instead of a tuple for the composite key. -
Keyis now implemented forResult<T,E>, where T and E both implementKey
andKeyEncodingusing the same error type. -
Keyis now implemented forCow<'a, str>. -
Keyis now implemented forisizeandusize. This is implemented using
variable integer encoding, allowing for proper cross-architecture behavior.
When trying to decode a value that is too large for the given target
architecture, an error will be returned. -
Keyis now implemented forNonZeroU*andNonZeroI*types, wrapping the
inner type's encoding functionality and adding extra checks for 0 values. For
signed types,next_value()will skip 0. -
bonsaidb::core::key::KeyFormatis a newtransmog::Formatthat can be used
as aSerializedCollection::Formatassociated type. This implements
serialization using theKeytrait rather than Serde.When deriving the
Collectiontrait, specifyingserialization = Keywill
use this format. -
ViewSchemacan now be derived. -
bonsaidb_core::Error::is_unique_key_error()is a convenience function to
quickly check if an error is a result of a unique key violation from a
specific view. -
bonsaidb_core::Error::conflicting_document()is a convenience function to
return the conflicting document's header if the error is a conflict from a
specific collection. -
Operation::Checkis a new operation that can be performed during a
transaction. It checks whether a document exists in a given collection, and
optionally can verify that a revision matches the currently stored revision.These constructor functions provide more ergonomic ways to create this variant:
Operation::check_document_id_exists(CollectionName,DocumentId)Operation::check_document_exists<Collection>(Collection::PrimaryKey)Operation::check_document_is_current(&impl HasHeader)
-
Storagenow acquires an exclusive lock to ensure multiple instances are not
able to be opened at the same time. This lock is held across all locations the
database is accessed, including background threads. -
bonsaidb-filesis a new crate that enables storing large files in BonsaiDb,
and includes abstractions for reading/writing files using common
traits:std::io::Readstd::io::Seekstd::io::Writetokio::io::AsyncReadtokio::io::AsyncSeektokio::io::AsyncWriteIterator<Item = std::io::Result<Vec<u8>>>futures::Stream<Item = std::io::Result<Vec<u8>>>
This crate can be added directly to your project, or if you're using the
omnibus crate, featurefileswill enable this crate atbonsaidb::files. -
SerializedCollection::push_all[_async]()is a new function that accepts an
iterator of document contents to push into the database using a single
transaction. It returns the created collection documents if successful. If any
errors occur, no documents will be inserted. -
ViewSchema::lazy()/CollectionViewSchema::lazy()are provided functions
that return true by default. This preserves the existing behavior for
map/reduce views -- they are only updated when queried, and as dictated by the
AccessPolicy. By returning false, a view can become eagerly updated, which
means that the views are fully updated by the time each transaction completes.This was how unique views already functioned, but now users who have workflows
where an eagerly-updated view will be more efficient than a lazy view can
opt-in to this behavior. -
bonsaidb::server::cli::Commandhas a new function,execute_onwhich
accepts an already constructed server instance. -
ServerDatabase,AnyDatabase, andAnyConnectionnow all implementClone
andDebug. -
DefaultPermissionsnow implementsFrom<Vec<Statement>>and
From<Statement>, enabling simpler usage when usingdefault_permissions()
andauthenticated_permissions(). -
[Async]StorageConnection::authenticate_with_passwordare new functions
providing a simpler interface for authenticating with a username/user id and
password. -
[Async]StorageConnection::authenticate_with_tokenis a new function that
allows authenticating with a previously createdAuthenticationToken.Token authentication is an optional feature, enabled with the
token-authenticationfeature. This feature is currently powered by
BLAKE3, but has been written to be
able to support multiple algorithms.An
AuthenticationTokenis a randomly generated id, a private token, and an
identity that are used to perform a cryptographically secure verification
during authentication without transferring the private token to the server.
Upon successful authentication, the identity is assumed on the newly returned
connection. This supports both assuming users and roles. -
The
Apitrait can now be derived. -
SerializedViewhas two new methods:entriesandentries_async, which
enable a "Type-first" query pattern. These two statements produce the same
results:let mappings = MyView::entries(&db).query()?; let mappings = db.view::<MyView>().query()?;
These new APIs are provided purely for style preference considerations.
-
LimitedResolutionDurationnow has a functionchecked_add()supports
iter::Sum intoOption<LimitedResolutionDuration<T>>or
LimitedResolutionDuration<T>. The option-wrapped version does a checked
operation, and the other will panic if the result of the operation is not
representable by theLimitedResolutionDuration. -
BonsaiListenConfigis a new structure that controls the settings of the
BonsaiDb network protocol server socket. This structure currently allows
specifying the specificSocketAddrto listen on and whether the
SO_REUSEADDRflag should be specified on the underlying socket. -
CollectionDocumentnow implements Serialize and/or Deserialize if both
PrimaryKeyandContentsare Serialize and/or Deserialize, respectively. -
Backend::client_session_endedis a new function that is invoked any time a
connected client's session is ending. -
VarInt<T>is a new type that implementsKeyusing theordered-varint
crate. This allows using types such asVarInt<u64>instead ofu64to
reduce the number of bytes encoded keys consume on average. -
SerializedCollectionnow hasinsert_in_transaction(),
push_in_transaction(), andoverwrite_in_transaction()which are new
helpers that help writing transactional code easier by creating and pushing
theOperationsin one step. -
CollectionDocument<T>now hasupdate_in_transaction()and
delete_in_transaction()which are new helpers that help writing
transactional code easier by creating and pushing theOperationsin one
step. -
Client's builder now has two additional settings:request_timeoutand
connect_timeout. If not specified, both timeouts are 60 seconds. Thank you
to @phantie for requesting these settings in #296. -
CollectionDocument::refresh()/CollectionDocument::refresh_async()are new
methods that reload the document from the database. -
ConnectedClient::connected()is a new function that returns the current
state of whether the client is still connected. BecauseConnectedClientis
able to be cloned and sent between threads, this allows other threads to
notice when clients have disconnected without needing to be notified via the
Backend.
Changed
bonsaidb::cli::Command::Servernow callsCommandLine::open_server()rather
than constructing the server directly. This allows CommandLine implementors to
useopen_serveras a location to launch extra services upon server startup.bonsaidb::cli::Argsandbonsaidb::cli::Command::executenow accept a token
id or a username, allowing for commands to be executed with authentication if
the features are enabled.bonsaidb::local::cli::Commandnow offers the ability to create a user and
set a user's password.bonsaidb::local::cli::adminis a newly exposed module that allows some basic
user management. This set of commands is also available on
bonsaidb::cli::Commandthrough theAdminvariant, allowing for both local
and remote administration.Header,CollectionHeader, andRevisionnow all implementHash.- Database names are no longer case insensitive. This was implemented poorly,
and in hindsight, the feature was removed in favor of strictness. Because the
database name is used as a directory name on-disk, care must be taken on
case-insensitive filesystems to not attempt to create two databases with
different casing. TimedArgonParametersnow guarantees that the minimum parameters chosen will
meet theOWASPrecommendations. Manual configuration still is allowed to set
exact parameters.
Fixed
- Unique views/eager views now are properly updated when an overwrite operation
is performed that resulted in a new document being created. - Argon2 ram configuration is now correctly applied. Previously, the memory cost
was being supplied in bytes, but the underlying API was expecting kilobytes. - When a View's version has changed, the view is now fully cleaned before
reindexing. Previously, BonsaiDb was lazily cleaning up the entries, which led
to slower reindexing and disk bloat. - Fixed the
sourcefield of mappings returned from a View query when a
document was updated but emitted the same key. Previously the value was
correctly updated, but the source's revision was not updated. - When querying a View with
AccessPolicy::NoUpdate, the integrity scanner is
now checked and waited upon before allowing access to the view. - When querying a View with
AccessPolicy::UpdateAfter, the update task is no
longer blocked until complete. CustomServer::listen_for_shutdown()now listens for
CustomServer::shutdown()in addition to operating system signals.Clientwill no longer return aSessionfrom a previous connection. Because
theClientautomatically reconnects, theSessions are no longer
authenticated.CustomServer::shutdownnow fully shuts down the server by forcefully
disconnecting clients after the optional grace period has elapsed.
Additionally, QUIC-connected workers are sent the proper disconnection
notification.- The
Keygeneric parameter toOperation::overwrite_serializedis now used
in the function definition. Because previouslyC::PrimaryKeywas hard-coded,
any existing code should work as long as the correctKeytype was provided.
This fix also allows for types likestrto be used instead ofStringwith
this function. - Limited case insensitivity was implemented incorrectly yielding inconsistent
results. CustomServer::listen_onno longer will return an error if an incoming
connection fails during the TLS or QUIC handshake. Thank you to @phantie for
reporting this in #296.