From 998a3c773ea41cf55e7085701c99e4b8787e8f50 Mon Sep 17 00:00:00 2001 From: Brendan Clement Date: Tue, 2 Jun 2026 09:38:43 -0700 Subject: [PATCH] feat: add update_field_metadata operation --- docs/src/namespace/operations/index.md | 1 + .../models/UpdateFieldMetadataEntry.md | 15 + .../models/UpdateFieldMetadataRequest.md | 15 + .../models/UpdateFieldMetadataResponse.md | 14 + docs/src/spec.yaml | 108 ++++++ java/lance-namespace-apache-client/README.md | 5 + .../api/openapi.yaml | 127 +++++++ .../docs/MetadataApi.md | 92 +++++ .../docs/TableApi.md | 92 +++++ .../docs/UpdateFieldMetadataEntry.md | 15 + .../docs/UpdateFieldMetadataRequest.md | 15 + .../docs/UpdateFieldMetadataResponse.md | 14 + .../client/apache/api/MetadataApi.java | 109 ++++++ .../namespace/client/apache/api/TableApi.java | 109 ++++++ .../model/UpdateFieldMetadataEntry.java | 281 +++++++++++++++ .../model/UpdateFieldMetadataRequest.java | 256 ++++++++++++++ .../model/UpdateFieldMetadataResponse.java | 210 +++++++++++ java/lance-namespace-async-client/README.md | 7 + .../api/openapi.yaml | 127 +++++++ .../docs/MetadataApi.md | 195 +++++++++++ .../docs/TableApi.md | 195 +++++++++++ .../docs/UpdateFieldMetadataEntry.md | 15 + .../docs/UpdateFieldMetadataRequest.md | 15 + .../docs/UpdateFieldMetadataResponse.md | 14 + .../client/async/api/MetadataApi.java | 161 +++++++++ .../namespace/client/async/api/TableApi.java | 161 +++++++++ .../model/UpdateFieldMetadataEntry.java | 260 ++++++++++++++ .../model/UpdateFieldMetadataRequest.java | 248 +++++++++++++ .../model/UpdateFieldMetadataResponse.java | 196 +++++++++++ .../namespace/async/LanceNamespaceAsync.java | 12 + .../org/lance/namespace/LanceNamespace.java | 10 + .../server/springboot/api/TableApi.java | 179 ++++++++++ .../model/UpdateFieldMetadataEntry.java | 170 +++++++++ .../model/UpdateFieldMetadataRequest.java | 172 +++++++++ .../model/UpdateFieldMetadataResponse.java | 140 ++++++++ .../lance_namespace/__init__.py | 20 ++ .../lance_namespace_urllib3_client/README.md | 5 + .../docs/MetadataApi.md | 105 ++++++ .../docs/TableApi.md | 105 ++++++ .../docs/UpdateFieldMetadataEntry.md | 31 ++ .../docs/UpdateFieldMetadataRequest.md | 31 ++ .../docs/UpdateFieldMetadataResponse.md | 30 ++ .../__init__.py | 3 + .../api/metadata_api.py | 328 ++++++++++++++++++ .../api/table_api.py | 328 ++++++++++++++++++ .../models/__init__.py | 3 + .../models/update_field_metadata_entry.py | 96 +++++ .../models/update_field_metadata_request.py | 103 ++++++ .../models/update_field_metadata_response.py | 90 +++++ .../test/test_metadata_api.py | 7 + .../test/test_table_api.py | 7 + .../test/test_update_field_metadata_entry.py | 59 ++++ .../test_update_field_metadata_request.py | 72 ++++ .../test_update_field_metadata_response.py | 57 +++ rust/lance-namespace-reqwest-client/README.md | 5 + .../docs/MetadataApi.md | 33 ++ .../docs/TableApi.md | 33 ++ .../docs/UpdateFieldMetadataEntry.md | 13 + .../docs/UpdateFieldMetadataRequest.md | 13 + .../docs/UpdateFieldMetadataResponse.md | 12 + .../src/apis/metadata_api.rs | 70 ++++ .../src/apis/table_api.rs | 70 ++++ .../src/models/mod.rs | 6 + .../src/models/update_field_metadata_entry.rs | 36 ++ .../models/update_field_metadata_request.rs | 35 ++ .../models/update_field_metadata_response.rs | 32 ++ 66 files changed, 5593 insertions(+) create mode 100644 docs/src/namespace/operations/models/UpdateFieldMetadataEntry.md create mode 100644 docs/src/namespace/operations/models/UpdateFieldMetadataRequest.md create mode 100644 docs/src/namespace/operations/models/UpdateFieldMetadataResponse.md create mode 100644 java/lance-namespace-apache-client/docs/UpdateFieldMetadataEntry.md create mode 100644 java/lance-namespace-apache-client/docs/UpdateFieldMetadataRequest.md create mode 100644 java/lance-namespace-apache-client/docs/UpdateFieldMetadataResponse.md create mode 100644 java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java create mode 100644 java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java create mode 100644 java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java create mode 100644 java/lance-namespace-async-client/docs/UpdateFieldMetadataEntry.md create mode 100644 java/lance-namespace-async-client/docs/UpdateFieldMetadataRequest.md create mode 100644 java/lance-namespace-async-client/docs/UpdateFieldMetadataResponse.md create mode 100644 java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java create mode 100644 java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java create mode 100644 java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java create mode 100644 java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataEntry.java create mode 100644 java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataRequest.java create mode 100644 java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataResponse.java create mode 100644 python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataEntry.md create mode 100644 python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataRequest.md create mode 100644 python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataResponse.md create mode 100644 python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_entry.py create mode 100644 python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_request.py create mode 100644 python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_response.py create mode 100644 python/lance_namespace_urllib3_client/test/test_update_field_metadata_entry.py create mode 100644 python/lance_namespace_urllib3_client/test/test_update_field_metadata_request.py create mode 100644 python/lance_namespace_urllib3_client/test/test_update_field_metadata_response.py create mode 100644 rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataEntry.md create mode 100644 rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataRequest.md create mode 100644 rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataResponse.md create mode 100644 rust/lance-namespace-reqwest-client/src/models/update_field_metadata_entry.rs create mode 100644 rust/lance-namespace-reqwest-client/src/models/update_field_metadata_request.rs create mode 100644 rust/lance-namespace-reqwest-client/src/models/update_field_metadata_response.rs diff --git a/docs/src/namespace/operations/index.md b/docs/src/namespace/operations/index.md index 17698ca5..ccccb555 100644 --- a/docs/src/namespace/operations/index.md +++ b/docs/src/namespace/operations/index.md @@ -79,6 +79,7 @@ See [REST Routes](../../catalog/rest/index.md#rest-routes) for more details. | AlterTableBackfillColumns | 1 | | ✓ | | | ✓ | | | AlterTableDropColumns | 1 | | ✓ | | ✓ | | | | RefreshMaterializedView | 1 | | ✓ | | | ✓ | | +| UpdateFieldMetadata | 1 | | ✓ | | ✓ | | | | UpdateTableSchemaMetadata | 1 | | ✓ | | ✓ | | | | GetTableStats | 1 | | ✓ | | ✓ | | | | ListTableTags | 1 | | ✓ | | ✓ | | | diff --git a/docs/src/namespace/operations/models/UpdateFieldMetadataEntry.md b/docs/src/namespace/operations/models/UpdateFieldMetadataEntry.md new file mode 100644 index 00000000..839cae8e --- /dev/null +++ b/docs/src/namespace/operations/models/UpdateFieldMetadataEntry.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataEntry + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**path** | **String** | Field (column) path whose metadata to update | | +|**metadata** | **Map<String, String>** | Metadata key-value pairs to apply to the field. A null value deletes that key. | | +|**replace** | **Boolean** | If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). | [optional] | + + + diff --git a/docs/src/namespace/operations/models/UpdateFieldMetadataRequest.md b/docs/src/namespace/operations/models/UpdateFieldMetadataRequest.md new file mode 100644 index 00000000..c94a4d10 --- /dev/null +++ b/docs/src/namespace/operations/models/UpdateFieldMetadataRequest.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataRequest + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**identity** | [**Identity**](Identity.md) | | [optional] | +|**id** | **List<String>** | Table identifier path (namespace + table name) | [optional] | +|**updates** | [**List<UpdateFieldMetadataEntry>**](UpdateFieldMetadataEntry.md) | List of per-field metadata updates to apply | | + + + diff --git a/docs/src/namespace/operations/models/UpdateFieldMetadataResponse.md b/docs/src/namespace/operations/models/UpdateFieldMetadataResponse.md new file mode 100644 index 00000000..82496448 --- /dev/null +++ b/docs/src/namespace/operations/models/UpdateFieldMetadataResponse.md @@ -0,0 +1,14 @@ + + +# UpdateFieldMetadataResponse + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**version** | **Long** | The commit version associated with the operation | | +|**fields** | **Map<String, Map<String, String>>** | Resulting metadata for each updated field, keyed by field path. | [optional] | + + + diff --git a/docs/src/spec.yaml b/docs/src/spec.yaml index ffcd32bf..e0c27c1a 100644 --- a/docs/src/spec.yaml +++ b/docs/src/spec.yaml @@ -938,6 +938,44 @@ paths: 5XX: $ref: "#/components/responses/ServerErrorResponse" + /v1/table/{id}/update_field_metadata: + parameters: + - $ref: "#/components/parameters/id" + - $ref: "#/components/parameters/delimiter" + post: + tags: + - Table + - Metadata + summary: Update per-field metadata + operationId: UpdateFieldMetadata + description: | + Update the Arrow field (column) metadata for table `id`. + + Each entry targets a field by `path` and merges the provided key-value + pairs into that field's existing metadata, or replaces it when `replace` + is true. A null metadata value deletes that key. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateFieldMetadataRequest" + responses: + 200: + $ref: "#/components/responses/UpdateFieldMetadataResponse" + 400: + $ref: "#/components/responses/BadRequestErrorResponse" + 401: + $ref: "#/components/responses/UnauthorizedErrorResponse" + 403: + $ref: "#/components/responses/ForbiddenErrorResponse" + 404: + $ref: "#/components/responses/NotFoundErrorResponse" + 503: + $ref: "#/components/responses/ServiceUnavailableErrorResponse" + 5XX: + $ref: "#/components/responses/ServerErrorResponse" + /v1/table/{id}/drop_columns: parameters: - $ref: "#/components/parameters/id" @@ -4726,6 +4764,69 @@ components: description: The commit version associated with the operation minimum: 0 + UpdateFieldMetadataRequest: + type: object + required: + - updates + properties: + identity: + $ref: "#/components/schemas/Identity" + id: + type: array + items: + type: string + description: Table identifier path (namespace + table name) + updates: + type: array + items: + $ref: "#/components/schemas/UpdateFieldMetadataEntry" + description: List of per-field metadata updates to apply + + UpdateFieldMetadataEntry: + type: object + required: + - path + - metadata + properties: + path: + type: string + description: Field (column) path whose metadata to update + metadata: + type: object + additionalProperties: + type: + - string + - "null" + description: | + Metadata key-value pairs to apply to the field. A null value + deletes that key. + replace: + type: + - boolean + - "null" + description: | + If true, replace the field's existing metadata entirely; otherwise + merge into it (optional, defaults to false). + + UpdateFieldMetadataResponse: + type: object + required: + - version + properties: + version: + type: integer + format: int64 + description: The commit version associated with the operation + minimum: 0 + fields: + type: object + additionalProperties: + type: object + additionalProperties: + type: string + description: | + Resulting metadata for each updated field, keyed by field path. + AlterTableAlterColumnsRequest: type: object required: @@ -5648,6 +5749,13 @@ components: schema: $ref: "#/components/schemas/AlterTableAddColumnsResponse" + UpdateFieldMetadataResponse: + description: Field metadata update result + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateFieldMetadataResponse" + AlterTableAlterColumnsResponse: description: Alter columns operation result content: diff --git a/java/lance-namespace-apache-client/README.md b/java/lance-namespace-apache-client/README.md index 04d71d0e..79c62254 100644 --- a/java/lance-namespace-apache-client/README.md +++ b/java/lance-namespace-apache-client/README.md @@ -187,6 +187,7 @@ Class | Method | HTTP request | Description *MetadataApi* | [**renameTable**](docs/MetadataApi.md#renameTable) | **POST** /v1/table/{id}/rename | Rename a table *MetadataApi* | [**restoreTable**](docs/MetadataApi.md#restoreTable) | **POST** /v1/table/{id}/restore | Restore table to a specific version *MetadataApi* | [**tableExists**](docs/MetadataApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists +*MetadataApi* | [**updateFieldMetadata**](docs/MetadataApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *MetadataApi* | [**updateTableSchemaMetadata**](docs/MetadataApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *MetadataApi* | [**updateTableTag**](docs/MetadataApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version *NamespaceApi* | [**createNamespace**](docs/NamespaceApi.md#createNamespace) | **POST** /v1/namespace/{id}/create | Create a new namespace @@ -233,6 +234,7 @@ Class | Method | HTTP request | Description *TableApi* | [**renameTable**](docs/TableApi.md#renameTable) | **POST** /v1/table/{id}/rename | Rename a table *TableApi* | [**restoreTable**](docs/TableApi.md#restoreTable) | **POST** /v1/table/{id}/restore | Restore table to a specific version *TableApi* | [**tableExists**](docs/TableApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists +*TableApi* | [**updateFieldMetadata**](docs/TableApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *TableApi* | [**updateTable**](docs/TableApi.md#updateTable) | **POST** /v1/table/{id}/update | Update rows in a table *TableApi* | [**updateTableSchemaMetadata**](docs/TableApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *TableApi* | [**updateTableTag**](docs/TableApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -373,6 +375,9 @@ Class | Method | HTTP request | Description - [TableExistsRequest](docs/TableExistsRequest.md) - [TableVersion](docs/TableVersion.md) - [TagContents](docs/TagContents.md) + - [UpdateFieldMetadataEntry](docs/UpdateFieldMetadataEntry.md) + - [UpdateFieldMetadataRequest](docs/UpdateFieldMetadataRequest.md) + - [UpdateFieldMetadataResponse](docs/UpdateFieldMetadataResponse.md) - [UpdateTableRequest](docs/UpdateTableRequest.md) - [UpdateTableResponse](docs/UpdateTableResponse.md) - [UpdateTableSchemaMetadataRequest](docs/UpdateTableSchemaMetadataRequest.md) diff --git a/java/lance-namespace-apache-client/api/openapi.yaml b/java/lance-namespace-apache-client/api/openapi.yaml index 4fe2aa50..54006172 100644 --- a/java/lance-namespace-apache-client/api/openapi.yaml +++ b/java/lance-namespace-apache-client/api/openapi.yaml @@ -1038,6 +1038,49 @@ paths: x-content-type: application/json x-accepts: - application/json + /v1/table/{id}/update_field_metadata: + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/delimiter' + post: + description: | + Update the Arrow field (column) metadata for table `id`. + + Each entry targets a field by `path` and merges the provided key-value + pairs into that field's existing metadata, or replaces it when `replace` + is true. A null metadata value deletes that key. + operationId: UpdateFieldMetadata + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/delimiter' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateFieldMetadataRequest' + required: true + responses: + "200": + $ref: '#/components/responses/UpdateFieldMetadataResponse' + "400": + $ref: '#/components/responses/BadRequestErrorResponse' + "401": + $ref: '#/components/responses/UnauthorizedErrorResponse' + "403": + $ref: '#/components/responses/ForbiddenErrorResponse' + "404": + $ref: '#/components/responses/NotFoundErrorResponse' + "503": + $ref: '#/components/responses/ServiceUnavailableErrorResponse' + "5XX": + $ref: '#/components/responses/ServerErrorResponse' + summary: Update per-field metadata + tags: + - Table + - Metadata + x-content-type: application/json + x-accepts: + - application/json /v1/table/{id}/drop_columns: parameters: - $ref: '#/components/parameters/id' @@ -2837,6 +2880,12 @@ components: schema: $ref: '#/components/schemas/AlterTableAddColumnsResponse' description: Add columns operation result + UpdateFieldMetadataResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateFieldMetadataResponse' + description: Field metadata update result AlterTableAlterColumnsResponse: content: application/json: @@ -7296,6 +7345,84 @@ components: type: integer required: - version + UpdateFieldMetadataRequest: + example: + identity: + api_key: api_key + auth_token: auth_token + id: + - id + - id + updates: + - path: path + metadata: + key: metadata + replace: true + - path: path + metadata: + key: metadata + replace: true + properties: + identity: + $ref: '#/components/schemas/Identity' + id: + description: Table identifier path (namespace + table name) + items: + type: string + type: array + updates: + description: List of per-field metadata updates to apply + items: + $ref: '#/components/schemas/UpdateFieldMetadataEntry' + type: array + required: + - updates + UpdateFieldMetadataEntry: + example: + path: path + metadata: + key: metadata + replace: true + properties: + path: + description: Field (column) path whose metadata to update + type: string + metadata: + additionalProperties: + nullable: true + type: string + description: | + Metadata key-value pairs to apply to the field. A null value + deletes that key. + replace: + description: | + If true, replace the field's existing metadata entirely; otherwise + merge into it (optional, defaults to false). + nullable: true + type: boolean + required: + - metadata + - path + UpdateFieldMetadataResponse: + example: + fields: + key: + key: fields + version: 0 + properties: + version: + description: The commit version associated with the operation + format: int64 + minimum: 0 + type: integer + fields: + additionalProperties: + additionalProperties: + type: string + description: | + Resulting metadata for each updated field, keyed by field path. + required: + - version AlterTableAlterColumnsRequest: example: identity: diff --git a/java/lance-namespace-apache-client/docs/MetadataApi.md b/java/lance-namespace-apache-client/docs/MetadataApi.md index 47d21d4e..e8bf22cd 100644 --- a/java/lance-namespace-apache-client/docs/MetadataApi.md +++ b/java/lance-namespace-apache-client/docs/MetadataApi.md @@ -38,6 +38,7 @@ All URIs are relative to *http://localhost:2333* | [**renameTable**](MetadataApi.md#renameTable) | **POST** /v1/table/{id}/rename | Rename a table | | [**restoreTable**](MetadataApi.md#restoreTable) | **POST** /v1/table/{id}/restore | Restore table to a specific version | | [**tableExists**](MetadataApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists | +| [**updateFieldMetadata**](MetadataApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | | [**updateTableSchemaMetadata**](MetadataApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata | | [**updateTableTag**](MetadataApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version | @@ -3163,6 +3164,97 @@ null (empty response body) | **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | +## updateFieldMetadata + +> UpdateFieldMetadataResponse updateFieldMetadata(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.apache.ApiClient; +import org.lance.namespace.client.apache.ApiException; +import org.lance.namespace.client.apache.Configuration; +import org.lance.namespace.client.apache.auth.*; +import org.lance.namespace.client.apache.models.*; +import org.lance.namespace.client.apache.api.MetadataApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + MetadataApi apiInstance = new MetadataApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + UpdateFieldMetadataResponse result = apiInstance.updateFieldMetadata(id, updateFieldMetadataRequest, delimiter); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling MetadataApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + + ## updateTableSchemaMetadata > Map<String, String> updateTableSchemaMetadata(id, requestBody, delimiter) diff --git a/java/lance-namespace-apache-client/docs/TableApi.md b/java/lance-namespace-apache-client/docs/TableApi.md index 07d3b544..7e7ddae0 100644 --- a/java/lance-namespace-apache-client/docs/TableApi.md +++ b/java/lance-namespace-apache-client/docs/TableApi.md @@ -42,6 +42,7 @@ All URIs are relative to *http://localhost:2333* | [**renameTable**](TableApi.md#renameTable) | **POST** /v1/table/{id}/rename | Rename a table | | [**restoreTable**](TableApi.md#restoreTable) | **POST** /v1/table/{id}/restore | Restore table to a specific version | | [**tableExists**](TableApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists | +| [**updateFieldMetadata**](TableApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | | [**updateTable**](TableApi.md#updateTable) | **POST** /v1/table/{id}/update | Update rows in a table | | [**updateTableSchemaMetadata**](TableApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata | | [**updateTableTag**](TableApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version | @@ -3552,6 +3553,97 @@ null (empty response body) | **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | +## updateFieldMetadata + +> UpdateFieldMetadataResponse updateFieldMetadata(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.apache.ApiClient; +import org.lance.namespace.client.apache.ApiException; +import org.lance.namespace.client.apache.Configuration; +import org.lance.namespace.client.apache.auth.*; +import org.lance.namespace.client.apache.models.*; +import org.lance.namespace.client.apache.api.TableApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + TableApi apiInstance = new TableApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + UpdateFieldMetadataResponse result = apiInstance.updateFieldMetadata(id, updateFieldMetadataRequest, delimiter); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling TableApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + + ## updateTable > UpdateTableResponse updateTable(id, updateTableRequest, delimiter) diff --git a/java/lance-namespace-apache-client/docs/UpdateFieldMetadataEntry.md b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataEntry.md new file mode 100644 index 00000000..839cae8e --- /dev/null +++ b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataEntry.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataEntry + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**path** | **String** | Field (column) path whose metadata to update | | +|**metadata** | **Map<String, String>** | Metadata key-value pairs to apply to the field. A null value deletes that key. | | +|**replace** | **Boolean** | If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). | [optional] | + + + diff --git a/java/lance-namespace-apache-client/docs/UpdateFieldMetadataRequest.md b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataRequest.md new file mode 100644 index 00000000..c94a4d10 --- /dev/null +++ b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataRequest.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataRequest + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**identity** | [**Identity**](Identity.md) | | [optional] | +|**id** | **List<String>** | Table identifier path (namespace + table name) | [optional] | +|**updates** | [**List<UpdateFieldMetadataEntry>**](UpdateFieldMetadataEntry.md) | List of per-field metadata updates to apply | | + + + diff --git a/java/lance-namespace-apache-client/docs/UpdateFieldMetadataResponse.md b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataResponse.md new file mode 100644 index 00000000..82496448 --- /dev/null +++ b/java/lance-namespace-apache-client/docs/UpdateFieldMetadataResponse.md @@ -0,0 +1,14 @@ + + +# UpdateFieldMetadataResponse + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**version** | **Long** | The commit version associated with the operation | | +|**fields** | **Map<String, Map<String, String>>** | Resulting metadata for each updated field, keyed by field path. | [optional] | + + + diff --git a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/MetadataApi.java b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/MetadataApi.java index 0bdfea47..a9fccb49 100644 --- a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/MetadataApi.java +++ b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/MetadataApi.java @@ -77,6 +77,8 @@ import org.lance.namespace.model.RestoreTableRequest; import org.lance.namespace.model.RestoreTableResponse; import org.lance.namespace.model.TableExistsRequest; +import org.lance.namespace.model.UpdateFieldMetadataRequest; +import org.lance.namespace.model.UpdateFieldMetadataResponse; import org.lance.namespace.model.UpdateTableTagRequest; import org.lance.namespace.model.UpdateTableTagResponse; @@ -3641,6 +3643,113 @@ public void tableExists( null); } + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return UpdateFieldMetadataResponse + * @throws ApiException if fails to make API call + */ + public UpdateFieldMetadataResponse updateFieldMetadata( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + return this.updateFieldMetadata( + id, updateFieldMetadataRequest, delimiter, Collections.emptyMap()); + } + + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @param additionalHeaders additionalHeaders for this call + * @return UpdateFieldMetadataResponse + * @throws ApiException if fails to make API call + */ + public UpdateFieldMetadataResponse updateFieldMetadata( + String id, + UpdateFieldMetadataRequest updateFieldMetadataRequest, + String delimiter, + Map additionalHeaders) + throws ApiException { + Object localVarPostBody = updateFieldMetadataRequest; + + // verify the required parameter 'id' is set + if (id == null) { + throw new ApiException( + 400, "Missing the required parameter 'id' when calling updateFieldMetadata"); + } + + // verify the required parameter 'updateFieldMetadataRequest' is set + if (updateFieldMetadataRequest == null) { + throw new ApiException( + 400, + "Missing the required parameter 'updateFieldMetadataRequest' when calling updateFieldMetadata"); + } + + // create path and map variables + String localVarPath = + "/v1/table/{id}/update_field_metadata" + .replaceAll( + "\\{" + "id" + "\\}", apiClient.escapeString(apiClient.parameterToString(id))); + + StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + String localVarQueryParameterBaseName; + List localVarQueryParams = new ArrayList(); + List localVarCollectionQueryParams = new ArrayList(); + Map localVarHeaderParams = new HashMap(); + Map localVarCookieParams = new HashMap(); + Map localVarFormParams = new HashMap(); + + localVarQueryParams.addAll(apiClient.parameterToPair("delimiter", delimiter)); + + localVarHeaderParams.putAll(additionalHeaders); + + final String[] localVarAccepts = {"application/json"}; + final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + + final String[] localVarContentTypes = {"application/json"}; + final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] {"OAuth2", "ApiKeyAuth", "BearerAuth"}; + + TypeReference localVarReturnType = + new TypeReference() {}; + return apiClient.invokeAPI( + localVarPath, + "POST", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + localVarPostBody, + localVarHeaderParams, + localVarCookieParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarAuthNames, + localVarReturnType); + } + /** * Update table schema metadata Replace the schema metadata for table `id` with the * provided key-value pairs. REST NAMESPACE ONLY REST namespace uses a direct object (map of diff --git a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/TableApi.java b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/TableApi.java index fb13d8a4..8f8d3a76 100644 --- a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/TableApi.java +++ b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/client/apache/api/TableApi.java @@ -78,6 +78,8 @@ import org.lance.namespace.model.RestoreTableRequest; import org.lance.namespace.model.RestoreTableResponse; import org.lance.namespace.model.TableExistsRequest; +import org.lance.namespace.model.UpdateFieldMetadataRequest; +import org.lance.namespace.model.UpdateFieldMetadataResponse; import org.lance.namespace.model.UpdateTableRequest; import org.lance.namespace.model.UpdateTableResponse; import org.lance.namespace.model.UpdateTableTagRequest; @@ -4223,6 +4225,113 @@ public void tableExists( null); } + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return UpdateFieldMetadataResponse + * @throws ApiException if fails to make API call + */ + public UpdateFieldMetadataResponse updateFieldMetadata( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + return this.updateFieldMetadata( + id, updateFieldMetadataRequest, delimiter, Collections.emptyMap()); + } + + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @param additionalHeaders additionalHeaders for this call + * @return UpdateFieldMetadataResponse + * @throws ApiException if fails to make API call + */ + public UpdateFieldMetadataResponse updateFieldMetadata( + String id, + UpdateFieldMetadataRequest updateFieldMetadataRequest, + String delimiter, + Map additionalHeaders) + throws ApiException { + Object localVarPostBody = updateFieldMetadataRequest; + + // verify the required parameter 'id' is set + if (id == null) { + throw new ApiException( + 400, "Missing the required parameter 'id' when calling updateFieldMetadata"); + } + + // verify the required parameter 'updateFieldMetadataRequest' is set + if (updateFieldMetadataRequest == null) { + throw new ApiException( + 400, + "Missing the required parameter 'updateFieldMetadataRequest' when calling updateFieldMetadata"); + } + + // create path and map variables + String localVarPath = + "/v1/table/{id}/update_field_metadata" + .replaceAll( + "\\{" + "id" + "\\}", apiClient.escapeString(apiClient.parameterToString(id))); + + StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + String localVarQueryParameterBaseName; + List localVarQueryParams = new ArrayList(); + List localVarCollectionQueryParams = new ArrayList(); + Map localVarHeaderParams = new HashMap(); + Map localVarCookieParams = new HashMap(); + Map localVarFormParams = new HashMap(); + + localVarQueryParams.addAll(apiClient.parameterToPair("delimiter", delimiter)); + + localVarHeaderParams.putAll(additionalHeaders); + + final String[] localVarAccepts = {"application/json"}; + final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + + final String[] localVarContentTypes = {"application/json"}; + final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] {"OAuth2", "ApiKeyAuth", "BearerAuth"}; + + TypeReference localVarReturnType = + new TypeReference() {}; + return apiClient.invokeAPI( + localVarPath, + "POST", + localVarQueryParams, + localVarCollectionQueryParams, + localVarQueryStringJoiner.toString(), + localVarPostBody, + localVarHeaderParams, + localVarCookieParams, + localVarFormParams, + localVarAccept, + localVarContentType, + localVarAuthNames, + localVarReturnType); + } + /** * Update rows in a table Update existing rows in table `id`. * diff --git a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java new file mode 100644 index 00000000..67353b1a --- /dev/null +++ b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java @@ -0,0 +1,281 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.openapitools.jackson.nullable.JsonNullable; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataEntry */ +@JsonPropertyOrder({ + UpdateFieldMetadataEntry.JSON_PROPERTY_PATH, + UpdateFieldMetadataEntry.JSON_PROPERTY_METADATA, + UpdateFieldMetadataEntry.JSON_PROPERTY_REPLACE +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataEntry { + public static final String JSON_PROPERTY_PATH = "path"; + @javax.annotation.Nonnull private String path; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + @javax.annotation.Nonnull private Map metadata = new HashMap<>(); + + public static final String JSON_PROPERTY_REPLACE = "replace"; + + @javax.annotation.Nullable + private JsonNullable replace = JsonNullable.undefined(); + + public UpdateFieldMetadataEntry() {} + + public UpdateFieldMetadataEntry path(@javax.annotation.Nonnull String path) { + + this.path = path; + return this; + } + + /** + * Field (column) path whose metadata to update + * + * @return path + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_PATH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getPath() { + return path; + } + + @JsonProperty(JSON_PROPERTY_PATH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPath(@javax.annotation.Nonnull String path) { + this.path = path; + } + + public UpdateFieldMetadataEntry metadata(@javax.annotation.Nonnull Map metadata) { + + this.metadata = metadata; + return this; + } + + public UpdateFieldMetadataEntry putMetadataItem(String key, String metadataItem) { + this.metadata.put(key, metadataItem); + return this; + } + + /** + * Metadata key-value pairs to apply to the field. A null value deletes that key. + * + * @return metadata + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.ALWAYS) + public Map getMetadata() { + return metadata; + } + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.ALWAYS) + public void setMetadata(@javax.annotation.Nonnull Map metadata) { + this.metadata = metadata; + } + + public UpdateFieldMetadataEntry replace(@javax.annotation.Nullable Boolean replace) { + this.replace = JsonNullable.of(replace); + + return this; + } + + /** + * If true, replace the field's existing metadata entirely; otherwise merge into it (optional, + * defaults to false). + * + * @return replace + */ + @javax.annotation.Nullable + @JsonIgnore + public Boolean getReplace() { + return replace.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_REPLACE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getReplace_JsonNullable() { + return replace; + } + + @JsonProperty(JSON_PROPERTY_REPLACE) + public void setReplace_JsonNullable(JsonNullable replace) { + this.replace = replace; + } + + public void setReplace(@javax.annotation.Nullable Boolean replace) { + this.replace = JsonNullable.of(replace); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataEntry updateFieldMetadataEntry = (UpdateFieldMetadataEntry) o; + return Objects.equals(this.path, updateFieldMetadataEntry.path) + && Objects.equals(this.metadata, updateFieldMetadataEntry.metadata) + && equalsNullable(this.replace, updateFieldMetadataEntry.replace); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b + || (a != null + && b != null + && a.isPresent() + && b.isPresent() + && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(path, metadata, hashCodeNullable(replace)); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[] {a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataEntry {\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" replace: ").append(toIndentedString(replace)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `path` to the URL query string + if (getPath() != null) { + try { + joiner.add( + String.format( + "%spath%s=%s", + prefix, + suffix, + URLEncoder.encode(String.valueOf(getPath()), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + + // add `metadata` to the URL query string + if (getMetadata() != null) { + for (String _key : getMetadata().keySet()) { + try { + joiner.add( + String.format( + "%smetadata%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, _key, containerSuffix), + getMetadata().get(_key), + URLEncoder.encode(String.valueOf(getMetadata().get(_key)), "UTF-8") + .replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + } + + // add `replace` to the URL query string + if (getReplace() != null) { + try { + joiner.add( + String.format( + "%sreplace%s=%s", + prefix, + suffix, + URLEncoder.encode(String.valueOf(getReplace()), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java new file mode 100644 index 00000000..98b6c2a6 --- /dev/null +++ b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java @@ -0,0 +1,256 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataRequest */ +@JsonPropertyOrder({ + UpdateFieldMetadataRequest.JSON_PROPERTY_IDENTITY, + UpdateFieldMetadataRequest.JSON_PROPERTY_ID, + UpdateFieldMetadataRequest.JSON_PROPERTY_UPDATES +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataRequest { + public static final String JSON_PROPERTY_IDENTITY = "identity"; + @javax.annotation.Nullable private Identity identity; + + public static final String JSON_PROPERTY_ID = "id"; + @javax.annotation.Nullable private List id = new ArrayList<>(); + + public static final String JSON_PROPERTY_UPDATES = "updates"; + @javax.annotation.Nonnull private List updates = new ArrayList<>(); + + public UpdateFieldMetadataRequest() {} + + public UpdateFieldMetadataRequest identity(@javax.annotation.Nullable Identity identity) { + + this.identity = identity; + return this; + } + + /** + * Get identity + * + * @return identity + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_IDENTITY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Identity getIdentity() { + return identity; + } + + @JsonProperty(JSON_PROPERTY_IDENTITY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIdentity(@javax.annotation.Nullable Identity identity) { + this.identity = identity; + } + + public UpdateFieldMetadataRequest id(@javax.annotation.Nullable List id) { + + this.id = id; + return this; + } + + public UpdateFieldMetadataRequest addIdItem(String idItem) { + if (this.id == null) { + this.id = new ArrayList<>(); + } + this.id.add(idItem); + return this; + } + + /** + * Table identifier path (namespace + table name) + * + * @return id + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getId() { + return id; + } + + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setId(@javax.annotation.Nullable List id) { + this.id = id; + } + + public UpdateFieldMetadataRequest updates( + @javax.annotation.Nonnull List updates) { + + this.updates = updates; + return this; + } + + public UpdateFieldMetadataRequest addUpdatesItem(UpdateFieldMetadataEntry updatesItem) { + if (this.updates == null) { + this.updates = new ArrayList<>(); + } + this.updates.add(updatesItem); + return this; + } + + /** + * List of per-field metadata updates to apply + * + * @return updates + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_UPDATES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getUpdates() { + return updates; + } + + @JsonProperty(JSON_PROPERTY_UPDATES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUpdates(@javax.annotation.Nonnull List updates) { + this.updates = updates; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataRequest updateFieldMetadataRequest = (UpdateFieldMetadataRequest) o; + return Objects.equals(this.identity, updateFieldMetadataRequest.identity) + && Objects.equals(this.id, updateFieldMetadataRequest.id) + && Objects.equals(this.updates, updateFieldMetadataRequest.updates); + } + + @Override + public int hashCode() { + return Objects.hash(identity, id, updates); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataRequest {\n"); + sb.append(" identity: ").append(toIndentedString(identity)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" updates: ").append(toIndentedString(updates)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `identity` to the URL query string + if (getIdentity() != null) { + joiner.add(getIdentity().toUrlQueryString(prefix + "identity" + suffix)); + } + + // add `id` to the URL query string + if (getId() != null) { + for (int i = 0; i < getId().size(); i++) { + try { + joiner.add( + String.format( + "%sid%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getId().get(i)), "UTF-8") + .replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + } + + // add `updates` to the URL query string + if (getUpdates() != null) { + for (int i = 0; i < getUpdates().size(); i++) { + if (getUpdates().get(i) != null) { + joiner.add( + getUpdates() + .get(i) + .toUrlQueryString( + String.format( + "%supdates%s%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java new file mode 100644 index 00000000..a1a29b1d --- /dev/null +++ b/java/lance-namespace-apache-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java @@ -0,0 +1,210 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataResponse */ +@JsonPropertyOrder({ + UpdateFieldMetadataResponse.JSON_PROPERTY_VERSION, + UpdateFieldMetadataResponse.JSON_PROPERTY_FIELDS +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataResponse { + public static final String JSON_PROPERTY_VERSION = "version"; + @javax.annotation.Nonnull private Long version; + + public static final String JSON_PROPERTY_FIELDS = "fields"; + @javax.annotation.Nullable private Map> fields = new HashMap<>(); + + public UpdateFieldMetadataResponse() {} + + public UpdateFieldMetadataResponse version(@javax.annotation.Nonnull Long version) { + + this.version = version; + return this; + } + + /** + * The commit version associated with the operation minimum: 0 + * + * @return version + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getVersion() { + return version; + } + + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVersion(@javax.annotation.Nonnull Long version) { + this.version = version; + } + + public UpdateFieldMetadataResponse fields( + @javax.annotation.Nullable Map> fields) { + + this.fields = fields; + return this; + } + + public UpdateFieldMetadataResponse putFieldsItem(String key, Map fieldsItem) { + if (this.fields == null) { + this.fields = new HashMap<>(); + } + this.fields.put(key, fieldsItem); + return this; + } + + /** + * Resulting metadata for each updated field, keyed by field path. + * + * @return fields + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_FIELDS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Map> getFields() { + return fields; + } + + @JsonProperty(JSON_PROPERTY_FIELDS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFields(@javax.annotation.Nullable Map> fields) { + this.fields = fields; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataResponse updateFieldMetadataResponse = (UpdateFieldMetadataResponse) o; + return Objects.equals(this.version, updateFieldMetadataResponse.version) + && Objects.equals(this.fields, updateFieldMetadataResponse.fields); + } + + @Override + public int hashCode() { + return Objects.hash(version, fields); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataResponse {\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `version` to the URL query string + if (getVersion() != null) { + try { + joiner.add( + String.format( + "%sversion%s=%s", + prefix, + suffix, + URLEncoder.encode(String.valueOf(getVersion()), "UTF-8").replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + + // add `fields` to the URL query string + if (getFields() != null) { + for (String _key : getFields().keySet()) { + try { + joiner.add( + String.format( + "%sfields%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, _key, containerSuffix), + getFields().get(_key), + URLEncoder.encode(String.valueOf(getFields().get(_key)), "UTF-8") + .replaceAll("\\+", "%20"))); + } catch (UnsupportedEncodingException e) { + // Should never happen, UTF-8 is always supported + throw new RuntimeException(e); + } + } + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-async-client/README.md b/java/lance-namespace-async-client/README.md index 326947d6..b10bc92c 100644 --- a/java/lance-namespace-async-client/README.md +++ b/java/lance-namespace-async-client/README.md @@ -227,6 +227,8 @@ Class | Method | HTTP request | Description *MetadataApi* | [**restoreTableWithHttpInfo**](docs/MetadataApi.md#restoreTableWithHttpInfo) | **POST** /v1/table/{id}/restore | Restore table to a specific version *MetadataApi* | [**tableExists**](docs/MetadataApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists *MetadataApi* | [**tableExistsWithHttpInfo**](docs/MetadataApi.md#tableExistsWithHttpInfo) | **POST** /v1/table/{id}/exists | Check if a table exists +*MetadataApi* | [**updateFieldMetadata**](docs/MetadataApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata +*MetadataApi* | [**updateFieldMetadataWithHttpInfo**](docs/MetadataApi.md#updateFieldMetadataWithHttpInfo) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *MetadataApi* | [**updateTableSchemaMetadata**](docs/MetadataApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *MetadataApi* | [**updateTableSchemaMetadataWithHttpInfo**](docs/MetadataApi.md#updateTableSchemaMetadataWithHttpInfo) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *MetadataApi* | [**updateTableTag**](docs/MetadataApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -319,6 +321,8 @@ Class | Method | HTTP request | Description *TableApi* | [**restoreTableWithHttpInfo**](docs/TableApi.md#restoreTableWithHttpInfo) | **POST** /v1/table/{id}/restore | Restore table to a specific version *TableApi* | [**tableExists**](docs/TableApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists *TableApi* | [**tableExistsWithHttpInfo**](docs/TableApi.md#tableExistsWithHttpInfo) | **POST** /v1/table/{id}/exists | Check if a table exists +*TableApi* | [**updateFieldMetadata**](docs/TableApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata +*TableApi* | [**updateFieldMetadataWithHttpInfo**](docs/TableApi.md#updateFieldMetadataWithHttpInfo) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *TableApi* | [**updateTable**](docs/TableApi.md#updateTable) | **POST** /v1/table/{id}/update | Update rows in a table *TableApi* | [**updateTableWithHttpInfo**](docs/TableApi.md#updateTableWithHttpInfo) | **POST** /v1/table/{id}/update | Update rows in a table *TableApi* | [**updateTableSchemaMetadata**](docs/TableApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata @@ -470,6 +474,9 @@ Class | Method | HTTP request | Description - [TableExistsRequest](docs/TableExistsRequest.md) - [TableVersion](docs/TableVersion.md) - [TagContents](docs/TagContents.md) + - [UpdateFieldMetadataEntry](docs/UpdateFieldMetadataEntry.md) + - [UpdateFieldMetadataRequest](docs/UpdateFieldMetadataRequest.md) + - [UpdateFieldMetadataResponse](docs/UpdateFieldMetadataResponse.md) - [UpdateTableRequest](docs/UpdateTableRequest.md) - [UpdateTableResponse](docs/UpdateTableResponse.md) - [UpdateTableSchemaMetadataRequest](docs/UpdateTableSchemaMetadataRequest.md) diff --git a/java/lance-namespace-async-client/api/openapi.yaml b/java/lance-namespace-async-client/api/openapi.yaml index 4fe2aa50..54006172 100644 --- a/java/lance-namespace-async-client/api/openapi.yaml +++ b/java/lance-namespace-async-client/api/openapi.yaml @@ -1038,6 +1038,49 @@ paths: x-content-type: application/json x-accepts: - application/json + /v1/table/{id}/update_field_metadata: + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/delimiter' + post: + description: | + Update the Arrow field (column) metadata for table `id`. + + Each entry targets a field by `path` and merges the provided key-value + pairs into that field's existing metadata, or replaces it when `replace` + is true. A null metadata value deletes that key. + operationId: UpdateFieldMetadata + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/delimiter' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateFieldMetadataRequest' + required: true + responses: + "200": + $ref: '#/components/responses/UpdateFieldMetadataResponse' + "400": + $ref: '#/components/responses/BadRequestErrorResponse' + "401": + $ref: '#/components/responses/UnauthorizedErrorResponse' + "403": + $ref: '#/components/responses/ForbiddenErrorResponse' + "404": + $ref: '#/components/responses/NotFoundErrorResponse' + "503": + $ref: '#/components/responses/ServiceUnavailableErrorResponse' + "5XX": + $ref: '#/components/responses/ServerErrorResponse' + summary: Update per-field metadata + tags: + - Table + - Metadata + x-content-type: application/json + x-accepts: + - application/json /v1/table/{id}/drop_columns: parameters: - $ref: '#/components/parameters/id' @@ -2837,6 +2880,12 @@ components: schema: $ref: '#/components/schemas/AlterTableAddColumnsResponse' description: Add columns operation result + UpdateFieldMetadataResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateFieldMetadataResponse' + description: Field metadata update result AlterTableAlterColumnsResponse: content: application/json: @@ -7296,6 +7345,84 @@ components: type: integer required: - version + UpdateFieldMetadataRequest: + example: + identity: + api_key: api_key + auth_token: auth_token + id: + - id + - id + updates: + - path: path + metadata: + key: metadata + replace: true + - path: path + metadata: + key: metadata + replace: true + properties: + identity: + $ref: '#/components/schemas/Identity' + id: + description: Table identifier path (namespace + table name) + items: + type: string + type: array + updates: + description: List of per-field metadata updates to apply + items: + $ref: '#/components/schemas/UpdateFieldMetadataEntry' + type: array + required: + - updates + UpdateFieldMetadataEntry: + example: + path: path + metadata: + key: metadata + replace: true + properties: + path: + description: Field (column) path whose metadata to update + type: string + metadata: + additionalProperties: + nullable: true + type: string + description: | + Metadata key-value pairs to apply to the field. A null value + deletes that key. + replace: + description: | + If true, replace the field's existing metadata entirely; otherwise + merge into it (optional, defaults to false). + nullable: true + type: boolean + required: + - metadata + - path + UpdateFieldMetadataResponse: + example: + fields: + key: + key: fields + version: 0 + properties: + version: + description: The commit version associated with the operation + format: int64 + minimum: 0 + type: integer + fields: + additionalProperties: + additionalProperties: + type: string + description: | + Resulting metadata for each updated field, keyed by field path. + required: + - version AlterTableAlterColumnsRequest: example: identity: diff --git a/java/lance-namespace-async-client/docs/MetadataApi.md b/java/lance-namespace-async-client/docs/MetadataApi.md index 753dfef1..cdf39ea0 100644 --- a/java/lance-namespace-async-client/docs/MetadataApi.md +++ b/java/lance-namespace-async-client/docs/MetadataApi.md @@ -72,6 +72,8 @@ All URIs are relative to *http://localhost:2333* | [**restoreTableWithHttpInfo**](MetadataApi.md#restoreTableWithHttpInfo) | **POST** /v1/table/{id}/restore | Restore table to a specific version | | [**tableExists**](MetadataApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists | | [**tableExistsWithHttpInfo**](MetadataApi.md#tableExistsWithHttpInfo) | **POST** /v1/table/{id}/exists | Check if a table exists | +| [**updateFieldMetadata**](MetadataApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | +| [**updateFieldMetadataWithHttpInfo**](MetadataApi.md#updateFieldMetadataWithHttpInfo) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | | [**updateTableSchemaMetadata**](MetadataApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata | | [**updateTableSchemaMetadataWithHttpInfo**](MetadataApi.md#updateTableSchemaMetadataWithHttpInfo) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata | | [**updateTableTag**](MetadataApi.md#updateTableTag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version | @@ -6693,6 +6695,199 @@ CompletableFuture> | **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | +## updateFieldMetadata + +> CompletableFuture updateFieldMetadata(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.async.ApiClient; +import org.lance.namespace.client.async.ApiException; +import org.lance.namespace.client.async.Configuration; +import org.lance.namespace.client.async.auth.*; +import org.lance.namespace.client.async.models.*; +import org.lance.namespace.client.async.api.MetadataApi; +import java.util.concurrent.CompletableFuture; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + MetadataApi apiInstance = new MetadataApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + CompletableFuture result = apiInstance.updateFieldMetadata(id, updateFieldMetadataRequest, delimiter); + System.out.println(result.get()); + } catch (ApiException e) { + System.err.println("Exception when calling MetadataApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +CompletableFuture<[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md)> + + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + +## updateFieldMetadataWithHttpInfo + +> CompletableFuture> updateFieldMetadata updateFieldMetadataWithHttpInfo(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.async.ApiClient; +import org.lance.namespace.client.async.ApiException; +import org.lance.namespace.client.async.ApiResponse; +import org.lance.namespace.client.async.Configuration; +import org.lance.namespace.client.async.auth.*; +import org.lance.namespace.client.async.models.*; +import org.lance.namespace.client.async.api.MetadataApi; +import java.util.concurrent.CompletableFuture; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + MetadataApi apiInstance = new MetadataApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + CompletableFuture> response = apiInstance.updateFieldMetadataWithHttpInfo(id, updateFieldMetadataRequest, delimiter); + System.out.println("Status code: " + response.get().getStatusCode()); + System.out.println("Response headers: " + response.get().getHeaders()); + System.out.println("Response body: " + response.get().getData()); + } catch (InterruptedException | ExecutionException e) { + ApiException apiException = (ApiException)e.getCause(); + System.err.println("Exception when calling MetadataApi#updateFieldMetadata"); + System.err.println("Status code: " + apiException.getCode()); + System.err.println("Response headers: " + apiException.getResponseHeaders()); + System.err.println("Reason: " + apiException.getResponseBody()); + e.printStackTrace(); + } catch (ApiException e) { + System.err.println("Exception when calling MetadataApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Response headers: " + e.getResponseHeaders()); + System.err.println("Reason: " + e.getResponseBody()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +CompletableFuture> + + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + + ## updateTableSchemaMetadata > CompletableFuture> updateTableSchemaMetadata(id, requestBody, delimiter) diff --git a/java/lance-namespace-async-client/docs/TableApi.md b/java/lance-namespace-async-client/docs/TableApi.md index e3e74739..e0b8553f 100644 --- a/java/lance-namespace-async-client/docs/TableApi.md +++ b/java/lance-namespace-async-client/docs/TableApi.md @@ -80,6 +80,8 @@ All URIs are relative to *http://localhost:2333* | [**restoreTableWithHttpInfo**](TableApi.md#restoreTableWithHttpInfo) | **POST** /v1/table/{id}/restore | Restore table to a specific version | | [**tableExists**](TableApi.md#tableExists) | **POST** /v1/table/{id}/exists | Check if a table exists | | [**tableExistsWithHttpInfo**](TableApi.md#tableExistsWithHttpInfo) | **POST** /v1/table/{id}/exists | Check if a table exists | +| [**updateFieldMetadata**](TableApi.md#updateFieldMetadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | +| [**updateFieldMetadataWithHttpInfo**](TableApi.md#updateFieldMetadataWithHttpInfo) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata | | [**updateTable**](TableApi.md#updateTable) | **POST** /v1/table/{id}/update | Update rows in a table | | [**updateTableWithHttpInfo**](TableApi.md#updateTableWithHttpInfo) | **POST** /v1/table/{id}/update | Update rows in a table | | [**updateTableSchemaMetadata**](TableApi.md#updateTableSchemaMetadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata | @@ -7515,6 +7517,199 @@ CompletableFuture> | **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | +## updateFieldMetadata + +> CompletableFuture updateFieldMetadata(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.async.ApiClient; +import org.lance.namespace.client.async.ApiException; +import org.lance.namespace.client.async.Configuration; +import org.lance.namespace.client.async.auth.*; +import org.lance.namespace.client.async.models.*; +import org.lance.namespace.client.async.api.TableApi; +import java.util.concurrent.CompletableFuture; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + TableApi apiInstance = new TableApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + CompletableFuture result = apiInstance.updateFieldMetadata(id, updateFieldMetadataRequest, delimiter); + System.out.println(result.get()); + } catch (ApiException e) { + System.err.println("Exception when calling TableApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +CompletableFuture<[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md)> + + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + +## updateFieldMetadataWithHttpInfo + +> CompletableFuture> updateFieldMetadata updateFieldMetadataWithHttpInfo(id, updateFieldMetadataRequest, delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Example + +```java +// Import classes: +import org.lance.namespace.client.async.ApiClient; +import org.lance.namespace.client.async.ApiException; +import org.lance.namespace.client.async.ApiResponse; +import org.lance.namespace.client.async.Configuration; +import org.lance.namespace.client.async.auth.*; +import org.lance.namespace.client.async.models.*; +import org.lance.namespace.client.async.api.TableApi; +import java.util.concurrent.CompletableFuture; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("http://localhost:2333"); + + // Configure OAuth2 access token for authorization: OAuth2 + OAuth OAuth2 = (OAuth) defaultClient.getAuthentication("OAuth2"); + OAuth2.setAccessToken("YOUR ACCESS TOKEN"); + + // Configure API key authorization: ApiKeyAuth + ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); + ApiKeyAuth.setApiKey("YOUR API KEY"); + // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) + //ApiKeyAuth.setApiKeyPrefix("Token"); + + // Configure HTTP bearer authorization: BearerAuth + HttpBearerAuth BearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("BearerAuth"); + BearerAuth.setBearerToken("BEARER TOKEN"); + + TableApi apiInstance = new TableApi(defaultClient); + String id = "id_example"; // String | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + UpdateFieldMetadataRequest updateFieldMetadataRequest = new UpdateFieldMetadataRequest(); // UpdateFieldMetadataRequest | + String delimiter = "delimiter_example"; // String | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + try { + CompletableFuture> response = apiInstance.updateFieldMetadataWithHttpInfo(id, updateFieldMetadataRequest, delimiter); + System.out.println("Status code: " + response.get().getStatusCode()); + System.out.println("Response headers: " + response.get().getHeaders()); + System.out.println("Response body: " + response.get().getData()); + } catch (InterruptedException | ExecutionException e) { + ApiException apiException = (ApiException)e.getCause(); + System.err.println("Exception when calling TableApi#updateFieldMetadata"); + System.err.println("Status code: " + apiException.getCode()); + System.err.println("Response headers: " + apiException.getResponseHeaders()); + System.err.println("Reason: " + apiException.getResponseBody()); + e.printStackTrace(); + } catch (ApiException e) { + System.err.println("Exception when calling TableApi#updateFieldMetadata"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Response headers: " + e.getResponseHeaders()); + System.err.println("Reason: " + e.getResponseBody()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **String**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | | +| **updateFieldMetadataRequest** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | | +| **delimiter** | **String**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] | + +### Return type + +CompletableFuture> + + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | Field metadata update result | - | +| **400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +| **401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +| **403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +| **404** | A server-side problem that means can not find the specified resource. | - | +| **503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +| **5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + + ## updateTable > CompletableFuture updateTable(id, updateTableRequest, delimiter) diff --git a/java/lance-namespace-async-client/docs/UpdateFieldMetadataEntry.md b/java/lance-namespace-async-client/docs/UpdateFieldMetadataEntry.md new file mode 100644 index 00000000..839cae8e --- /dev/null +++ b/java/lance-namespace-async-client/docs/UpdateFieldMetadataEntry.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataEntry + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**path** | **String** | Field (column) path whose metadata to update | | +|**metadata** | **Map<String, String>** | Metadata key-value pairs to apply to the field. A null value deletes that key. | | +|**replace** | **Boolean** | If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). | [optional] | + + + diff --git a/java/lance-namespace-async-client/docs/UpdateFieldMetadataRequest.md b/java/lance-namespace-async-client/docs/UpdateFieldMetadataRequest.md new file mode 100644 index 00000000..c94a4d10 --- /dev/null +++ b/java/lance-namespace-async-client/docs/UpdateFieldMetadataRequest.md @@ -0,0 +1,15 @@ + + +# UpdateFieldMetadataRequest + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**identity** | [**Identity**](Identity.md) | | [optional] | +|**id** | **List<String>** | Table identifier path (namespace + table name) | [optional] | +|**updates** | [**List<UpdateFieldMetadataEntry>**](UpdateFieldMetadataEntry.md) | List of per-field metadata updates to apply | | + + + diff --git a/java/lance-namespace-async-client/docs/UpdateFieldMetadataResponse.md b/java/lance-namespace-async-client/docs/UpdateFieldMetadataResponse.md new file mode 100644 index 00000000..82496448 --- /dev/null +++ b/java/lance-namespace-async-client/docs/UpdateFieldMetadataResponse.md @@ -0,0 +1,14 @@ + + +# UpdateFieldMetadataResponse + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**version** | **Long** | The commit version associated with the operation | | +|**fields** | **Map<String, Map<String, String>>** | Resulting metadata for each updated field, keyed by field path. | [optional] | + + + diff --git a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/MetadataApi.java b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/MetadataApi.java index 6a570b6f..42e968d1 100644 --- a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/MetadataApi.java +++ b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/MetadataApi.java @@ -77,6 +77,8 @@ import org.lance.namespace.model.RestoreTableRequest; import org.lance.namespace.model.RestoreTableResponse; import org.lance.namespace.model.TableExistsRequest; +import org.lance.namespace.model.UpdateFieldMetadataRequest; +import org.lance.namespace.model.UpdateFieldMetadataResponse; import org.lance.namespace.model.UpdateTableTagRequest; import org.lance.namespace.model.UpdateTableTagResponse; @@ -5370,6 +5372,165 @@ private HttpRequest.Builder tableExistsRequestBuilder( return localVarRequestBuilder; } + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return CompletableFuture<UpdateFieldMetadataResponse> + * @throws ApiException if fails to make API call + */ + public CompletableFuture updateFieldMetadata( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = + updateFieldMetadataRequestBuilder(id, updateFieldMetadataRequest, delimiter); + return memberVarHttpClient + .sendAsync(localVarRequestBuilder.build(), HttpResponse.BodyHandlers.ofString()) + .thenComposeAsync( + localVarResponse -> { + if (localVarResponse.statusCode() / 100 != 2) { + return CompletableFuture.failedFuture( + getApiException("updateFieldMetadata", localVarResponse)); + } + try { + String responseBody = localVarResponse.body(); + return CompletableFuture.completedFuture( + responseBody == null || responseBody.isBlank() + ? null + : memberVarObjectMapper.readValue( + responseBody, new TypeReference() {})); + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + }); + } catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return CompletableFuture<ApiResponse<UpdateFieldMetadataResponse>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> + updateFieldMetadataWithHttpInfo( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = + updateFieldMetadataRequestBuilder(id, updateFieldMetadataRequest, delimiter); + return memberVarHttpClient + .sendAsync(localVarRequestBuilder.build(), HttpResponse.BodyHandlers.ofString()) + .thenComposeAsync( + localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode() / 100 != 2) { + return CompletableFuture.failedFuture( + getApiException("updateFieldMetadata", localVarResponse)); + } + try { + String responseBody = localVarResponse.body(); + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseBody == null || responseBody.isBlank() + ? null + : memberVarObjectMapper.readValue( + responseBody, + new TypeReference() {}))); + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + }); + } catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder updateFieldMetadataRequestBuilder( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + // verify the required parameter 'id' is set + if (id == null) { + throw new ApiException( + 400, "Missing the required parameter 'id' when calling updateFieldMetadata"); + } + // verify the required parameter 'updateFieldMetadataRequest' is set + if (updateFieldMetadataRequest == null) { + throw new ApiException( + 400, + "Missing the required parameter 'updateFieldMetadataRequest' when calling updateFieldMetadata"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = + "/v1/table/{id}/update_field_metadata".replace("{id}", ApiClient.urlEncode(id.toString())); + + List localVarQueryParams = new ArrayList<>(); + StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + String localVarQueryParameterBaseName; + localVarQueryParameterBaseName = "delimiter"; + localVarQueryParams.addAll(ApiClient.parameterToPairs("delimiter", delimiter)); + + if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { + StringJoiner queryJoiner = new StringJoiner("&"); + localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); + if (localVarQueryStringJoiner.length() != 0) { + queryJoiner.add(localVarQueryStringJoiner.toString()); + } + localVarRequestBuilder.uri( + URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); + } else { + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + } + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(updateFieldMetadataRequest); + localVarRequestBuilder.method( + "POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** * Update table schema metadata Replace the schema metadata for table `id` with the * provided key-value pairs. REST NAMESPACE ONLY REST namespace uses a direct object (map of diff --git a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/TableApi.java b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/TableApi.java index 0e2bec3d..e6db7847 100644 --- a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/TableApi.java +++ b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/client/async/api/TableApi.java @@ -78,6 +78,8 @@ import org.lance.namespace.model.RestoreTableRequest; import org.lance.namespace.model.RestoreTableResponse; import org.lance.namespace.model.TableExistsRequest; +import org.lance.namespace.model.UpdateFieldMetadataRequest; +import org.lance.namespace.model.UpdateFieldMetadataResponse; import org.lance.namespace.model.UpdateTableRequest; import org.lance.namespace.model.UpdateTableResponse; import org.lance.namespace.model.UpdateTableTagRequest; @@ -6277,6 +6279,165 @@ private HttpRequest.Builder tableExistsRequestBuilder( return localVarRequestBuilder; } + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return CompletableFuture<UpdateFieldMetadataResponse> + * @throws ApiException if fails to make API call + */ + public CompletableFuture updateFieldMetadata( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = + updateFieldMetadataRequestBuilder(id, updateFieldMetadataRequest, delimiter); + return memberVarHttpClient + .sendAsync(localVarRequestBuilder.build(), HttpResponse.BodyHandlers.ofString()) + .thenComposeAsync( + localVarResponse -> { + if (localVarResponse.statusCode() / 100 != 2) { + return CompletableFuture.failedFuture( + getApiException("updateFieldMetadata", localVarResponse)); + } + try { + String responseBody = localVarResponse.body(); + return CompletableFuture.completedFuture( + responseBody == null || responseBody.isBlank() + ? null + : memberVarObjectMapper.readValue( + responseBody, new TypeReference() {})); + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + }); + } catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + /** + * Update per-field metadata Update the Arrow field (column) metadata for table `id`. + * Each entry targets a field by `path` and merges the provided key-value pairs into + * that field's existing metadata, or replaces it when `replace` is true. A null + * metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return CompletableFuture<ApiResponse<UpdateFieldMetadataResponse>> + * @throws ApiException if fails to make API call + */ + public CompletableFuture> + updateFieldMetadataWithHttpInfo( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + try { + HttpRequest.Builder localVarRequestBuilder = + updateFieldMetadataRequestBuilder(id, updateFieldMetadataRequest, delimiter); + return memberVarHttpClient + .sendAsync(localVarRequestBuilder.build(), HttpResponse.BodyHandlers.ofString()) + .thenComposeAsync( + localVarResponse -> { + if (memberVarAsyncResponseInterceptor != null) { + memberVarAsyncResponseInterceptor.accept(localVarResponse); + } + if (localVarResponse.statusCode() / 100 != 2) { + return CompletableFuture.failedFuture( + getApiException("updateFieldMetadata", localVarResponse)); + } + try { + String responseBody = localVarResponse.body(); + return CompletableFuture.completedFuture( + new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + responseBody == null || responseBody.isBlank() + ? null + : memberVarObjectMapper.readValue( + responseBody, + new TypeReference() {}))); + } catch (IOException e) { + return CompletableFuture.failedFuture(new ApiException(e)); + } + }); + } catch (ApiException e) { + return CompletableFuture.failedFuture(e); + } + } + + private HttpRequest.Builder updateFieldMetadataRequestBuilder( + String id, UpdateFieldMetadataRequest updateFieldMetadataRequest, String delimiter) + throws ApiException { + // verify the required parameter 'id' is set + if (id == null) { + throw new ApiException( + 400, "Missing the required parameter 'id' when calling updateFieldMetadata"); + } + // verify the required parameter 'updateFieldMetadataRequest' is set + if (updateFieldMetadataRequest == null) { + throw new ApiException( + 400, + "Missing the required parameter 'updateFieldMetadataRequest' when calling updateFieldMetadata"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = + "/v1/table/{id}/update_field_metadata".replace("{id}", ApiClient.urlEncode(id.toString())); + + List localVarQueryParams = new ArrayList<>(); + StringJoiner localVarQueryStringJoiner = new StringJoiner("&"); + String localVarQueryParameterBaseName; + localVarQueryParameterBaseName = "delimiter"; + localVarQueryParams.addAll(ApiClient.parameterToPairs("delimiter", delimiter)); + + if (!localVarQueryParams.isEmpty() || localVarQueryStringJoiner.length() != 0) { + StringJoiner queryJoiner = new StringJoiner("&"); + localVarQueryParams.forEach(p -> queryJoiner.add(p.getName() + '=' + p.getValue())); + if (localVarQueryStringJoiner.length() != 0) { + queryJoiner.add(localVarQueryStringJoiner.toString()); + } + localVarRequestBuilder.uri( + URI.create(memberVarBaseUri + localVarPath + '?' + queryJoiner.toString())); + } else { + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + } + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(updateFieldMetadataRequest); + localVarRequestBuilder.method( + "POST", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } + /** * Update rows in a table Update existing rows in table `id`. * diff --git a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java new file mode 100644 index 00000000..752ae7a1 --- /dev/null +++ b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataEntry.java @@ -0,0 +1,260 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import org.lance.namespace.client.async.ApiClient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.openapitools.jackson.nullable.JsonNullable; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataEntry */ +@JsonPropertyOrder({ + UpdateFieldMetadataEntry.JSON_PROPERTY_PATH, + UpdateFieldMetadataEntry.JSON_PROPERTY_METADATA, + UpdateFieldMetadataEntry.JSON_PROPERTY_REPLACE +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataEntry { + public static final String JSON_PROPERTY_PATH = "path"; + @javax.annotation.Nonnull private String path; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + @javax.annotation.Nonnull private Map metadata = new HashMap<>(); + + public static final String JSON_PROPERTY_REPLACE = "replace"; + private JsonNullable replace = JsonNullable.undefined(); + + public UpdateFieldMetadataEntry() {} + + public UpdateFieldMetadataEntry path(@javax.annotation.Nonnull String path) { + this.path = path; + return this; + } + + /** + * Field (column) path whose metadata to update + * + * @return path + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_PATH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public String getPath() { + return path; + } + + @JsonProperty(JSON_PROPERTY_PATH) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPath(@javax.annotation.Nonnull String path) { + this.path = path; + } + + public UpdateFieldMetadataEntry metadata(@javax.annotation.Nonnull Map metadata) { + this.metadata = metadata; + return this; + } + + public UpdateFieldMetadataEntry putMetadataItem(String key, String metadataItem) { + if (this.metadata == null) { + this.metadata = new HashMap<>(); + } + this.metadata.put(key, metadataItem); + return this; + } + + /** + * Metadata key-value pairs to apply to the field. A null value deletes that key. + * + * @return metadata + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.ALWAYS) + public Map getMetadata() { + return metadata; + } + + @JsonProperty(JSON_PROPERTY_METADATA) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.ALWAYS) + public void setMetadata(@javax.annotation.Nonnull Map metadata) { + this.metadata = metadata; + } + + public UpdateFieldMetadataEntry replace(@javax.annotation.Nullable Boolean replace) { + this.replace = JsonNullable.of(replace); + return this; + } + + /** + * If true, replace the field's existing metadata entirely; otherwise merge into it (optional, + * defaults to false). + * + * @return replace + */ + @javax.annotation.Nullable + @JsonIgnore + public Boolean getReplace() { + return replace.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_REPLACE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public JsonNullable getReplace_JsonNullable() { + return replace; + } + + @JsonProperty(JSON_PROPERTY_REPLACE) + public void setReplace_JsonNullable(JsonNullable replace) { + this.replace = replace; + } + + public void setReplace(@javax.annotation.Nullable Boolean replace) { + this.replace = JsonNullable.of(replace); + } + + /** Return true if this UpdateFieldMetadataEntry object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataEntry updateFieldMetadataEntry = (UpdateFieldMetadataEntry) o; + return Objects.equals(this.path, updateFieldMetadataEntry.path) + && Objects.equals(this.metadata, updateFieldMetadataEntry.metadata) + && equalsNullable(this.replace, updateFieldMetadataEntry.replace); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b + || (a != null + && b != null + && a.isPresent() + && b.isPresent() + && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(path, metadata, hashCodeNullable(replace)); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[] {a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataEntry {\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" replace: ").append(toIndentedString(replace)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `path` to the URL query string + if (getPath() != null) { + joiner.add( + String.format( + "%spath%s=%s", + prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getPath())))); + } + + // add `metadata` to the URL query string + if (getMetadata() != null) { + for (String _key : getMetadata().keySet()) { + joiner.add( + String.format( + "%smetadata%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, _key, containerSuffix), + getMetadata().get(_key), + ApiClient.urlEncode(ApiClient.valueToString(getMetadata().get(_key))))); + } + } + + // add `replace` to the URL query string + if (getReplace() != null) { + joiner.add( + String.format( + "%sreplace%s=%s", + prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getReplace())))); + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java new file mode 100644 index 00000000..c437d293 --- /dev/null +++ b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataRequest.java @@ -0,0 +1,248 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import org.lance.namespace.client.async.ApiClient; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataRequest */ +@JsonPropertyOrder({ + UpdateFieldMetadataRequest.JSON_PROPERTY_IDENTITY, + UpdateFieldMetadataRequest.JSON_PROPERTY_ID, + UpdateFieldMetadataRequest.JSON_PROPERTY_UPDATES +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataRequest { + public static final String JSON_PROPERTY_IDENTITY = "identity"; + @javax.annotation.Nullable private Identity identity; + + public static final String JSON_PROPERTY_ID = "id"; + @javax.annotation.Nullable private List id = new ArrayList<>(); + + public static final String JSON_PROPERTY_UPDATES = "updates"; + @javax.annotation.Nonnull private List updates = new ArrayList<>(); + + public UpdateFieldMetadataRequest() {} + + public UpdateFieldMetadataRequest identity(@javax.annotation.Nullable Identity identity) { + this.identity = identity; + return this; + } + + /** + * Get identity + * + * @return identity + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_IDENTITY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Identity getIdentity() { + return identity; + } + + @JsonProperty(JSON_PROPERTY_IDENTITY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setIdentity(@javax.annotation.Nullable Identity identity) { + this.identity = identity; + } + + public UpdateFieldMetadataRequest id(@javax.annotation.Nullable List id) { + this.id = id; + return this; + } + + public UpdateFieldMetadataRequest addIdItem(String idItem) { + if (this.id == null) { + this.id = new ArrayList<>(); + } + this.id.add(idItem); + return this; + } + + /** + * Table identifier path (namespace + table name) + * + * @return id + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public List getId() { + return id; + } + + @JsonProperty(JSON_PROPERTY_ID) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setId(@javax.annotation.Nullable List id) { + this.id = id; + } + + public UpdateFieldMetadataRequest updates( + @javax.annotation.Nonnull List updates) { + this.updates = updates; + return this; + } + + public UpdateFieldMetadataRequest addUpdatesItem(UpdateFieldMetadataEntry updatesItem) { + if (this.updates == null) { + this.updates = new ArrayList<>(); + } + this.updates.add(updatesItem); + return this; + } + + /** + * List of per-field metadata updates to apply + * + * @return updates + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_UPDATES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public List getUpdates() { + return updates; + } + + @JsonProperty(JSON_PROPERTY_UPDATES) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUpdates(@javax.annotation.Nonnull List updates) { + this.updates = updates; + } + + /** Return true if this UpdateFieldMetadataRequest object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataRequest updateFieldMetadataRequest = (UpdateFieldMetadataRequest) o; + return Objects.equals(this.identity, updateFieldMetadataRequest.identity) + && Objects.equals(this.id, updateFieldMetadataRequest.id) + && Objects.equals(this.updates, updateFieldMetadataRequest.updates); + } + + @Override + public int hashCode() { + return Objects.hash(identity, id, updates); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataRequest {\n"); + sb.append(" identity: ").append(toIndentedString(identity)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" updates: ").append(toIndentedString(updates)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `identity` to the URL query string + if (getIdentity() != null) { + joiner.add(getIdentity().toUrlQueryString(prefix + "identity" + suffix)); + } + + // add `id` to the URL query string + if (getId() != null) { + for (int i = 0; i < getId().size(); i++) { + joiner.add( + String.format( + "%sid%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, i, containerSuffix), + ApiClient.urlEncode(ApiClient.valueToString(getId().get(i))))); + } + } + + // add `updates` to the URL query string + if (getUpdates() != null) { + for (int i = 0; i < getUpdates().size(); i++) { + if (getUpdates().get(i) != null) { + joiner.add( + getUpdates() + .get(i) + .toUrlQueryString( + String.format( + "%supdates%s%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, i, containerSuffix)))); + } + } + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java new file mode 100644 index 00000000..7711018f --- /dev/null +++ b/java/lance-namespace-async-client/src/main/java/org/lance/namespace/model/UpdateFieldMetadataResponse.java @@ -0,0 +1,196 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.model; + +import org.lance.namespace.client.async.ApiClient; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +/** UpdateFieldMetadataResponse */ +@JsonPropertyOrder({ + UpdateFieldMetadataResponse.JSON_PROPERTY_VERSION, + UpdateFieldMetadataResponse.JSON_PROPERTY_FIELDS +}) +@javax.annotation.Generated( + value = "org.openapitools.codegen.languages.JavaClientCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataResponse { + public static final String JSON_PROPERTY_VERSION = "version"; + @javax.annotation.Nonnull private Long version; + + public static final String JSON_PROPERTY_FIELDS = "fields"; + @javax.annotation.Nullable private Map> fields = new HashMap<>(); + + public UpdateFieldMetadataResponse() {} + + public UpdateFieldMetadataResponse version(@javax.annotation.Nonnull Long version) { + this.version = version; + return this; + } + + /** + * The commit version associated with the operation minimum: 0 + * + * @return version + */ + @javax.annotation.Nonnull + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public Long getVersion() { + return version; + } + + @JsonProperty(JSON_PROPERTY_VERSION) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setVersion(@javax.annotation.Nonnull Long version) { + this.version = version; + } + + public UpdateFieldMetadataResponse fields( + @javax.annotation.Nullable Map> fields) { + this.fields = fields; + return this; + } + + public UpdateFieldMetadataResponse putFieldsItem(String key, Map fieldsItem) { + if (this.fields == null) { + this.fields = new HashMap<>(); + } + this.fields.put(key, fieldsItem); + return this; + } + + /** + * Resulting metadata for each updated field, keyed by field path. + * + * @return fields + */ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_FIELDS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Map> getFields() { + return fields; + } + + @JsonProperty(JSON_PROPERTY_FIELDS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setFields(@javax.annotation.Nullable Map> fields) { + this.fields = fields; + } + + /** Return true if this UpdateFieldMetadataResponse object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataResponse updateFieldMetadataResponse = (UpdateFieldMetadataResponse) o; + return Objects.equals(this.version, updateFieldMetadataResponse.version) + && Objects.equals(this.fields, updateFieldMetadataResponse.fields); + } + + @Override + public int hashCode() { + return Objects.hash(version, fields); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataResponse {\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `version` to the URL query string + if (getVersion() != null) { + joiner.add( + String.format( + "%sversion%s=%s", + prefix, suffix, ApiClient.urlEncode(ApiClient.valueToString(getVersion())))); + } + + // add `fields` to the URL query string + if (getFields() != null) { + for (String _key : getFields().keySet()) { + joiner.add( + String.format( + "%sfields%s%s=%s", + prefix, + suffix, + "".equals(suffix) + ? "" + : String.format("%s%d%s", containerPrefix, _key, containerSuffix), + getFields().get(_key), + ApiClient.urlEncode(ApiClient.valueToString(getFields().get(_key))))); + } + } + + return joiner.toString(); + } +} diff --git a/java/lance-namespace-core-async/src/main/java/org/lance/namespace/async/LanceNamespaceAsync.java b/java/lance-namespace-core-async/src/main/java/org/lance/namespace/async/LanceNamespaceAsync.java index de99bda0..03ec17ba 100644 --- a/java/lance-namespace-core-async/src/main/java/org/lance/namespace/async/LanceNamespaceAsync.java +++ b/java/lance-namespace-core-async/src/main/java/org/lance/namespace/async/LanceNamespaceAsync.java @@ -610,6 +610,18 @@ default CompletableFuture updateTableSchemaMe new UnsupportedOperationException("Not supported: updateTableSchemaMetadata")); } + /** + * Update per-field metadata. + * + * @param request The update field metadata request + * @return A CompletableFuture containing the update field metadata response + */ + default CompletableFuture updateFieldMetadata( + UpdateFieldMetadataRequest request) { + return CompletableFuture.failedFuture( + new UnsupportedOperationException("Not supported: updateFieldMetadata")); + } + /** * Get table statistics. * diff --git a/java/lance-namespace-core/src/main/java/org/lance/namespace/LanceNamespace.java b/java/lance-namespace-core/src/main/java/org/lance/namespace/LanceNamespace.java index c6c2cd5b..2ce4db0f 100644 --- a/java/lance-namespace-core/src/main/java/org/lance/namespace/LanceNamespace.java +++ b/java/lance-namespace-core/src/main/java/org/lance/namespace/LanceNamespace.java @@ -591,6 +591,16 @@ default UpdateTableSchemaMetadataResponse updateTableSchemaMetadata( throw new UnsupportedOperationException("Not supported: updateTableSchemaMetadata"); } + /** + * Update per-field metadata. + * + * @param request The update field metadata request + * @return The update field metadata response + */ + default UpdateFieldMetadataResponse updateFieldMetadata(UpdateFieldMetadataRequest request) { + throw new UnsupportedOperationException("Not supported: updateFieldMetadata"); + } + /** * Get table statistics. * diff --git a/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/api/TableApi.java b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/api/TableApi.java index 8c675993..8c608ba9 100644 --- a/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/api/TableApi.java +++ b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/api/TableApi.java @@ -74,6 +74,8 @@ import org.lance.namespace.server.springboot.model.RestoreTableRequest; import org.lance.namespace.server.springboot.model.RestoreTableResponse; import org.lance.namespace.server.springboot.model.TableExistsRequest; +import org.lance.namespace.server.springboot.model.UpdateFieldMetadataRequest; +import org.lance.namespace.server.springboot.model.UpdateFieldMetadataResponse; import org.lance.namespace.server.springboot.model.UpdateTableRequest; import org.lance.namespace.server.springboot.model.UpdateTableResponse; import org.lance.namespace.server.springboot.model.UpdateTableTagRequest; @@ -6940,6 +6942,183 @@ default ResponseEntity tableExists( return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } + /** + * POST /v1/table/{id}/update_field_metadata : Update per-field metadata Update the Arrow field + * (column) metadata for table `id`. Each entry targets a field by `path` and + * merges the provided key-value pairs into that field's existing metadata, or replaces it + * when `replace` is true. A null metadata value deletes that key. + * + * @param id `string identifier` of an object in a namespace, following the Lance + * Namespace spec. When the value is equal to the delimiter, it represents the root namespace. + * For example, `v1/namespace/$/list` performs a `ListNamespace` on the + * root namespace. (required) + * @param updateFieldMetadataRequest (required) + * @param delimiter An optional delimiter of the `string identifier`, following the + * Lance Namespace spec. When not specified, the `$` delimiter must be used. + * (optional) + * @return Field metadata update result (status code 200) or Indicates a bad request error. It + * could be caused by an unexpected request body format or other forms of request validation + * failure, such as invalid json. Usually serves application/json content, although in some + * cases simple text/plain content might be returned by the server's middleware. (status + * code 400) or Unauthorized. The request lacks valid authentication credentials for the + * operation. (status code 401) or Forbidden. Authenticated user does not have the necessary + * permissions. (status code 403) or A server-side problem that means can not find the + * specified resource. (status code 404) or The service is not ready to handle the request. + * The client should wait and retry. The service may additionally send a Retry-After header to + * indicate when to retry. (status code 503) or A server-side problem that might not be + * addressable from the client side. Used for server 5xx errors without more specific + * documentation in individual routes. (status code 5XX) + */ + @Operation( + operationId = "updateFieldMetadata", + summary = "Update per-field metadata", + description = + "Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. ", + tags = {"Table", "Metadata"}, + responses = { + @ApiResponse( + responseCode = "200", + description = "Field metadata update result", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = UpdateFieldMetadataResponse.class)) + }), + @ApiResponse( + responseCode = "400", + description = + "Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }), + @ApiResponse( + responseCode = "401", + description = + "Unauthorized. The request lacks valid authentication credentials for the operation.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }), + @ApiResponse( + responseCode = "403", + description = "Forbidden. Authenticated user does not have the necessary permissions.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }), + @ApiResponse( + responseCode = "404", + description = "A server-side problem that means can not find the specified resource.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }), + @ApiResponse( + responseCode = "503", + description = + "The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }), + @ApiResponse( + responseCode = "5XX", + description = + "A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes.", + content = { + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class)) + }) + }, + security = { + @SecurityRequirement(name = "OAuth2"), + @SecurityRequirement(name = "ApiKeyAuth"), + @SecurityRequirement(name = "BearerAuth") + }) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/table/{id}/update_field_metadata", + produces = {"application/json"}, + consumes = {"application/json"}) + default ResponseEntity updateFieldMetadata( + @Parameter( + name = "id", + description = + "`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ", + required = true, + in = ParameterIn.PATH) + @PathVariable("id") + String id, + @Parameter(name = "UpdateFieldMetadataRequest", description = "", required = true) + @Valid + @RequestBody + UpdateFieldMetadataRequest updateFieldMetadataRequest, + @Parameter( + name = "delimiter", + description = + "An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ", + in = ParameterIn.QUERY) + @Valid + @RequestParam(value = "delimiter", required = false) + Optional delimiter) { + getRequest() + .ifPresent( + request -> { + for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"fields\" : { \"key\" : { \"key\" : \"fields\" } }, \"version\" : 0 }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { + String exampleString = + "{ \"code\" : 4, \"instance\" : \"/v1/table/production$users/describe\", \"detail\" : \"The table may have been dropped or renamed\", \"error\" : \"Table 'users' not found in namespace 'production'\" }"; + ApiUtil.setExampleResponse(request, "application/json", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** * POST /v1/table/{id}/update : Update rows in a table Update existing rows in table * `id`. diff --git a/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataEntry.java b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataEntry.java new file mode 100644 index 00000000..850a2450 --- /dev/null +++ b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataEntry.java @@ -0,0 +1,170 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.server.springboot.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; + +import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** UpdateFieldMetadataEntry */ +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataEntry { + + private String path; + + @Valid private Map metadata = new HashMap<>(); + + private Boolean replace = null; + + public UpdateFieldMetadataEntry() { + super(); + } + + /** Constructor with only required parameters */ + public UpdateFieldMetadataEntry(String path, Map metadata) { + this.path = path; + this.metadata = metadata; + } + + public UpdateFieldMetadataEntry path(String path) { + this.path = path; + return this; + } + + /** + * Field (column) path whose metadata to update + * + * @return path + */ + @NotNull + @Schema( + name = "path", + description = "Field (column) path whose metadata to update", + requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("path") + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public UpdateFieldMetadataEntry metadata(Map metadata) { + this.metadata = metadata; + return this; + } + + public UpdateFieldMetadataEntry putMetadataItem(String key, String metadataItem) { + if (this.metadata == null) { + this.metadata = new HashMap<>(); + } + this.metadata.put(key, metadataItem); + return this; + } + + /** + * Metadata key-value pairs to apply to the field. A null value deletes that key. + * + * @return metadata + */ + @NotNull + @Schema( + name = "metadata", + description = + "Metadata key-value pairs to apply to the field. A null value deletes that key. ", + requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("metadata") + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + public UpdateFieldMetadataEntry replace(Boolean replace) { + this.replace = replace; + return this; + } + + /** + * If true, replace the field's existing metadata entirely; otherwise merge into it (optional, + * defaults to false). + * + * @return replace + */ + @Schema( + name = "replace", + description = + "If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). ", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("replace") + public Boolean getReplace() { + return replace; + } + + public void setReplace(Boolean replace) { + this.replace = replace; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataEntry updateFieldMetadataEntry = (UpdateFieldMetadataEntry) o; + return Objects.equals(this.path, updateFieldMetadataEntry.path) + && Objects.equals(this.metadata, updateFieldMetadataEntry.metadata) + && Objects.equals(this.replace, updateFieldMetadataEntry.replace); + } + + @Override + public int hashCode() { + return Objects.hash(path, metadata, replace); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataEntry {\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); + sb.append(" replace: ").append(toIndentedString(replace)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataRequest.java b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataRequest.java new file mode 100644 index 00000000..f0f2837f --- /dev/null +++ b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataRequest.java @@ -0,0 +1,172 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.server.springboot.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; + +import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** UpdateFieldMetadataRequest */ +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataRequest { + + private Identity identity; + + @Valid private List id = new ArrayList<>(); + + @Valid private List<@Valid UpdateFieldMetadataEntry> updates = new ArrayList<>(); + + public UpdateFieldMetadataRequest() { + super(); + } + + /** Constructor with only required parameters */ + public UpdateFieldMetadataRequest(List<@Valid UpdateFieldMetadataEntry> updates) { + this.updates = updates; + } + + public UpdateFieldMetadataRequest identity(Identity identity) { + this.identity = identity; + return this; + } + + /** + * Get identity + * + * @return identity + */ + @Valid + @Schema(name = "identity", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("identity") + public Identity getIdentity() { + return identity; + } + + public void setIdentity(Identity identity) { + this.identity = identity; + } + + public UpdateFieldMetadataRequest id(List id) { + this.id = id; + return this; + } + + public UpdateFieldMetadataRequest addIdItem(String idItem) { + if (this.id == null) { + this.id = new ArrayList<>(); + } + this.id.add(idItem); + return this; + } + + /** + * Table identifier path (namespace + table name) + * + * @return id + */ + @Schema( + name = "id", + description = "Table identifier path (namespace + table name)", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("id") + public List getId() { + return id; + } + + public void setId(List id) { + this.id = id; + } + + public UpdateFieldMetadataRequest updates(List<@Valid UpdateFieldMetadataEntry> updates) { + this.updates = updates; + return this; + } + + public UpdateFieldMetadataRequest addUpdatesItem(UpdateFieldMetadataEntry updatesItem) { + if (this.updates == null) { + this.updates = new ArrayList<>(); + } + this.updates.add(updatesItem); + return this; + } + + /** + * List of per-field metadata updates to apply + * + * @return updates + */ + @NotNull + @Valid + @Schema( + name = "updates", + description = "List of per-field metadata updates to apply", + requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("updates") + public List<@Valid UpdateFieldMetadataEntry> getUpdates() { + return updates; + } + + public void setUpdates(List<@Valid UpdateFieldMetadataEntry> updates) { + this.updates = updates; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataRequest updateFieldMetadataRequest = (UpdateFieldMetadataRequest) o; + return Objects.equals(this.identity, updateFieldMetadataRequest.identity) + && Objects.equals(this.id, updateFieldMetadataRequest.id) + && Objects.equals(this.updates, updateFieldMetadataRequest.updates); + } + + @Override + public int hashCode() { + return Objects.hash(identity, id, updates); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataRequest {\n"); + sb.append(" identity: ").append(toIndentedString(identity)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" updates: ").append(toIndentedString(updates)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataResponse.java b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataResponse.java new file mode 100644 index 00000000..7119b030 --- /dev/null +++ b/java/lance-namespace-springboot-server/src/main/java/org/lance/namespace/server/springboot/model/UpdateFieldMetadataResponse.java @@ -0,0 +1,140 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.server.springboot.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Generated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; + +import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** UpdateFieldMetadataResponse */ +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + comments = "Generator version: 7.12.0") +public class UpdateFieldMetadataResponse { + + private Long version; + + @Valid private Map> fields = new HashMap<>(); + + public UpdateFieldMetadataResponse() { + super(); + } + + /** Constructor with only required parameters */ + public UpdateFieldMetadataResponse(Long version) { + this.version = version; + } + + public UpdateFieldMetadataResponse version(Long version) { + this.version = version; + return this; + } + + /** + * The commit version associated with the operation minimum: 0 + * + * @return version + */ + @NotNull + @Min(0L) + @Schema( + name = "version", + description = "The commit version associated with the operation", + requiredMode = Schema.RequiredMode.REQUIRED) + @JsonProperty("version") + public Long getVersion() { + return version; + } + + public void setVersion(Long version) { + this.version = version; + } + + public UpdateFieldMetadataResponse fields(Map> fields) { + this.fields = fields; + return this; + } + + public UpdateFieldMetadataResponse putFieldsItem(String key, Map fieldsItem) { + if (this.fields == null) { + this.fields = new HashMap<>(); + } + this.fields.put(key, fieldsItem); + return this; + } + + /** + * Resulting metadata for each updated field, keyed by field path. + * + * @return fields + */ + @Valid + @Schema( + name = "fields", + description = "Resulting metadata for each updated field, keyed by field path. ", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @JsonProperty("fields") + public Map> getFields() { + return fields; + } + + public void setFields(Map> fields) { + this.fields = fields; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UpdateFieldMetadataResponse updateFieldMetadataResponse = (UpdateFieldMetadataResponse) o; + return Objects.equals(this.version, updateFieldMetadataResponse.version) + && Objects.equals(this.fields, updateFieldMetadataResponse.fields); + } + + @Override + public int hashCode() { + return Objects.hash(version, fields); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UpdateFieldMetadataResponse {\n"); + sb.append(" version: ").append(toIndentedString(version)).append("\n"); + sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/python/lance_namespace/lance_namespace/__init__.py b/python/lance_namespace/lance_namespace/__init__.py index 20e0ec01..49586d5c 100644 --- a/python/lance_namespace/lance_namespace/__init__.py +++ b/python/lance_namespace/lance_namespace/__init__.py @@ -147,6 +147,8 @@ RestoreTableResponse, TableExistsRequest, TableVersion, + UpdateFieldMetadataRequest, + UpdateFieldMetadataResponse, UpdateTableRequest, UpdateTableResponse, UpdateTableSchemaMetadataRequest, @@ -279,6 +281,8 @@ "RestoreTableResponse", "TableExistsRequest", "TableVersion", + "UpdateFieldMetadataRequest", + "UpdateFieldMetadataResponse", "UpdateTableRequest", "UpdateTableResponse", "UpdateTableSchemaMetadataRequest", @@ -858,6 +862,22 @@ def update_table_schema_metadata( """ raise UnsupportedOperationError("Not supported: update_table_schema_metadata") + def update_field_metadata( + self, request: UpdateFieldMetadataRequest + ) -> UpdateFieldMetadataResponse: + """Update per-field metadata. + + Raises + ------ + NamespaceNotFoundError + If the namespace does not exist. + TableNotFoundError + If the table does not exist. + ConcurrentModificationError + If a concurrent modification conflict occurs. + """ + raise UnsupportedOperationError("Not supported: update_field_metadata") + def get_table_stats(self, request: GetTableStatsRequest) -> GetTableStatsResponse: """Get table statistics. diff --git a/python/lance_namespace_urllib3_client/README.md b/python/lance_namespace_urllib3_client/README.md index f97f1a73..10b13c7e 100644 --- a/python/lance_namespace_urllib3_client/README.md +++ b/python/lance_namespace_urllib3_client/README.md @@ -167,6 +167,7 @@ Class | Method | HTTP request | Description *MetadataApi* | [**rename_table**](docs/MetadataApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table *MetadataApi* | [**restore_table**](docs/MetadataApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version *MetadataApi* | [**table_exists**](docs/MetadataApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +*MetadataApi* | [**update_field_metadata**](docs/MetadataApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *MetadataApi* | [**update_table_schema_metadata**](docs/MetadataApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *MetadataApi* | [**update_table_tag**](docs/MetadataApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version *NamespaceApi* | [**create_namespace**](docs/NamespaceApi.md#create_namespace) | **POST** /v1/namespace/{id}/create | Create a new namespace @@ -213,6 +214,7 @@ Class | Method | HTTP request | Description *TableApi* | [**rename_table**](docs/TableApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table *TableApi* | [**restore_table**](docs/TableApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version *TableApi* | [**table_exists**](docs/TableApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +*TableApi* | [**update_field_metadata**](docs/TableApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *TableApi* | [**update_table**](docs/TableApi.md#update_table) | **POST** /v1/table/{id}/update | Update rows in a table *TableApi* | [**update_table_schema_metadata**](docs/TableApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *TableApi* | [**update_table_tag**](docs/TableApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -353,6 +355,9 @@ Class | Method | HTTP request | Description - [TableExistsRequest](docs/TableExistsRequest.md) - [TableVersion](docs/TableVersion.md) - [TagContents](docs/TagContents.md) + - [UpdateFieldMetadataEntry](docs/UpdateFieldMetadataEntry.md) + - [UpdateFieldMetadataRequest](docs/UpdateFieldMetadataRequest.md) + - [UpdateFieldMetadataResponse](docs/UpdateFieldMetadataResponse.md) - [UpdateTableRequest](docs/UpdateTableRequest.md) - [UpdateTableResponse](docs/UpdateTableResponse.md) - [UpdateTableSchemaMetadataRequest](docs/UpdateTableSchemaMetadataRequest.md) diff --git a/python/lance_namespace_urllib3_client/docs/MetadataApi.md b/python/lance_namespace_urllib3_client/docs/MetadataApi.md index 4b6f1b98..8e0f4699 100644 --- a/python/lance_namespace_urllib3_client/docs/MetadataApi.md +++ b/python/lance_namespace_urllib3_client/docs/MetadataApi.md @@ -38,6 +38,7 @@ Method | HTTP request | Description [**rename_table**](MetadataApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table [**restore_table**](MetadataApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version [**table_exists**](MetadataApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +[**update_field_metadata**](MetadataApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata [**update_table_schema_metadata**](MetadataApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata [**update_table_tag**](MetadataApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -3562,6 +3563,110 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **update_field_metadata** +> UpdateFieldMetadataResponse update_field_metadata(id, update_field_metadata_request, delimiter=delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. + +Each entry targets a field by `path` and merges the provided key-value +pairs into that field's existing metadata, or replaces it when `replace` +is true. A null metadata value deletes that key. + + +### Example + +* OAuth Authentication (OAuth2): +* Api Key Authentication (ApiKeyAuth): +* Bearer Authentication (BearerAuth): + +```python +import lance_namespace_urllib3_client +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse +from lance_namespace_urllib3_client.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost:2333 +# See configuration.py for a list of all supported configuration parameters. +configuration = lance_namespace_urllib3_client.Configuration( + host = "http://localhost:2333" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +configuration.access_token = os.environ["ACCESS_TOKEN"] + +# Configure API key authorization: ApiKeyAuth +configuration.api_key['ApiKeyAuth'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['ApiKeyAuth'] = 'Bearer' + +# Configure Bearer authorization: BearerAuth +configuration = lance_namespace_urllib3_client.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with lance_namespace_urllib3_client.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = lance_namespace_urllib3_client.MetadataApi(api_client) + id = 'id_example' # str | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + update_field_metadata_request = lance_namespace_urllib3_client.UpdateFieldMetadataRequest() # UpdateFieldMetadataRequest | + delimiter = 'delimiter_example' # str | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. (optional) + + try: + # Update per-field metadata + api_response = api_instance.update_field_metadata(id, update_field_metadata_request, delimiter=delimiter) + print("The response of MetadataApi->update_field_metadata:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MetadataApi->update_field_metadata: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **id** | **str**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | + **update_field_metadata_request** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | + **delimiter** | **str**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] + +### Return type + +[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Field metadata update result | - | +**400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +**401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +**403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +**404** | A server-side problem that means can not find the specified resource. | - | +**503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +**5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **update_table_schema_metadata** > Dict[str, str] update_table_schema_metadata(id, request_body, delimiter=delimiter) diff --git a/python/lance_namespace_urllib3_client/docs/TableApi.md b/python/lance_namespace_urllib3_client/docs/TableApi.md index 3be73090..d60a56d1 100644 --- a/python/lance_namespace_urllib3_client/docs/TableApi.md +++ b/python/lance_namespace_urllib3_client/docs/TableApi.md @@ -42,6 +42,7 @@ Method | HTTP request | Description [**rename_table**](TableApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table [**restore_table**](TableApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version [**table_exists**](TableApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +[**update_field_metadata**](TableApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata [**update_table**](TableApi.md#update_table) | **POST** /v1/table/{id}/update | Update rows in a table [**update_table_schema_metadata**](TableApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata [**update_table_tag**](TableApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -4038,6 +4039,110 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **update_field_metadata** +> UpdateFieldMetadataResponse update_field_metadata(id, update_field_metadata_request, delimiter=delimiter) + +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. + +Each entry targets a field by `path` and merges the provided key-value +pairs into that field's existing metadata, or replaces it when `replace` +is true. A null metadata value deletes that key. + + +### Example + +* OAuth Authentication (OAuth2): +* Api Key Authentication (ApiKeyAuth): +* Bearer Authentication (BearerAuth): + +```python +import lance_namespace_urllib3_client +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse +from lance_namespace_urllib3_client.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost:2333 +# See configuration.py for a list of all supported configuration parameters. +configuration = lance_namespace_urllib3_client.Configuration( + host = "http://localhost:2333" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +configuration.access_token = os.environ["ACCESS_TOKEN"] + +# Configure API key authorization: ApiKeyAuth +configuration.api_key['ApiKeyAuth'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['ApiKeyAuth'] = 'Bearer' + +# Configure Bearer authorization: BearerAuth +configuration = lance_namespace_urllib3_client.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with lance_namespace_urllib3_client.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = lance_namespace_urllib3_client.TableApi(api_client) + id = 'id_example' # str | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. + update_field_metadata_request = lance_namespace_urllib3_client.UpdateFieldMetadataRequest() # UpdateFieldMetadataRequest | + delimiter = 'delimiter_example' # str | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. (optional) + + try: + # Update per-field metadata + api_response = api_instance.update_field_metadata(id, update_field_metadata_request, delimiter=delimiter) + print("The response of TableApi->update_field_metadata:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling TableApi->update_field_metadata: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **id** | **str**| `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | + **update_field_metadata_request** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md)| | + **delimiter** | **str**| An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | [optional] + +### Return type + +[**UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Field metadata update result | - | +**400** | Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware. | - | +**401** | Unauthorized. The request lacks valid authentication credentials for the operation. | - | +**403** | Forbidden. Authenticated user does not have the necessary permissions. | - | +**404** | A server-side problem that means can not find the specified resource. | - | +**503** | The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry. | - | +**5XX** | A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **update_table** > UpdateTableResponse update_table(id, update_table_request, delimiter=delimiter) diff --git a/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataEntry.md b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataEntry.md new file mode 100644 index 00000000..6a691c6b --- /dev/null +++ b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataEntry.md @@ -0,0 +1,31 @@ +# UpdateFieldMetadataEntry + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**path** | **str** | Field (column) path whose metadata to update | +**metadata** | **Dict[str, Optional[str]]** | Metadata key-value pairs to apply to the field. A null value deletes that key. | +**replace** | **bool** | If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). | [optional] + +## Example + +```python +from lance_namespace_urllib3_client.models.update_field_metadata_entry import UpdateFieldMetadataEntry + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateFieldMetadataEntry from a JSON string +update_field_metadata_entry_instance = UpdateFieldMetadataEntry.from_json(json) +# print the JSON string representation of the object +print(UpdateFieldMetadataEntry.to_json()) + +# convert the object into a dict +update_field_metadata_entry_dict = update_field_metadata_entry_instance.to_dict() +# create an instance of UpdateFieldMetadataEntry from a dict +update_field_metadata_entry_from_dict = UpdateFieldMetadataEntry.from_dict(update_field_metadata_entry_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataRequest.md b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataRequest.md new file mode 100644 index 00000000..321a1a4b --- /dev/null +++ b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataRequest.md @@ -0,0 +1,31 @@ +# UpdateFieldMetadataRequest + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**identity** | [**Identity**](Identity.md) | | [optional] +**id** | **List[str]** | Table identifier path (namespace + table name) | [optional] +**updates** | [**List[UpdateFieldMetadataEntry]**](UpdateFieldMetadataEntry.md) | List of per-field metadata updates to apply | + +## Example + +```python +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateFieldMetadataRequest from a JSON string +update_field_metadata_request_instance = UpdateFieldMetadataRequest.from_json(json) +# print the JSON string representation of the object +print(UpdateFieldMetadataRequest.to_json()) + +# convert the object into a dict +update_field_metadata_request_dict = update_field_metadata_request_instance.to_dict() +# create an instance of UpdateFieldMetadataRequest from a dict +update_field_metadata_request_from_dict = UpdateFieldMetadataRequest.from_dict(update_field_metadata_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataResponse.md b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataResponse.md new file mode 100644 index 00000000..3a9ec188 --- /dev/null +++ b/python/lance_namespace_urllib3_client/docs/UpdateFieldMetadataResponse.md @@ -0,0 +1,30 @@ +# UpdateFieldMetadataResponse + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**version** | **int** | The commit version associated with the operation | +**fields** | **Dict[str, Dict[str, str]]** | Resulting metadata for each updated field, keyed by field path. | [optional] + +## Example + +```python +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateFieldMetadataResponse from a JSON string +update_field_metadata_response_instance = UpdateFieldMetadataResponse.from_json(json) +# print the JSON string representation of the object +print(UpdateFieldMetadataResponse.to_json()) + +# convert the object into a dict +update_field_metadata_response_dict = update_field_metadata_response_instance.to_dict() +# create an instance of UpdateFieldMetadataResponse from a dict +update_field_metadata_response_from_dict = UpdateFieldMetadataResponse.from_dict(update_field_metadata_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/__init__.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/__init__.py index 51c9e23b..dc9acf32 100644 --- a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/__init__.py +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/__init__.py @@ -163,6 +163,9 @@ from lance_namespace_urllib3_client.models.table_exists_request import TableExistsRequest from lance_namespace_urllib3_client.models.table_version import TableVersion from lance_namespace_urllib3_client.models.tag_contents import TagContents +from lance_namespace_urllib3_client.models.update_field_metadata_entry import UpdateFieldMetadataEntry +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse from lance_namespace_urllib3_client.models.update_table_request import UpdateTableRequest from lance_namespace_urllib3_client.models.update_table_response import UpdateTableResponse from lance_namespace_urllib3_client.models.update_table_schema_metadata_request import UpdateTableSchemaMetadataRequest diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/metadata_api.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/metadata_api.py index 64e24c77..57ab487f 100644 --- a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/metadata_api.py +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/metadata_api.py @@ -78,6 +78,8 @@ from lance_namespace_urllib3_client.models.restore_table_request import RestoreTableRequest from lance_namespace_urllib3_client.models.restore_table_response import RestoreTableResponse from lance_namespace_urllib3_client.models.table_exists_request import TableExistsRequest +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse from lance_namespace_urllib3_client.models.update_table_tag_request import UpdateTableTagRequest from lance_namespace_urllib3_client.models.update_table_tag_response import UpdateTableTagResponse @@ -11278,6 +11280,332 @@ def _table_exists_serialize( + @validate_call + def update_field_metadata( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UpdateFieldMetadataResponse: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_field_metadata_with_http_info( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UpdateFieldMetadataResponse]: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_field_metadata_without_preload_content( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_field_metadata_serialize( + self, + id, + update_field_metadata_request, + delimiter, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if id is not None: + _path_params['id'] = id + # process the query parameters + if delimiter is not None: + + _query_params.append(('delimiter', delimiter)) + + # process the header parameters + # process the form parameters + # process the body parameter + if update_field_metadata_request is not None: + _body_params = update_field_metadata_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'ApiKeyAuth', + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/table/{id}/update_field_metadata', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def update_table_schema_metadata( self, diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/table_api.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/table_api.py index 1589ebf1..e2bf6b69 100644 --- a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/table_api.py +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/api/table_api.py @@ -79,6 +79,8 @@ from lance_namespace_urllib3_client.models.restore_table_request import RestoreTableRequest from lance_namespace_urllib3_client.models.restore_table_response import RestoreTableResponse from lance_namespace_urllib3_client.models.table_exists_request import TableExistsRequest +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse from lance_namespace_urllib3_client.models.update_table_request import UpdateTableRequest from lance_namespace_urllib3_client.models.update_table_response import UpdateTableResponse from lance_namespace_urllib3_client.models.update_table_tag_request import UpdateTableTagRequest @@ -12801,6 +12803,332 @@ def _table_exists_serialize( + @validate_call + def update_field_metadata( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UpdateFieldMetadataResponse: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_field_metadata_with_http_info( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UpdateFieldMetadataResponse]: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_field_metadata_without_preload_content( + self, + id: Annotated[StrictStr, Field(description="`string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. ")], + update_field_metadata_request: UpdateFieldMetadataRequest, + delimiter: Annotated[Optional[StrictStr], Field(description="An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. ")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update per-field metadata + + Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + + :param id: `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. (required) + :type id: str + :param update_field_metadata_request: (required) + :type update_field_metadata_request: UpdateFieldMetadataRequest + :param delimiter: An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. + :type delimiter: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_field_metadata_serialize( + id=id, + update_field_metadata_request=update_field_metadata_request, + delimiter=delimiter, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UpdateFieldMetadataResponse", + '400': "ErrorResponse", + '401': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '503': "ErrorResponse", + '5XX': "ErrorResponse", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_field_metadata_serialize( + self, + id, + update_field_metadata_request, + delimiter, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if id is not None: + _path_params['id'] = id + # process the query parameters + if delimiter is not None: + + _query_params.append(('delimiter', delimiter)) + + # process the header parameters + # process the form parameters + # process the body parameter + if update_field_metadata_request is not None: + _body_params = update_field_metadata_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'ApiKeyAuth', + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/table/{id}/update_field_metadata', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def update_table( self, diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/__init__.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/__init__.py index 16acda89..a885e68a 100644 --- a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/__init__.py +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/__init__.py @@ -139,6 +139,9 @@ from lance_namespace_urllib3_client.models.table_exists_request import TableExistsRequest from lance_namespace_urllib3_client.models.table_version import TableVersion from lance_namespace_urllib3_client.models.tag_contents import TagContents +from lance_namespace_urllib3_client.models.update_field_metadata_entry import UpdateFieldMetadataEntry +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse from lance_namespace_urllib3_client.models.update_table_request import UpdateTableRequest from lance_namespace_urllib3_client.models.update_table_response import UpdateTableResponse from lance_namespace_urllib3_client.models.update_table_schema_metadata_request import UpdateTableSchemaMetadataRequest diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_entry.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_entry.py new file mode 100644 index 00000000..d26d129e --- /dev/null +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_entry.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class UpdateFieldMetadataEntry(BaseModel): + """ + UpdateFieldMetadataEntry + """ # noqa: E501 + path: StrictStr = Field(description="Field (column) path whose metadata to update") + metadata: Dict[str, Optional[StrictStr]] = Field(description="Metadata key-value pairs to apply to the field. A null value deletes that key. ") + replace: Optional[StrictBool] = Field(default=None, description="If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). ") + __properties: ClassVar[List[str]] = ["path", "metadata", "replace"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataEntry from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if replace (nullable) is None + # and model_fields_set contains the field + if self.replace is None and "replace" in self.model_fields_set: + _dict['replace'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataEntry from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "path": obj.get("path"), + "metadata": obj.get("metadata"), + "replace": obj.get("replace") + }) + return _obj + + diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_request.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_request.py new file mode 100644 index 00000000..6dfd81f5 --- /dev/null +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_request.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from lance_namespace_urllib3_client.models.identity import Identity +from lance_namespace_urllib3_client.models.update_field_metadata_entry import UpdateFieldMetadataEntry +from typing import Optional, Set +from typing_extensions import Self + +class UpdateFieldMetadataRequest(BaseModel): + """ + UpdateFieldMetadataRequest + """ # noqa: E501 + identity: Optional[Identity] = None + id: Optional[List[StrictStr]] = Field(default=None, description="Table identifier path (namespace + table name)") + updates: List[UpdateFieldMetadataEntry] = Field(description="List of per-field metadata updates to apply") + __properties: ClassVar[List[str]] = ["identity", "id", "updates"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of identity + if self.identity: + _dict['identity'] = self.identity.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in updates (list) + _items = [] + if self.updates: + for _item_updates in self.updates: + if _item_updates: + _items.append(_item_updates.to_dict()) + _dict['updates'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "identity": Identity.from_dict(obj["identity"]) if obj.get("identity") is not None else None, + "id": obj.get("id"), + "updates": [UpdateFieldMetadataEntry.from_dict(_item) for _item in obj["updates"]] if obj.get("updates") is not None else None + }) + return _obj + + diff --git a/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_response.py b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_response.py new file mode 100644 index 00000000..a79d311e --- /dev/null +++ b/python/lance_namespace_urllib3_client/lance_namespace_urllib3_client/models/update_field_metadata_response.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class UpdateFieldMetadataResponse(BaseModel): + """ + UpdateFieldMetadataResponse + """ # noqa: E501 + version: Annotated[int, Field(strict=True, ge=0)] = Field(description="The commit version associated with the operation") + fields: Optional[Dict[str, Dict[str, StrictStr]]] = Field(default=None, description="Resulting metadata for each updated field, keyed by field path. ") + __properties: ClassVar[List[str]] = ["version", "fields"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateFieldMetadataResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "version": obj.get("version"), + "fields": obj.get("fields") + }) + return _obj + + diff --git a/python/lance_namespace_urllib3_client/test/test_metadata_api.py b/python/lance_namespace_urllib3_client/test/test_metadata_api.py index d3b00d51..5b11f80e 100644 --- a/python/lance_namespace_urllib3_client/test/test_metadata_api.py +++ b/python/lance_namespace_urllib3_client/test/test_metadata_api.py @@ -264,6 +264,13 @@ def test_table_exists(self) -> None: """ pass + def test_update_field_metadata(self) -> None: + """Test case for update_field_metadata + + Update per-field metadata + """ + pass + def test_update_table_schema_metadata(self) -> None: """Test case for update_table_schema_metadata diff --git a/python/lance_namespace_urllib3_client/test/test_table_api.py b/python/lance_namespace_urllib3_client/test/test_table_api.py index 154aca05..898f81f3 100644 --- a/python/lance_namespace_urllib3_client/test/test_table_api.py +++ b/python/lance_namespace_urllib3_client/test/test_table_api.py @@ -292,6 +292,13 @@ def test_table_exists(self) -> None: """ pass + def test_update_field_metadata(self) -> None: + """Test case for update_field_metadata + + Update per-field metadata + """ + pass + def test_update_table(self) -> None: """Test case for update_table diff --git a/python/lance_namespace_urllib3_client/test/test_update_field_metadata_entry.py b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_entry.py new file mode 100644 index 00000000..7adb75d9 --- /dev/null +++ b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_entry.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from lance_namespace_urllib3_client.models.update_field_metadata_entry import UpdateFieldMetadataEntry + +class TestUpdateFieldMetadataEntry(unittest.TestCase): + """UpdateFieldMetadataEntry unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateFieldMetadataEntry: + """Test UpdateFieldMetadataEntry + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateFieldMetadataEntry` + """ + model = UpdateFieldMetadataEntry() + if include_optional: + return UpdateFieldMetadataEntry( + path = '', + metadata = { + 'key' : '' + }, + replace = True + ) + else: + return UpdateFieldMetadataEntry( + path = '', + metadata = { + 'key' : '' + }, + ) + """ + + def testUpdateFieldMetadataEntry(self): + """Test UpdateFieldMetadataEntry""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/python/lance_namespace_urllib3_client/test/test_update_field_metadata_request.py b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_request.py new file mode 100644 index 00000000..94337931 --- /dev/null +++ b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_request.py @@ -0,0 +1,72 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from lance_namespace_urllib3_client.models.update_field_metadata_request import UpdateFieldMetadataRequest + +class TestUpdateFieldMetadataRequest(unittest.TestCase): + """UpdateFieldMetadataRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateFieldMetadataRequest: + """Test UpdateFieldMetadataRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateFieldMetadataRequest` + """ + model = UpdateFieldMetadataRequest() + if include_optional: + return UpdateFieldMetadataRequest( + identity = lance_namespace_urllib3_client.models.identity.Identity( + api_key = '', + auth_token = '', ), + id = [ + '' + ], + updates = [ + lance_namespace_urllib3_client.models.update_field_metadata_entry.UpdateFieldMetadataEntry( + path = '', + metadata = { + 'key' : '' + }, + replace = True, ) + ] + ) + else: + return UpdateFieldMetadataRequest( + updates = [ + lance_namespace_urllib3_client.models.update_field_metadata_entry.UpdateFieldMetadataEntry( + path = '', + metadata = { + 'key' : '' + }, + replace = True, ) + ], + ) + """ + + def testUpdateFieldMetadataRequest(self): + """Test UpdateFieldMetadataRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/python/lance_namespace_urllib3_client/test/test_update_field_metadata_response.py b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_response.py new file mode 100644 index 00000000..acde5ec1 --- /dev/null +++ b/python/lance_namespace_urllib3_client/test/test_update_field_metadata_response.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +""" + Lance Namespace Specification + + This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from lance_namespace_urllib3_client.models.update_field_metadata_response import UpdateFieldMetadataResponse + +class TestUpdateFieldMetadataResponse(unittest.TestCase): + """UpdateFieldMetadataResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateFieldMetadataResponse: + """Test UpdateFieldMetadataResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateFieldMetadataResponse` + """ + model = UpdateFieldMetadataResponse() + if include_optional: + return UpdateFieldMetadataResponse( + version = 0, + fields = { + 'key' : { + 'key' : '' + } + } + ) + else: + return UpdateFieldMetadataResponse( + version = 0, + ) + """ + + def testUpdateFieldMetadataResponse(self): + """Test UpdateFieldMetadataResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/rust/lance-namespace-reqwest-client/README.md b/rust/lance-namespace-reqwest-client/README.md index 7d104fed..a824ee6c 100644 --- a/rust/lance-namespace-reqwest-client/README.md +++ b/rust/lance-namespace-reqwest-client/README.md @@ -89,6 +89,7 @@ Class | Method | HTTP request | Description *MetadataApi* | [**rename_table**](docs/MetadataApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table *MetadataApi* | [**restore_table**](docs/MetadataApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version *MetadataApi* | [**table_exists**](docs/MetadataApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +*MetadataApi* | [**update_field_metadata**](docs/MetadataApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *MetadataApi* | [**update_table_schema_metadata**](docs/MetadataApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *MetadataApi* | [**update_table_tag**](docs/MetadataApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version *NamespaceApi* | [**create_namespace**](docs/NamespaceApi.md#create_namespace) | **POST** /v1/namespace/{id}/create | Create a new namespace @@ -135,6 +136,7 @@ Class | Method | HTTP request | Description *TableApi* | [**rename_table**](docs/TableApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table *TableApi* | [**restore_table**](docs/TableApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version *TableApi* | [**table_exists**](docs/TableApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +*TableApi* | [**update_field_metadata**](docs/TableApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata *TableApi* | [**update_table**](docs/TableApi.md#update_table) | **POST** /v1/table/{id}/update | Update rows in a table *TableApi* | [**update_table_schema_metadata**](docs/TableApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata *TableApi* | [**update_table_tag**](docs/TableApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -275,6 +277,9 @@ Class | Method | HTTP request | Description - [TableExistsRequest](docs/TableExistsRequest.md) - [TableVersion](docs/TableVersion.md) - [TagContents](docs/TagContents.md) + - [UpdateFieldMetadataEntry](docs/UpdateFieldMetadataEntry.md) + - [UpdateFieldMetadataRequest](docs/UpdateFieldMetadataRequest.md) + - [UpdateFieldMetadataResponse](docs/UpdateFieldMetadataResponse.md) - [UpdateTableRequest](docs/UpdateTableRequest.md) - [UpdateTableResponse](docs/UpdateTableResponse.md) - [UpdateTableSchemaMetadataRequest](docs/UpdateTableSchemaMetadataRequest.md) diff --git a/rust/lance-namespace-reqwest-client/docs/MetadataApi.md b/rust/lance-namespace-reqwest-client/docs/MetadataApi.md index b1a748ae..61fea019 100644 --- a/rust/lance-namespace-reqwest-client/docs/MetadataApi.md +++ b/rust/lance-namespace-reqwest-client/docs/MetadataApi.md @@ -38,6 +38,7 @@ Method | HTTP request | Description [**rename_table**](MetadataApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table [**restore_table**](MetadataApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version [**table_exists**](MetadataApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +[**update_field_metadata**](MetadataApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata [**update_table_schema_metadata**](MetadataApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata [**update_table_tag**](MetadataApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -1138,6 +1139,38 @@ Name | Type | Description | Required | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +## update_field_metadata + +> models::UpdateFieldMetadataResponse update_field_metadata(id, update_field_metadata_request, delimiter) +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**id** | **String** | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | [required] | +**update_field_metadata_request** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md) | | [required] | +**delimiter** | Option<**String**> | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | | + +### Return type + +[**models::UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + ## update_table_schema_metadata > std::collections::HashMap update_table_schema_metadata(id, request_body, delimiter) diff --git a/rust/lance-namespace-reqwest-client/docs/TableApi.md b/rust/lance-namespace-reqwest-client/docs/TableApi.md index 80509cfb..ca417700 100644 --- a/rust/lance-namespace-reqwest-client/docs/TableApi.md +++ b/rust/lance-namespace-reqwest-client/docs/TableApi.md @@ -42,6 +42,7 @@ Method | HTTP request | Description [**rename_table**](TableApi.md#rename_table) | **POST** /v1/table/{id}/rename | Rename a table [**restore_table**](TableApi.md#restore_table) | **POST** /v1/table/{id}/restore | Restore table to a specific version [**table_exists**](TableApi.md#table_exists) | **POST** /v1/table/{id}/exists | Check if a table exists +[**update_field_metadata**](TableApi.md#update_field_metadata) | **POST** /v1/table/{id}/update_field_metadata | Update per-field metadata [**update_table**](TableApi.md#update_table) | **POST** /v1/table/{id}/update | Update rows in a table [**update_table_schema_metadata**](TableApi.md#update_table_schema_metadata) | **POST** /v1/table/{id}/schema_metadata/update | Update table schema metadata [**update_table_tag**](TableApi.md#update_table_tag) | **POST** /v1/table/{id}/tags/update | Update a tag to point to a different version @@ -1283,6 +1284,38 @@ Name | Type | Description | Required | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +## update_field_metadata + +> models::UpdateFieldMetadataResponse update_field_metadata(id, update_field_metadata_request, delimiter) +Update per-field metadata + +Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**id** | **String** | `string identifier` of an object in a namespace, following the Lance Namespace spec. When the value is equal to the delimiter, it represents the root namespace. For example, `v1/namespace/$/list` performs a `ListNamespace` on the root namespace. | [required] | +**update_field_metadata_request** | [**UpdateFieldMetadataRequest**](UpdateFieldMetadataRequest.md) | | [required] | +**delimiter** | Option<**String**> | An optional delimiter of the `string identifier`, following the Lance Namespace spec. When not specified, the `$` delimiter must be used. | | + +### Return type + +[**models::UpdateFieldMetadataResponse**](UpdateFieldMetadataResponse.md) + +### Authorization + +[OAuth2](../README.md#OAuth2), [ApiKeyAuth](../README.md#ApiKeyAuth), [BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + ## update_table > models::UpdateTableResponse update_table(id, update_table_request, delimiter) diff --git a/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataEntry.md b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataEntry.md new file mode 100644 index 00000000..dab609c1 --- /dev/null +++ b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataEntry.md @@ -0,0 +1,13 @@ +# UpdateFieldMetadataEntry + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**path** | **String** | Field (column) path whose metadata to update | +**metadata** | **std::collections::HashMap** | Metadata key-value pairs to apply to the field. A null value deletes that key. | +**replace** | Option<**bool**> | If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataRequest.md b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataRequest.md new file mode 100644 index 00000000..a0da8cde --- /dev/null +++ b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataRequest.md @@ -0,0 +1,13 @@ +# UpdateFieldMetadataRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**identity** | Option<[**models::Identity**](Identity.md)> | | [optional] +**id** | Option<**Vec**> | Table identifier path (namespace + table name) | [optional] +**updates** | [**Vec**](UpdateFieldMetadataEntry.md) | List of per-field metadata updates to apply | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataResponse.md b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataResponse.md new file mode 100644 index 00000000..5e0e8f42 --- /dev/null +++ b/rust/lance-namespace-reqwest-client/docs/UpdateFieldMetadataResponse.md @@ -0,0 +1,12 @@ +# UpdateFieldMetadataResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**version** | **i64** | The commit version associated with the operation | +**fields** | Option<[**std::collections::HashMap>**](std::collections::HashMap.md)> | Resulting metadata for each updated field, keyed by field path. | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rust/lance-namespace-reqwest-client/src/apis/metadata_api.rs b/rust/lance-namespace-reqwest-client/src/apis/metadata_api.rs index 87d6f6e3..8d46f7f8 100644 --- a/rust/lance-namespace-reqwest-client/src/apis/metadata_api.rs +++ b/rust/lance-namespace-reqwest-client/src/apis/metadata_api.rs @@ -471,6 +471,19 @@ pub enum TableExistsError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`update_field_metadata`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateFieldMetadataError { + Status400(models::ErrorResponse), + Status401(models::ErrorResponse), + Status403(models::ErrorResponse), + Status404(models::ErrorResponse), + Status503(models::ErrorResponse), + Status5XX(models::ErrorResponse), + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`update_table_schema_metadata`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -2454,6 +2467,63 @@ pub async fn table_exists(configuration: &configuration::Configuration, id: &str } } +/// Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. +pub async fn update_field_metadata(configuration: &configuration::Configuration, id: &str, update_field_metadata_request: models::UpdateFieldMetadataRequest, delimiter: Option<&str>) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_id = id; + let p_update_field_metadata_request = update_field_metadata_request; + let p_delimiter = delimiter; + + let uri_str = format!("{}/v1/table/{id}/update_field_metadata", configuration.base_path, id=crate::apis::urlencode(p_id)); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref param_value) = p_delimiter { + req_builder = req_builder.query(&[("delimiter", ¶m_value.to_string())]); + } + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.oauth_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + if let Some(ref apikey) = configuration.api_key { + let key = apikey.key.clone(); + let value = match apikey.prefix { + Some(ref prefix) => format!("{} {}", prefix, key), + None => key, + }; + req_builder = req_builder.header("x-api-key", value); + }; + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + req_builder = req_builder.json(&p_update_field_metadata_request); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UpdateFieldMetadataResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UpdateFieldMetadataResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + /// Replace the schema metadata for table `id` with the provided key-value pairs. REST NAMESPACE ONLY REST namespace uses a direct object (map of string to string) as both request and response body instead of the wrapped `UpdateTableSchemaMetadataRequest` and `UpdateTableSchemaMetadataResponse`. pub async fn update_table_schema_metadata(configuration: &configuration::Configuration, id: &str, request_body: std::collections::HashMap, delimiter: Option<&str>) -> Result, Error> { // add a prefix to parameters to efficiently prevent name collisions diff --git a/rust/lance-namespace-reqwest-client/src/apis/table_api.rs b/rust/lance-namespace-reqwest-client/src/apis/table_api.rs index 48ee2f25..3673a284 100644 --- a/rust/lance-namespace-reqwest-client/src/apis/table_api.rs +++ b/rust/lance-namespace-reqwest-client/src/apis/table_api.rs @@ -518,6 +518,19 @@ pub enum TableExistsError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`update_field_metadata`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateFieldMetadataError { + Status400(models::ErrorResponse), + Status401(models::ErrorResponse), + Status403(models::ErrorResponse), + Status404(models::ErrorResponse), + Status503(models::ErrorResponse), + Status5XX(models::ErrorResponse), + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`update_table`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -2791,6 +2804,63 @@ pub async fn table_exists(configuration: &configuration::Configuration, id: &str } } +/// Update the Arrow field (column) metadata for table `id`. Each entry targets a field by `path` and merges the provided key-value pairs into that field's existing metadata, or replaces it when `replace` is true. A null metadata value deletes that key. +pub async fn update_field_metadata(configuration: &configuration::Configuration, id: &str, update_field_metadata_request: models::UpdateFieldMetadataRequest, delimiter: Option<&str>) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_id = id; + let p_update_field_metadata_request = update_field_metadata_request; + let p_delimiter = delimiter; + + let uri_str = format!("{}/v1/table/{id}/update_field_metadata", configuration.base_path, id=crate::apis::urlencode(p_id)); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref param_value) = p_delimiter { + req_builder = req_builder.query(&[("delimiter", ¶m_value.to_string())]); + } + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.oauth_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + if let Some(ref apikey) = configuration.api_key { + let key = apikey.key.clone(); + let value = match apikey.prefix { + Some(ref prefix) => format!("{} {}", prefix, key), + None => key, + }; + req_builder = req_builder.header("x-api-key", value); + }; + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + req_builder = req_builder.json(&p_update_field_metadata_request); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UpdateFieldMetadataResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UpdateFieldMetadataResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + /// Update existing rows in table `id`. pub async fn update_table(configuration: &configuration::Configuration, id: &str, update_table_request: models::UpdateTableRequest, delimiter: Option<&str>) -> Result> { // add a prefix to parameters to efficiently prevent name collisions diff --git a/rust/lance-namespace-reqwest-client/src/models/mod.rs b/rust/lance-namespace-reqwest-client/src/models/mod.rs index 2d98c613..6a3aff2d 100644 --- a/rust/lance-namespace-reqwest-client/src/models/mod.rs +++ b/rust/lance-namespace-reqwest-client/src/models/mod.rs @@ -248,6 +248,12 @@ pub mod table_version; pub use self::table_version::TableVersion; pub mod tag_contents; pub use self::tag_contents::TagContents; +pub mod update_field_metadata_entry; +pub use self::update_field_metadata_entry::UpdateFieldMetadataEntry; +pub mod update_field_metadata_request; +pub use self::update_field_metadata_request::UpdateFieldMetadataRequest; +pub mod update_field_metadata_response; +pub use self::update_field_metadata_response::UpdateFieldMetadataResponse; pub mod update_table_request; pub use self::update_table_request::UpdateTableRequest; pub mod update_table_response; diff --git a/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_entry.rs b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_entry.rs new file mode 100644 index 00000000..d4c408f7 --- /dev/null +++ b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_entry.rs @@ -0,0 +1,36 @@ +/* + * Lance Namespace Specification + * + * This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct UpdateFieldMetadataEntry { + /// Field (column) path whose metadata to update + #[serde(rename = "path")] + pub path: String, + /// Metadata key-value pairs to apply to the field. A null value deletes that key. + #[serde(rename = "metadata")] + pub metadata: std::collections::HashMap, + /// If true, replace the field's existing metadata entirely; otherwise merge into it (optional, defaults to false). + #[serde(rename = "replace", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub replace: Option>, +} + +impl UpdateFieldMetadataEntry { + pub fn new(path: String, metadata: std::collections::HashMap) -> UpdateFieldMetadataEntry { + UpdateFieldMetadataEntry { + path, + metadata, + replace: None, + } + } +} + diff --git a/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_request.rs b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_request.rs new file mode 100644 index 00000000..59f8929e --- /dev/null +++ b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_request.rs @@ -0,0 +1,35 @@ +/* + * Lance Namespace Specification + * + * This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct UpdateFieldMetadataRequest { + #[serde(rename = "identity", skip_serializing_if = "Option::is_none")] + pub identity: Option>, + /// Table identifier path (namespace + table name) + #[serde(rename = "id", skip_serializing_if = "Option::is_none")] + pub id: Option>, + /// List of per-field metadata updates to apply + #[serde(rename = "updates")] + pub updates: Vec, +} + +impl UpdateFieldMetadataRequest { + pub fn new(updates: Vec) -> UpdateFieldMetadataRequest { + UpdateFieldMetadataRequest { + identity: None, + id: None, + updates, + } + } +} + diff --git a/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_response.rs b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_response.rs new file mode 100644 index 00000000..da3cc3e6 --- /dev/null +++ b/rust/lance-namespace-reqwest-client/src/models/update_field_metadata_response.rs @@ -0,0 +1,32 @@ +/* + * Lance Namespace Specification + * + * This OpenAPI specification is a part of the Lance namespace specification. It contains 2 parts: The `components/schemas`, `components/responses`, `components/examples`, `tags` sections define the request and response shape for each operation in a Lance Namespace across all implementations. See https://lance.org/format/namespace/operations for more details. The `servers`, `security`, `paths`, `components/parameters` sections are for the Lance REST Namespace implementation, which defines a complete REST server that can work with Lance datasets. See https://lance.org/format/namespace/rest for more details. + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct UpdateFieldMetadataResponse { + /// The commit version associated with the operation + #[serde(rename = "version")] + pub version: i64, + /// Resulting metadata for each updated field, keyed by field path. + #[serde(rename = "fields", skip_serializing_if = "Option::is_none")] + pub fields: Option>>, +} + +impl UpdateFieldMetadataResponse { + pub fn new(version: i64) -> UpdateFieldMetadataResponse { + UpdateFieldMetadataResponse { + version, + fields: None, + } + } +} +