Changelog¶
All notable changes to the Multicloud DB SDK modules.
The format is based on Keep a Changelog, and all modules adhere to Semantic Versioning.
multiclouddb-api¶
[Unreleased]¶
Documentation:
MulticloudDbClient.delete(...)is documented as idempotent — silent on missing key. The Javadoc now declares that deleting a key that does not exist is a silent no-op on every provider, which is the true LCD across Cosmos (404 swallowed), DynamoDB (DeleteItemis idempotent natively) and Spanner (Mutation.deleteis idempotent natively). Callers that need to detect a missing key should useMulticloudDbClient.read(...), which returnsnullon every provider when the key does not exist (non-mutating).update()also throwsNOT_FOUNDon a missing key, but it requires a document body and overwrites on hit, so it is not a safe pure existence probe.
[0.1.0-beta.1] - 2026-04-23¶
Added:
MulticloudDbClientConfig.Builder.userAgentSuffix(String)- optional caller-supplied token appended to the SDK user-agent header sent by all provider clients.MulticloudDbClientConfig.userAgentSuffix()- accessor returning the configured suffix, ornullif unset.com.multiclouddb.spi.SdkUserAgent- SPI helper that builds the canonicalmulticlouddb-sdk-java/<version>user-agent token.MulticloudDbClient- synchronous, provider-agnostic interface for CRUD, query, and schema provisioningMulticloudDbClientFactory- discovers provider adapters viaServiceLoaderMulticloudDbClientConfig- immutable builder-pattern configurationQueryRequest- portable expression or native expression passthrough with named parameters, pagination, partition key scoping, limit, and orderByMulticloudDbKey- portable(partitionKey, sortKey)identityResourceAddress-(database, collection)targeting- Portable expression parser, validator, and translator SPI
CapabilitySet- runtime capability introspectionMulticloudDbException- structured error model with portable categoriesOperationDiagnostics- latency, request charge, request IDDocumentMetadata- last modified, TTL expiry, version/ETag- Document size enforcement (399 KB limit)
Validation:
userAgentSuffix(String)rejects values longer than 256 characters and non-printable US-ASCII, protecting against header injection.
multiclouddb-provider-cosmos¶
[Unreleased]¶
Added:
consistencyLevelconnection config key for opt-in client-level read consistency override (applied uniformly to every read from a given client instance). Valid values (case-insensitive):STRONG,BOUNDED_STALENESS,SESSION,CONSISTENT_PREFIX,EVENTUAL. When absent, read requests inherit the Cosmos DB account's configured default. Seedocs/configuration.md— Consistency Level.
Changed:
- Removed the hardcoded
ConsistencyLevel.SESSIONoverride fromCosmosClientBuilder. Previously all reads were forced toSESSIONregardless of the account's configured default. Migration note: accounts with a default ofSTRONGorBOUNDED_STALENESSwill now serve reads at their configured level (higher latency / higher RU cost than before). Accounts configured toSESSIONare unaffected. To restore the previous behaviour explicitly, setmulticlouddb.connection.consistencyLevel=SESSION.
Removed:
CosmosConstants.CONSISTENCY_LEVEL_DEFAULT(public static final ConsistencyLevel, previouslyConsistencyLevel.SESSION) — removed without a deprecation cycle; the project is pre-release. Callers referencing this constant should useConsistencyLevel.SESSIONdirectly.
Changed:
BETWEENtranslation now wraps in parentheses ((c.field BETWEEN @lo AND @hi)). Without the wrapping parens, Cosmos NoSQL's parser greedily binds theBETWEEN's innerANDtogether with any trailing logicalAND, producing a "Syntax error, incorrect syntax near 'AND'"BadRequestfor predicates likeage BETWEEN @lo AND @hi AND marker = @m. The output ofTranslatedQuery.whereClause()is now parenthesised — backward-compatible at the query-execution level, but consumers that string-match the where clause should update their expectations.
Documentation:
delete()of a missing key remains a silent no-op (idempotent). The Cosmos provider continues to swallow the native 404 fromdeleteItem(...), matching the LCD behaviour of DynamoDB (DeleteItemis idempotent natively) and Spanner (Mutation.deleteis idempotent natively). Documented in the API Javadoc onMulticloudDbClient.delete(...)and indocs/guide.md. No caller-visible behaviour change. Callers needing to detect a missing key should useread(), which returnsnullon every provider when the key does not exist.
[0.1.0-beta.1] - 2026-04-23¶
Added:
- User-Agent header stamping with
multiclouddb-sdk-java/<version>token and optional user-configured suffix. CosmosProviderAdapter- SPI entry point for Cosmos DBCosmosProviderClient- full implementation backed by Azure Cosmos DB Java SDK v4- Master-key and Azure Identity (Entra ID) authentication
- Gateway and Direct connection modes
- Full CRUD with automatic field injection (
id,partitionKey) - Portable expression translation to Cosmos SQL
- Native SQL passthrough
- Cross-partition query support (capability-gated)
- Schema provisioning (database + container creation)
multiclouddb-provider-dynamo¶
[Unreleased]¶
Changed:
BETWEENtranslation now wraps in parentheses ((field BETWEEN ? AND ?)). Mirrors the parenthesised form emitted by sibling translators so cross-provider query stitching is uniform. PartiQL parses both forms correctly, so this is not a correctness fix on Dynamo — purely a consistency improvement. The output ofTranslatedQuery.whereClause()is now parenthesised.
Documentation:
delete()of a missing key remains a silent no-op (idempotent). The Dynamo provider issues an unconditionalDeleteItem, so a delete of a key that does not exist is silently ignored — matching the LCD behaviour of Cosmos (404 swallowed) and Spanner (Mutation.deleteis idempotent natively). Noattribute_existsguard is added, so deletes do not pay the conditional-write WCU surcharge. Documented in the API Javadoc onMulticloudDbClient.delete(...)and indocs/guide.md. Callers needing to detect a missing key should useread(), which returnsnullon every provider when the key does not exist.
[0.1.0-beta.1] - 2026-04-23¶
Added:
- User-Agent suffix support via
SdkAdvancedClientOption.USER_AGENT_SUFFIX. DynamoProviderAdapter- SPI entry point for DynamoDBDynamoProviderClient- full implementation backed by AWS SDK for Java 2.25.16- AWS credential authentication (access key + secret key)
- Full CRUD with
attribute_not_exists/attribute_existsguards - Portable expression translation to PartiQL
- Native PartiQL passthrough
- Schema provisioning (table creation with ACTIVE-wait)
multiclouddb-provider-spanner¶
[Unreleased]¶
Changed:
BETWEENtranslation now wraps in parentheses ((field BETWEEN @lo AND @hi)). Mirrors the parenthesised form emitted by sibling translators so cross-provider query stitching is uniform. GoogleSQL parses both forms correctly, so this is not a correctness fix on Spanner — purely a consistency improvement. The output ofTranslatedQuery.whereClause()is now parenthesised.
Documentation:
delete()of a missing key remains a silent no-op (idempotent). The Spanner provider continues to useMutation.delete(table, Key.of(pk, sk))viadatabaseClient.write(...), which is idempotent natively — deleting a row that does not exist returns success without modifying state. This matches the LCD behaviour of Cosmos (404 swallowed) and DynamoDB (DeleteItemis idempotent natively). Documented in the API Javadoc onMulticloudDbClient.delete(...)and indocs/guide.md. Callers needing to detect a missing key should useread(), which returnsnullon every provider when the key does not exist.
[0.1.0-beta.1] - 2026-04-23¶
Added:
- User-Agent support via gax
FixedHeaderProvider. SpannerProviderAdapter- SPI entry point for SpannerSpannerProviderClient- full implementation backed by Google Cloud Spanner 6.62.0- GCP credential and emulator authentication
- Full CRUD with mutation-based writes
- Portable expression translation to GoogleSQL
- Native GoogleSQL passthrough
- Schema provisioning (DDL-based table creation)