Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- feat(databases): add description field to fork lineage
- chore(databases): simplify fork error description

## [0.18.1] - 2026-09-18
Expand Down
2 changes: 1 addition & 1 deletion docs/DatabasesApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ Name | Type | Description | Required | Notes
> models::CreateDatabaseResponse fork_database(database_id, fork_database_request)
Fork database

Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `description` records why the fork is being taken; it is returned with the fork's `forked_from` and in the lineage of both databases. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.

### Parameters

Expand Down
1 change: 1 addition & 0 deletions docs/ForkDatabaseRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**description** | Option<**String**> | Optional note saying why the fork is being taken — for example \"backfill test before the March migration\". It is kept with the record of the fork and returned wherever that record appears: `forked_from` on the fork, and the fork's entry in both databases' lineage. Surrounding whitespace is trimmed, and an empty value is treated as absent. At most 4096 bytes; line breaks and tabs are allowed, other control characters are not. | [optional]
**expires_at** | Option<**String**> | When the fork expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"` or `\"7d\"`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. | [optional]
**name** | Option<**String**> | Optional display label for the fork. When omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. A source with no usable label of its own gives a fork named from that ID alone. | [optional]

Expand Down
1 change: 1 addition & 0 deletions docs/ForkedFromInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | ID of the database that was forked. The database may since have been deleted — the record outlives it — so this is not guaranteed to resolve. |
**description** | Option<**String**> | Why the fork was taken, as given when it was created. Absent when none was given. | [optional]
**forked_at** | Option<**String**> | When the fork was taken. | [optional]
**name** | Option<**String**> | Display label the source carried when the fork was taken, kept so a deleted source still reads as more than an ID. | [optional]
**snapshot_id** | Option<**i64**> | Marks the version of the source that this fork copied — its table set and their contents as of that moment. It is a point in time rather than a per-database revision count, so two forks of a source that did not change still report different values, and the numbers are not a way to tell whether a source has changed. Absent only on forks taken before the version was recorded. | [optional]
Expand Down
1 change: 1 addition & 0 deletions docs/LineageAncestorInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | |
**description** | Option<**String**> | Why the next database down the chain was forked from it, as given at the time. Absent when none was given. | [optional]
**exists** | **bool** | False once the ancestor has been deleted. Its place in the chain is kept either way, and the ancestry continues past it. |
**forked_at** | Option<**String**> | When the next database down the chain was forked from it. | [optional]
**name** | Option<**String**> | The ancestor's current label, or the one captured at fork time when it no longer exists. | [optional]
Expand Down
1 change: 1 addition & 0 deletions docs/LineageForkInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**database_id** | **String** | |
**description** | Option<**String**> | Why the fork was taken, as given when it was created. Absent when none was given. | [optional]
**exists** | **bool** | False once the fork has been deleted. The record of it is kept either way, so a source can still account for everything taken from it. |
**forked_at** | Option<**String**> | When the fork was taken. | [optional]
**name** | Option<**String**> | Absent once the fork has been deleted — only the record of it remains. | [optional]
Expand Down
2 changes: 1 addition & 1 deletion src/apis/databases_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ pub async fn detach_database_catalog(
}
}

/// Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
/// Create a new database that is an independent fork of an existing one. The fork has its own default catalog and contains the same schemas, tables, and data as the source; the source is left unchanged. External catalogs attached to the source are re-attached to the fork. Optional `description` records why the fork is being taken; it is returned with the fork's `forked_from` and in the lineage of both databases. Optional `name` sets the fork's display label; when omitted, the fork takes the source's label followed by a short suffix derived from the fork's own ID, so the two stay distinguishable. Optional `expires_at` sets when the fork expires — accepts an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `90m`, `7d`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires. Any indexes on the source's tables are not carried over. A fork adds no stored bytes at first, because it starts out sharing the source's storage. Routine maintenance can later rewrite a shared table into the fork's own storage, and the fork is billed for that copy from then on. Whether and when that happens depends on the table, so a fork that is only read can keep sharing indefinitely.
pub async fn fork_database(
configuration: &configuration::Configuration,
database_id: &str,
Expand Down
9 changes: 9 additions & 0 deletions src/models/fork_database_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ use serde::{Deserialize, Serialize};
/// ForkDatabaseRequest : Request body for POST /databases/{database_id}/fork
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct ForkDatabaseRequest {
/// Optional note saying why the fork is being taken — for example \"backfill test before the March migration\". It is kept with the record of the fork and returned wherever that record appears: `forked_from` on the fork, and the fork's entry in both databases' lineage. Surrounding whitespace is trimmed, and an empty value is treated as absent. At most 4096 bytes; line breaks and tabs are allowed, other control characters are not.
#[serde(
rename = "description",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub description: Option<Option<String>>,
/// When the fork expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"` or `\"7d\"`. When omitted, a still-future expiry on the source is carried over; otherwise the fork never expires.
#[serde(
rename = "expires_at",
Expand All @@ -36,6 +44,7 @@ impl ForkDatabaseRequest {
/// Request body for POST /databases/{database_id}/fork
pub fn new() -> ForkDatabaseRequest {
ForkDatabaseRequest {
description: None,
expires_at: None,
name: None,
}
Expand Down
9 changes: 9 additions & 0 deletions src/models/forked_from_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ pub struct ForkedFromInfo {
/// ID of the database that was forked. The database may since have been deleted — the record outlives it — so this is not guaranteed to resolve.
#[serde(rename = "database_id")]
pub database_id: String,
/// Why the fork was taken, as given when it was created. Absent when none was given.
#[serde(
rename = "description",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub description: Option<Option<String>>,
/// When the fork was taken.
#[serde(
rename = "forked_at",
Expand Down Expand Up @@ -48,6 +56,7 @@ impl ForkedFromInfo {
pub fn new(database_id: String) -> ForkedFromInfo {
ForkedFromInfo {
database_id,
description: None,
forked_at: None,
name: None,
snapshot_id: None,
Expand Down
9 changes: 9 additions & 0 deletions src/models/lineage_ancestor_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ use serde::{Deserialize, Serialize};
pub struct LineageAncestorInfo {
#[serde(rename = "database_id")]
pub database_id: String,
/// Why the next database down the chain was forked from it, as given at the time. Absent when none was given.
#[serde(
rename = "description",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub description: Option<Option<String>>,
/// False once the ancestor has been deleted. Its place in the chain is kept either way, and the ancestry continues past it.
#[serde(rename = "exists")]
pub exists: bool,
Expand Down Expand Up @@ -50,6 +58,7 @@ impl LineageAncestorInfo {
pub fn new(database_id: String, exists: bool) -> LineageAncestorInfo {
LineageAncestorInfo {
database_id,
description: None,
exists,
forked_at: None,
name: None,
Expand Down
9 changes: 9 additions & 0 deletions src/models/lineage_fork_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ use serde::{Deserialize, Serialize};
pub struct LineageForkInfo {
#[serde(rename = "database_id")]
pub database_id: String,
/// Why the fork was taken, as given when it was created. Absent when none was given.
#[serde(
rename = "description",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub description: Option<Option<String>>,
/// False once the fork has been deleted. The record of it is kept either way, so a source can still account for everything taken from it.
#[serde(rename = "exists")]
pub exists: bool,
Expand Down Expand Up @@ -50,6 +58,7 @@ impl LineageForkInfo {
pub fn new(database_id: String, exists: bool) -> LineageForkInfo {
LineageForkInfo {
database_id,
description: None,
exists,
forked_at: None,
name: None,
Expand Down
Loading