All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
The Minimum Supported Rust Version (MSRV) has been changed to 1.64.
-
All features in the
bonsaidbcrate have been updated to support the new features in Rust 1.60. Instead of needing separate flags forclient-websocketsandserver-websockets, a single feature flagwebsocketsis now able to work in conjunction with theclient/serverfeatures 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
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's
PrimaryKeyisString,&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::bonsaitobonsaidb::core::connection -
ApiNamehas been moved frombonsaidb::core::schematobonsaidb::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.BonsaiListenConfigimplementsFrom<u16>to minimize code breakage. -
The command-line
Servetype has had itslisten-onfield changed to aSocketAddrtype 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,BlockingClienthas been added. This splits theClientinto two separate parts: anasyncversion 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
RemoteDatabaseandRemoteSubscriber: 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 allowsfrom_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 usingVec<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 theKeyderive.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_schemasnow 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.
-
#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 implementKeyandKeyEncodingusing 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. -
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, feature
fileswill 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 theAccessPolicy. 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 implementCloneandDebug. -
DefaultPermissionsnow implementsFrom<Vec<Statement>>andFrom<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>>orLimitedResolutionDuration<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 theSO_REUSEADDRflag should be specified on the underlying socket. -
CollectionDocumentnow implements Serialize and/or Deserialize if bothPrimaryKeyandContentsare 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-varintcrate. This allows using types such asVarInt<u64>instead ofu64to reduce the number of bytes encoded keys consume on average.
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 onbonsaidb::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.
- 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 forCustomServer::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.
-
The View indexing system had a bug when deleting the last view entries for a key while also inserting new entries for that key in the same mapping update operation. This prevented the recording of new entries being made during that mapping operation. This bug was introduced during the optimizations in v0.3.0.
All views will be reindexed automatically on upgrade.
-
insert_bytes/push_bytesno longer requireSerializedCollectionto be implemented.
-
BonsaiDb now has both an async interface as well as a blocking interface. This has caused significant changes, but they can be summarized simply:
-
Connection-related async-compatible traits have had the
Asyncprefix added to them.Blocking Async Connection AsyncConnection StorageConnection AsyncStorageConnection PubSub AsyncPubSub Subscriber AsyncSubscriber KeyValue AsyncKeyValue LowLevelConnection AsyncLowLevelConnection -
Functions that take parameters of the above traits now are offered in pairs: a blocking function and an async function with "_async" at the end of the name. For example,
SerializedCollection::get()is the blocking version ofSerializedCollection::get_async(). -
For
bonsaidb-local, theDatabaseandStoragetypes are now blocking implementations. Under the hood, BonsaiDb previously usedtokio::task::spawn_blocking()to wrap calls to the database in an async API. New types,AsyncDatabaseandAsyncStoragehave been added that provide the previous behavior. The types can be converted between each other using helpers as/into/to_blocking/async available on each type.These changes allow
bonsaidb-localto be compiled without Tokio. To enable tokio, enable featureasyncif usingbonsaidb-localdirectly, or enable featurelocal-asyncwhen using thebonsaidbcrate. -
For
bonsaidb-server, it still uses networking driven by Tokio.Server/CustomServerimplementAsyncStorageConnection, andServercan convert toStoragevia theFromtrait for synchronous database access. -
For
bonsaidb-client,Clientimplements bothAsyncStorageConnectionandStorageConnectionand is safe for use in both synchronous and asynchronous contexts. In WASM,Clientonly implementsAsyncStorageConnection. For all other platforms, theClientbuilder supports specifying the Tokio runtime handle if needed. Otherwise, the current runtime will be used or a default runtime will be created automatically if unavailable.
-
-
Connection::query_with_docs/Connection::query_with_connection_docsnow verify the user has permission toDocumentAction::Get. This allows schema authors to allow querying views without allowing the documents themselves to be fetched. -
ViewAction::DeleteDocshas been removed. Delete docs is now composed of two permissions checks:ViewAction::Queryto retrieve the list of documents to delete, andDocumentAction::Deletefor each document retrieved. This ensures if permission is denied to delete a specific document, it still cannot be deleted throughdelete_docs(). -
All APIs have had their
limitparameters changed fromusizetou32. Sinceusizeis platform-dependent, picking a fixed-width type is more appropriate. -
CustomApihas been renamed toApiand changed significantly.On the Server,
Apis are registered on theServerConfiguration. TheApiimplementor is treated as the "request" type and is whatClients send to the Server. TheApi::Responsetype is what the Server sends to theClient. Out-of-band responses can still be delivered.On the Client,
Apis can simply be used without any extra steps. If you expect out-of-band responses, callbacks can be registered when building the client.Internally, all BonsaiDb APIs have been refactored to use this -- there is no distinction.
-
The
multiuserfeature flag has been removed. In the end this caused a lot of needless conditional compilation for removing a single lightweight dependency. -
User::assume_identityandRole::assume_identityallow assuming the identity of a user or role by their unique ID or name. The connection must be permitted with the newly addedServerAction::AssumeIdentityfor the appropriate resource name (user_resource_nameorrole_resource_name). -
StorageConnection::authenticateandStorageConnection::assume_identityboth return a new instance with the new authentication. This enables authenticating as multiple roles with the same underlying storage connection.StorageConnection::session()is a new function that returns the currentSession, if one exists. This new type contains information about any currently authenticated identity, the unique id of the session, and the current effective permissions.This release note applies equally to
AsyncStorageConnection. -
LowLevelConnectionandAsyncLowLevelConnectionhave been added to group functionality that is not generally meant for the average user to utilize. The methods that were documented as low-level inConnection/AsyncConnectionhave been moved to this trait. Additionally, new methods that allow performing operations without the generic types have been added to this trait. This functionality is what will be useful in providing applications that can interact with BonsaiDb without having the Schema definitions available. -
PubSub/AsyncPubSubnow allows anySerializeimplementation to be used as the topic parameter. New methodspublish_bytesandpublish_bytes_to_allhave been added enabling publishing raw payloads. -
CollectionName/SchemaNamehave had common methods extracted to a trait,Qualified. This was part of a refactoring to share code between these two types and the newly introducedApiNametype. -
BackupLocationandVaultKeyStoragehave been changed to blocking traits.bonsaidb-keystorage-s3wraps a tokio Runtime handle as the AWS SDK requires Tokio. -
ServerConfigurationnow takes aBackendgeneric parameter, which must match theCustomServerbeing created. In general the Rust compiler should be able to infer this type based on usage, and therefore shouldn't be a breaking change to many people. -
The
Backendtrait now has an associatedErrortype, which allows for custom error types to be used. When an error occurs during initialization, it is returned. Currently, errors that are returned during client connection handling are printed usinglog::errorand ignored. -
Keyhas had its encoding functionality moved to a new trait,KeyEncoding.KeyEncodinghas been implemented for borrowed representations ofKeytypes.This change allows all view query and collection access to utilize borrowed versions of their key types. For example, if a View's
Keytype isString, it is now possible to query the view using an&strparameter.
-
Range::default()now returns an unbounded range, andBound::default()returnsBound::Unbounded. -
Rangenow has several builder-pattern style methods to help construct ranges. In general, users should simply use the built-in range operators (..,start..,start..end,start..=end), as they are able to represent nearly every range pattern. The built-in range operators do not support specifying an excluded start bound, while the new methodRange::afterallows setting an excluded start bound. -
#215:
StorageConnection::delete_user()is a new function that allows deleting a user by name or id. Deleting a user is permitted with theServerAction::DeleteUseraction. -
bonsaidb_core::key::encode_composite_fieldandbonsaidb_core::key::decode_composite_fieldhave been added which allow building more complexKeyimplementations that are composed of multiple fields. These functions are what theKeyimplementation for tuples is powered by. -
Keyis now implemented for[u8; N]. -
#221:
headers()has been as a function to all collection list builders, enabling querying just the headers of a document. -
Transactionnow hasapply()andapply_async(), which the higher-level API toLowLevelConnection::apply_transaction. -
ArgonConfigurationcan now be specified when buildingStorageConfiguration/ServerConfigurationusingBuilder::argon. -
SystemTimeandDurationnow haveKeyimplementations. -
bonsaidb_core::key::timehas been added which contains a wide array of types that enable storing timestamps and durations with limited resolution, powered by variable integer encoding to reduce the number of bytes needed to encode the values.These types are powered by two traits:
TimeResolutionandTimeEpoch. Using these traits, theLimitedResolutionDurationandLimitedResolutionTimestamptypes can be used for completely custom resolutions (e.g., 15 minutes) and epochs (the base moment in time to store the limited resolution relative to).By constraining the resolution and using an epoch that is closer to the average timestamp being stored, we can reduce the number of bytes required to represent the values from 12 bytes to significantly fewer.
These type aliases have been added in these three categories:
- Durations:
Weeks,Days,Hours,Minutes,Seconds,Milliseconds,Microseconds, andNanoseconds. - Timestamps relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC):
WeeksSinceUnixEpoch,DaysSinceUnixEpoch, ... - Timestamps relative to the Bonsai Epoch (Mar 20, 2031 04:31:47 UTC):
TimestampAsWeeks,TimestampAsDays, ...
- Durations:
-
Backend::configure()is a new function that allows aBackendto set configuration options onServerConfigurationbefore the server is initialized. This is a good location forBackends to define theirApis andSchemas.
- Counting a list of documents now uses
reduce()in Nebari, a new feature that allows aggregating the embedded statistics without traversing the entire tree. The net result is that retrieving a Collection's count should be near instant and returning the count of a range of keys should be very fast as well. StorageConnection::create_database/AsyncStorageConnection::create_databasenow returns the newly created database.
- Defining multiple views with the same name for the same collection will now return an error.
-
bonsaidb::local::jobsis now private. It used to be a separate, public crate in the PliantDb days. After thinking about the job scheduler more, this initial implementation is better suited for the internal task management than the higher-level jobs system. As such, it has been internalized. -
bonsaidb::core::transaction::Changes::Documentshas been changed to store theCollectionNames separately from theChangedDocuments. This makes the transaction log entries smaller, as collection names aren't copied for each document.The storage layer is fully backwards compatible and will automatically convert existing transactions to the new format.
- Listing executed transactions that were written in
v0.1was broken inv0.2. Backwards compatibility is now automatically tested to help ensure this sort of issue won't happen in the future again.
-
SerializedCollection::list_with_prefix,connection::Collection::list_with_prefix, andconnection::View::with_key_prefixhave been added as an easy way to filter results based on whether the key starts with the given prefix.This is supported by a new trait,
IntoPrefixRange. This trait has been implemented for all byte-based key implementations as well as forString. -
Operation::push_serializedhas been added, which callsnatural_idbefore creating anOperation::Insertvariant. -
Tasks::parallelizationandBuilder::workers_parallelizationhave been added as a way to control how many threads can be used by any given task/worker. This is automatically configured to be the number of cpu cores detected. -
count()is a new function on the list builders, available via:SerializedCollection::all(db).count().awaitSerializedCollection::list(42.., db).count().awaitdb.collection::<Collection>().all().count().awaitdb.collection::<Collection>().list(42..).count().await
The performance of this call is not as good as it will eventually be, as it is currently doing more work than strictly necessary.
-
#215:
StorageConnection::delete_userhas been added, enabling deletions of users without directly interacting with theadmindatabase.
- The view map/reduce system has been optimized to take advantage of some parallelism. The view system is still not hightly optimized, but this change makes a significant improvement on performance.
-
bonsaidb::core::Error::DocumentConflictnow contains aHeaderinstead of just the document's ID. This allows an application to re-submit an update with the updated header without another request to the database. -
StorageConfiguratation::vault_key_storagenow uses anArcinstead of aBox. This change allowsStorageConfigurationandServerConfigurationto implementClone. -
Document::create_new_revisionhas been removed. It was meant to be an internal function. -
Documentnow requiresAsRef<Header>andAsMut<Header>instead ofDeref<Header>/DerefMut. The publicly visible change is that the shortcut of accessingdocument.header.emit_*through deref by usingdocument.emit_*will no longer work. This impactsCollectionDocument,OwnedDocument, andBorrowedDocument.This removes a little magic, but in some code flows, it was impossible to use Deref anyways due to Deref borrowing the entire document, not just the header.
-
Collection::PrimaryKeyis a new associated type that allows customizing the type that uniquely identifies documents inside of aCollection. Users of the derive macro will be unaffected by this change. If you're upgrading existing collections and wish to maintain backwards compatibility, useu64as the type.A
natural_id()function can now be implemented onSerializedCollectionorDefaultSerializationwhich allows extracting a primary key value from a new document being pushedA new example,
primary-keys.rs, as been added showing basic usage of changing the primary key type. This change resulted in a sequnce of breaking changes that will be listed independently. -
Keyhas been moved frombonsaidb::core::schema::viewtobonsaidb::core::key. -
Key::as/from_big_endian_byteshave been renamed toKey::as/from_ord_bytes. -
Key::first_value()andKey::next_value()are new provided functions. By default, these functions returnNextValueError::Unsupported.Key::first_value()allows aKeytype to define the first value in its sequence. For example,0_u64is the result ofu64::first_value().Key::next_value()allows aKeytype to find the next value in sequence from the current value. Implementors should never wrap, and should instead returnNextValueError::WouldWrap.Sensible defaults have been implemented for all numeric types.
-
Connectionand its related types have had all previously hard-coded primary keys pfu64changed to generic parameters that can accept either aDocumentIdorCollection::PrimaryKey. The affected methods are:Connection::insertConnection::overwriteConnection::getConnection::get_multipleConnection::listconnection::Collection::insertconnection::Collection::overwriteconnection::Collection::getconnection::Collection::get_multipleconnection::Collection::listSerializedCollection::insertSerializedCollection::insert_intoSerializedCollection::overwriteSerializedCollection::overwrite_intoSerializedCollection::getSerializedCollection::get_multipleSerializedCollection::listtransaction::Operation::insert_serializedtransaction::Operation::overwrite_serialized
-
Header::idhas changed fromu64toDocumentId, andCollectionHeader<PrimaryKey>has been added which containsCollection::PrimaryKeydeserialized.These previous usages of
Headerhave been changed toCollectionHeader:Connection::insertresult typeConnection::overwriteresult typeconnection::Collection::insertresult typeconnection::Collection::insert_bytesresult typeconnection::Collection::pushresult typeconnection::Collection::push_bytesresult typeCollectionDocument::header
The
Header::emit*functions have been moved to a new trait,Emit. This trait is implemented by bothHeaderandCollectionHeader. The functions moved are:emit()emit_key()emit_value()emit_key_and_value()
These functions now return a
Result, as encoding a primary key value can fail if it is larger thanDocumentId::MAX_LENGTH. -
HasHeaderis a new trait that allows accessing aHeadergenerically from many types. This type is used inConnection::deleteandconnection::Collection::delete. -
Types and functions that used
u64as a document ID have been replaced withDocumentIds. The number of locations are too many to list. If you need to convert from a u64 to aDocumentId, you can useDocumentId::from_u64(). -
Document::contentsandDocument::set_contentsare now ore "painful" to access due to the generic parameter added toDocument.SerializedCollection::document_contents(doc)andSerializedCollection::set_document_contents(doc, new_contents)have been provided as easier ways to invoke the same functionality. For example:let contents = doc.contents::<MyCollection>()?;
Becomes:
let contents = MyCollection::document_contents(&doc)?;
-
Backups made prior to
0.2.0will not be able to be restored with this updated version. The document IDs are encoded differently than in prior versions.
-
Optional compression is now available, using the LZ4 algorithm.
StorageConfiguration::default_compressioncontrols the setting. When using thebonsaidbcrate, the feature can be made available using eitherlocal-compressionorserver-compression. When usingbonsaidb-serverorbonsaidb-localdirectly, the feature name iscompression.This compression is currently applied on all chunks of data written to BonsaiDb that are larger than a hardcoded threshold. This includes the Key-Value store. The threshold may be configurable in the future.
Some of the benchmark suite has been expanded to include comparisons between local storage with and without compression.
-
Added ability to "overwrite" documents without checking the stored revision information. Because this removes a layer of safety, it has its own permissible action:
DocumentAction::Overwrite. The functions that have been added are:connection::Connection::overwriteconnection::Collection::overwriteschema::SerializedCollection::overwriteschema::SerializedCollection::overwrite_intodocument::CollectionDocument::overwritetransaction::Transaction::overwritetransaction::Operation::overwrite
-
Internal dependencies between crates are now pinned based on their needs. This means that
bonsaidb-severwill require a matching verison ofbonsaidb-localwhen compiling. A simple example of a change that is a breaking compilation change but is not breaking from a compatibility standpoint is a change to a structure where#[serde(rename)]is used to remap an old value to a new value.The only crate currently not pinning its dependencies is
bonsaidb-keystorage-s3. This crate, and hopefully many crates to come, are only tying themselves to the public API of BonsaiDb.This may generate slightly more crate updates than absolutely necessary, but for a small team it seems like the most manageable approach.
- The view system now tracks an internal version number in addition to the version specified in the view definiton. This allows internal structures to be upgraded transparently.
- Applying a transaction to a collection with a unique view now ensures a view mapping job has finished if the view's integrity check spawns one before allowing the transaction to begin.
- #196: Fixed a panic a user reported relating to an undocumented panic
within
tokio::time::sleep().
-
SchemaName:privateandCollectionName::privateare two new constructors that allow defining names without specifying an authority. Developers creatingreusable collections and/or schemas should not use these methods as namespacing is meant to help prevent name collisions. -
connection::Collection::all()andSchemaCollection::all()have been implemented as simple wrappers aroundlist(..). -
#146, #187: The
Schema,Collection, andViewtraits can now be derived rather than manually implemented:#[derive(Debug, Schema)] #[schema(name = "my-schema", collections = [Shape])] struct MySchema; #[derive(Debug, Serialize, Deserialize, Collection)] #[collection(name = "shapes", views = [ShapesByNumberOfSides])] struct Shape { pub sides: u32, } #[derive(Debug, Clone, View)] #[view(collection = Shape, key = u32, value = usize, name = "by-number-of-sides")] struct ShapesByNumberOfSides;
-
Memory-only instances of Storage can be created now. This is primarily intended for testing purposes.
- Inline examples have been added for every
connection::Collectionandconnection::Viewfunction. - All examples have been updated to the new derive macro syntax. Additionally, documentation and examples for deriving Schema, Collection, and View have been added to the respective traits.
bonsaidb::local::adminnow exposes collections that are used to manageBonsaiDb.- Ability to add users, set a user's password, and log in as a user.
- Each
bonsaidb::local::Storagenow has a unique ID. It will be randomly generated upon launch. If for some reason a random value isn't desired, it can be overridden in theConfiguration. - Centralized secrets vault: Enables limited at-rest encryption. See
bonsaidb::core::vaultfor more information. - For serializable types,
Collectionnow defines easier methods for dealing with documents.NamedCollectionallows collections that expose a unique name view to have easy ways to convert between IDs and names. - Server
Backendtrait now defines connection lifecycle functions that can be overridden to customize behavior when clients connect, disconnect, or authenticate. Clientnow has abuild()method to allow for customizing connections.CustomApiresponses can now be sent by the server viaConnectedClient::send(). The client can now register a callback to receive out-of-band responses.Backendhas a new associated type,CustomApiDispatcherwhich replacesServer::set_custom_api_dispatcher. This change allows custom api dispatchers to receive theserverorclientduring initialization if needed. For example, if a custom API needs to know the caller's identity, you can store theclientin your dispatcher and access it in your handlers.Backendhas a new associated type:ClientData. This associated type can be used to associate data on a per-ConnectedClientbasis.ServerConfigurationhas a new setting:client_simultaneous_request_limit. It controls the amount of query pipelining a single connection can achieve. Submitting more queries on a single connection will block reading additional requests from the network connection until responses have been sent.ServerConfigurationnow supportsauthenticated_permissions, allowing a set of permissions to be defined that are applied to any user that has successfully authenticated.CollectionViewis a new trait that can be implemented instead ofView. Themap()function takes aCollectionDocumentparameter that is already deserialized for you.bonsaidb_corenow has two new macros to ease some tedium of writing simple views:define_basic_mapped_viewanddefine_basic_unique_mapped_view.- BonsaiDb now uses
loginternally to report errors that are being ignored or happened in a background task. - Multiple crates now offer an "instrument" feature which enables
instrumentation using the
tracingecosystem. - Moved all
database()functions toStorageConnection. This allows fully generic code to be written against a "server". - Added
listen_for_shutdown()which listens for SIGINT and SIGQUIT and attemps to shut the server down gracefully. - Automatic TLS certificate acquisition can be performed using ACME on TCP port 443. This is automatically performed if the feature flag is enabled.
- BonsaiDb server can now listen for generic TCP connections with and without
TLS. This is primarily designed to allow extending the HTTP port to support
additional HTTP endpoints than just websockets. However, because the TLS
certificate aquired on port 443 can be used in other protocols such as SMTP,
it can be useful to allow BonsaiDb to control the networking connections.
listen_for_tcp_onandlisten_for_secure_tcp_onaccept a parameter that implements theTcpServicetrait. See the Axum example for how this integration can be used in conjunction with websockets. - Added convenience methods to
TransactionandOperationto make it easier to build multi-operation transactions. - The
Keytrait is now automatically implemented for tuples of up to 8 entries in length. CollectionDocument::modify()enables updating a document using a flow that will automatically fetch the document if a conflict is detected, re-invoking the callback to redo the modifications. This is useful for situations where you may have cached a document locally and wish to update it in the future, but don't want to refresh it before saving. It also will help, in general, with saving documents that might have some contention.CustomServer::authenticate_client_as()allows setting aConnectedClient's authenticated user, skipping BonsaiDb's authentication. This allows developers to still utilize the users and permissions within BonsaiDb while authenticating via some other mechanism.SerializedCollection::list()andSerializedCollection::get_multiple()have been added to make it easier to retrieveCollectionDocument<T>s.
-
Configuration has been refactored to use a builder-style pattern.
bonsaidb::local::config::Configurationhas been renamedStorageConfiguration, andbonsaidb::server::ServerConfigurationhas been renamedServerConfiguration. -
Database::open_localandStorage::open_localhave been renamed toopen. -
Database::open,Storage::open, andServer::openno longer take a path argument. The path is provided from the configuration. -
Listing all schemas and databases will now include the built-in admin database.
-
The underlying dependency on
sledhas been changed for an in-house storage implementationnebari. -
The command-line interface has received an overhaul.
- A new trait,
CommandLinecan be implemented on a type that implementsBackendto utilize the built-in, extensible command line interface. An example of this is located at./examples/basic-server/examples/cli.rs. - The parameter types to
execute()functions have changed. - This interface will receive further refinement as part of switching to clap 3.0 once it is fully released.
- A new trait,
-
View::mapnow returns aMappingsinstead of anOption, allowing for emitting of multiple keys. -
View mapping now stores the source document header, not just the ID.
-
ServerConfiguration::default_permissionshas been changed into aDefaultPermissionsenum. -
Changed the default serialization format from
CBORto an in-house format,Pot. -
Keynow has a new associated constant:LENGTH. If a value is provided, the result of converting the value should always produce the length specified. This new information is used to automatically implement theKeytrait for tuples. -
The
Keyimplementation forEnumKeyhas been updated to useordered-varintto minimize the size of the indexes. Previously, each entry in the view was always 8 bytes. -
ConnectionandSerializedCollectionhave had theirinsert/insert_intofunctions modified to include an id parameter. New functions namedpushandpush_intohave been added that do not accept an id parameter. This is in an effort to keep naming consistent with common collection names in Rust. -
Operation::insertandCommand::Insertnow take an optional u64 parameter which can be used to insert a document with a specific ID rather than having one chosen. If an document exists already, a conflict error will be returned. -
bonsaidb::local::backuphas been replaced withStorage::backupandStorage::restore. This backup format is incompatible with the old format, but is built with proper support for restoring at-rest encrypted collections. Backups are not encrypted, but the old implementation could not be updated to support restoring the documents into an encrypted state.This new functionality exposes
BackupLocation, an async_trait that enables arbitrary backup locations. -
KeyValuestorage has internally changed its format. Because this was pre-alpha, this data loss was premitted. If this is an issue for anyone, the data is still there, the format of the key has been changed. By editing any database files directly using Nebari, you can change the format from "namespace.key" to "namespace\0key", where\0is a single null byte. -
ExecutedTransactions::changesis now aChangesenum, which can be a list ofChangedDocuments orChangedKeys. -
The Key-Value store is now semi-transactional and more optimized. The behavior of persistence can be customized using the
key_value_persistenceoption when opening a BonsaiDb instance. This can enable higher performace at the risk of data loss in the event of an unexpected hardware or power failure. -
A new trait,
SerializedCollection, now controls serialization withinCollectionDocument,CollectionView, and other helper methods that serialized document contents. This allows any serialization format that implementstransmog::Formatcan be used within BonsaiDb by setting theFormatassociated type within yourSerializedCollectionimplementation.For users who just want the default serialization, a convenience trait
DefaultSerializationhas been added. All types that implement this trait will automatically implementSerializedCollectionusing BonsaiDb's preferred settings. -
A new trait,
SerializedView, now controls serialization of view values. This uses a similar approach toSerializedCollection. For users who just want the default serialization, a convenience traitDefaultViewSerializationhas been added. All types that implement this trait will automatically implementSerializedViewusing BonsaiDb's preferred settings.The
view-histogramexample has been updated to define a customtransmog::Formatimplementation rather creating a Serde-based wrapper. -
Viewhas been split into two traits to allow separating client and server logic entirely if desired. TheViewSchematrait is wheremap(),reduce(),version(), andunique()have moved. If you're using aCollectionView, the implementation should now be a combination ofViewandCollectionViewSchema. -
CollectionName,SchemaName, andNameall no longer generate errors if using invalid characters. When BonsaiDb needs to use these names in a context that must be able to be parsed, the names are encoded automatically into a safe format. This change also means thatView::view_name(),Collection::collection_name(), andSchema::schema_name()have been updated to not return error types. -
The
Documenttype has been renamed toOwnedDocument. A trait namedDocumenthas been introduced that contains most of the functionality ofDocument, but is now implemented byOwnedDocumentin addition to a new type:BorrowedDocument. Most APIs have been updated to returnOwnedDocuments. The View mapping process receives aBorrowedDocumentwithin themap()function.This refactor changes the signatures of
ViewSchema::map(),ViewSchema::reduce(),CollectionViewSchema::map(), andCollectionViewSchema::reduce().The benefit of this breaking change is that the view mapping process now can happen with fewer copies of data.
-
A new function,
query_with_collection_docs()is provided that is functionally identical toquery_with_docs()except the return type contains already deserializedCollectionDocument<T>s. -
Moved
CollectionDocumentfrombonsaidb_core::schematobonsaidb_core::document. -
Due to issues with unmaintained crates, X25519 has been swapped for P256 in the vault implementation. This is an intra-alpha breaking change. Use the backup functionality with the existing version of BonsaiDb to export a decrypted version of your data that you can restore into the new version of BonsaiDb.
If you have encryption enabled but aren't actually storing any encrypted data yet, you can remove these files from inside your database:
mydb.bonsaidb/master-keysmydb.bonsaidb/vault-keys/(or remove the keys from your S3 bucket)
-
query_with_docs()andquery_with_collection_docs()now return aMappedDocumentsstructure, which contains a list of mappings and aBTreeMapcontaining the associated documents. Documents are allowed to emit more than one mapping, and due to that design, a single document can be returned multiple times.
- Adding two collections with the same name now throw an error.
-
View::unique()has been added, allowing for aViewto restrict saving documents when multiple documents would end up with the same key emitted for this view. For example, if you have aUsercollection and want to ensure eachUserhas a uniqueemail_address, you could create aViewwith the key ofemail_addressand return true fromunique(), andBonsaiDbwill enforce that constraint. -
Permissions support has been added across the platform with granular access. The
bonsaidb::core::permissionsmodule contains the data types involved. More documentation and examples are to-come -- users and roles haven't been added yet. -
The initial underpinnings of customizing the
BonsaiDbserver have been added. First, there's theBackendtrait. Right now, its only purpose is to allow defining aCustomApi. This allows applications built withBonsaiDbto extend the network protocol withRequestandResponsetypes that just need to support Serde. For a full example, check out this in-developmentGooeyexample. -
An initial version of a WebAssembly client is now supported. It only supports WebSockets. While there has been news of
QUICsupport in the browser, it's a limited implementation that only exposes an HTTP protocol. As such, it is incompatible with theBonsaiDbprotocol. Eventually, we hope to supportWebRTCas an alternative to TCP in WebAssembly. The example linked in the previous bullet point can be built and loaded in a browser.