diff --git a/packages/web-console/src/components/CreateTableDialog/index.tsx b/packages/web-console/src/components/CreateTableDialog/index.tsx index 5f484ba98..9de43d229 100644 --- a/packages/web-console/src/components/CreateTableDialog/index.tsx +++ b/packages/web-console/src/components/CreateTableDialog/index.tsx @@ -26,12 +26,14 @@ export const CreateTableDialog = () => { const { appendQuery } = useEditor() const handleAddTableSchema = (values: SchemaFormValues) => { - const { name, partitionBy, timestamp, schemaColumns, walEnabled } = values + const { name, partitionBy, timestamp, ttlValue, ttlUnit, schemaColumns, walEnabled } = values const tableSchemaQuery = formatTableSchemaQuery({ name, partitionBy, timestamp, walEnabled: walEnabled === "true", + ttlValue, + ttlUnit, schemaColumns: schemaColumns.map((column) => ({ column: column.name, type: column.type, @@ -75,6 +77,8 @@ export const CreateTableDialog = () => { walEnabled={false} name="" partitionBy="NONE" + ttlValue={0} + ttlUnit="HOURS" schema={[]} tables={tables} timestamp="" diff --git a/packages/web-console/src/components/TableSchemaDialog/dialog.tsx b/packages/web-console/src/components/TableSchemaDialog/dialog.tsx index 084a67b76..359c39e2c 100644 --- a/packages/web-console/src/components/TableSchemaDialog/dialog.tsx +++ b/packages/web-console/src/components/TableSchemaDialog/dialog.tsx @@ -55,6 +55,8 @@ type Props = { name: string schema: SchemaColumn[] partitionBy: string + ttlValue: number + ttlUnit: string timestamp: string trigger?: React.ReactNode tables?: QuestDB.Table[] @@ -67,6 +69,8 @@ export const Dialog = ({ schema, partitionBy, timestamp, + ttlValue, + ttlUnit, open, isEditLocked, hasWalSetting, @@ -82,6 +86,8 @@ export const Dialog = ({ schemaColumns: schema, partitionBy, timestamp, + ttlValue, + ttlUnit, walEnabled: hasWalSetting ? "false" : undefined, } @@ -97,6 +103,8 @@ export const Dialog = ({ schemaColumns: schema, partitionBy: partitionBy, timestamp: timestamp, + ttlValue: ttlValue, + ttlUnit: ttlUnit, walEnabled: hasWalSetting && walEnabled !== undefined ? walEnabled.toString() @@ -136,6 +144,8 @@ export const Dialog = ({ "string.timestampRequired": "Designated timestamp is required when partitioning is set to anything other than NONE", }), + ttlValue: Joi.number(), + ttlUnit: Joi.string(), walEnabled: Joi.any() .allow(...["true", "false"]) .empty(), diff --git a/packages/web-console/src/components/TableSchemaDialog/types.ts b/packages/web-console/src/components/TableSchemaDialog/types.ts index 6feefd931..361d4ef1e 100644 --- a/packages/web-console/src/components/TableSchemaDialog/types.ts +++ b/packages/web-console/src/components/TableSchemaDialog/types.ts @@ -12,5 +12,7 @@ export type SchemaFormValues = { schemaColumns: SchemaColumn[] partitionBy: string timestamp: string + ttlValue: number + ttlUnit: string walEnabled?: string } diff --git a/packages/web-console/src/scenes/Import/ImportCSVFiles/files-to-upload.tsx b/packages/web-console/src/scenes/Import/ImportCSVFiles/files-to-upload.tsx index 208257c9f..759f81fbc 100644 --- a/packages/web-console/src/scenes/Import/ImportCSVFiles/files-to-upload.tsx +++ b/packages/web-console/src/scenes/Import/ImportCSVFiles/files-to-upload.tsx @@ -279,6 +279,8 @@ export const FilesToUpload = ({ name={name} schema={data.schema} partitionBy={data.partitionBy} + ttlValue={data.ttlValue} + ttlUnit={data.ttlUnit} timestamp={data.timestamp} isEditLocked={ data.exists && data.table_name === data.fileObject.name diff --git a/packages/web-console/src/scenes/Import/ImportCSVFiles/index.tsx b/packages/web-console/src/scenes/Import/ImportCSVFiles/index.tsx index 0a349673e..58053cfef 100644 --- a/packages/web-console/src/scenes/Import/ImportCSVFiles/index.tsx +++ b/packages/web-console/src/scenes/Import/ImportCSVFiles/index.tsx @@ -94,6 +94,22 @@ export const ImportCSVFiles = ({ onViewData, onUpload }: Props) => { })() : "NONE" + const ttlValue = + result.status === FileCheckStatus.EXISTS && tables + ? await (async () => { + const table = tables.find((t) => t.table_name === file.name) + return table?.ttlValue ?? 0 + })() + : 0 + + const ttlUnit = + result.status === FileCheckStatus.EXISTS && tables + ? await (async () => { + const table = tables.find((t) => t.table_name === file.name) + return table?.ttlUnit ?? "HOURS" + })() + : "HOURS" + const timestamp = result.status === FileCheckStatus.EXISTS && tables ? await (async () => { @@ -110,6 +126,8 @@ export const ImportCSVFiles = ({ onViewData, onUpload }: Props) => { exists: result.status === FileCheckStatus.EXISTS, schema, partitionBy, + ttlValue, + ttlUnit, timestamp, settings: { forceHeader: false, diff --git a/packages/web-console/src/scenes/Import/ImportCSVFiles/types.ts b/packages/web-console/src/scenes/Import/ImportCSVFiles/types.ts index c21353f0a..5541a9b54 100644 --- a/packages/web-console/src/scenes/Import/ImportCSVFiles/types.ts +++ b/packages/web-console/src/scenes/Import/ImportCSVFiles/types.ts @@ -10,6 +10,8 @@ export type ProcessedFile = { schema: SchemaColumn[] partitionBy: string timestamp: string + ttlValue: number + ttlUnit: string isUploading: boolean uploaded: boolean uploadResult?: UploadResult diff --git a/packages/web-console/src/scenes/Schema/Table/index.tsx b/packages/web-console/src/scenes/Schema/Table/index.tsx index 2409025a0..ca02d4f86 100644 --- a/packages/web-console/src/scenes/Schema/Table/index.tsx +++ b/packages/web-console/src/scenes/Schema/Table/index.tsx @@ -118,9 +118,11 @@ const columnRender = const Table = ({ description, isScrolling, - designatedTimestamp, table_name, + designatedTimestamp, partitionBy, + ttlValue, + ttlUnit, expanded = false, walEnabled, walTableData, diff --git a/packages/web-console/src/scenes/Schema/formatTableSchemaQueryResult.ts b/packages/web-console/src/scenes/Schema/formatTableSchemaQueryResult.ts index 066ff4725..27154820f 100644 --- a/packages/web-console/src/scenes/Schema/formatTableSchemaQueryResult.ts +++ b/packages/web-console/src/scenes/Schema/formatTableSchemaQueryResult.ts @@ -30,15 +30,19 @@ import * as QuestDB from "../../utils/questdb" export const formatTableSchemaQueryResult = ( name: string, partitionBy: string, + ttlValue: number, + ttlUnit: string, columns: QuestDB.Column[], walEnabled: boolean, - dedup: boolean, + dedup: boolean ): string => { const findTimestampColumn = columns.find((c) => c.designated) return formatTableSchemaQuery({ name, - partitionBy, timestamp: findTimestampColumn ? findTimestampColumn.column : "", + partitionBy, + ttlValue, + ttlUnit, walEnabled, dedup, schemaColumns: columns.map((c) => { diff --git a/packages/web-console/src/scenes/Schema/index.tsx b/packages/web-console/src/scenes/Schema/index.tsx index ce72ee77a..23e5c3fb6 100644 --- a/packages/web-console/src/scenes/Schema/index.tsx +++ b/packages/web-console/src/scenes/Schema/index.tsx @@ -235,9 +235,11 @@ const Schema = ({ return formatTableSchemaQueryResult( tableData.table_name, tableData.partitionBy, + tableData.ttlValue, + tableData.ttlUnit, columnResponse.data, tableData.walEnabled, - tableData.dedup, + tableData.dedup ) } } catch (error) { @@ -359,6 +361,8 @@ const Schema = ({ table_name={table.table_name} onChange={handleChange} partitionBy={table.partitionBy} + ttlValue={table.ttlValue} + ttlUnit={table.ttlUnit} walEnabled={table.walEnabled} walTableData={walTables?.find( (wt) => wt.name === table.table_name, diff --git a/packages/web-console/src/utils/formatTableSchemaQuery.ts b/packages/web-console/src/utils/formatTableSchemaQuery.ts index 6320ac39f..c192dc58f 100644 --- a/packages/web-console/src/utils/formatTableSchemaQuery.ts +++ b/packages/web-console/src/utils/formatTableSchemaQuery.ts @@ -18,6 +18,8 @@ type Props = { timestamp: string dedup: boolean walEnabled: boolean + ttlValue: number + ttlUnit: string schemaColumns: Column[] } @@ -27,6 +29,8 @@ export const formatTableSchemaQuery = ({ timestamp, walEnabled, dedup, + ttlValue, + ttlUnit, schemaColumns, }: Props) => { const hasValidTimestamp = @@ -75,7 +79,11 @@ export const formatTableSchemaQuery = ({ } if (partitionBy !== "NONE") { - query += ` PARTITION BY ${partitionBy} ${walEnabled ? "WAL" : "BYPASS WAL"}` + query += ` PARTITION BY ${partitionBy}` + if ((ttlValue ?? 0) !== 0) { + query += ` TTL ${ttlValue} ${ttlUnit}` + } + query += ` ${walEnabled ? "WAL" : "BYPASS WAL"}` } // For deduplication keys to work, WAL has to be enabled and a designated timestamp has to be set. diff --git a/packages/web-console/src/utils/questdb.ts b/packages/web-console/src/utils/questdb.ts index 7cafb9864..457ccc5d1 100644 --- a/packages/web-console/src/utils/questdb.ts +++ b/packages/web-console/src/utils/questdb.ts @@ -149,6 +149,8 @@ export type Table = { designatedTimestamp: string walEnabled: boolean dedup: boolean + ttlValue: number + ttlUnit: string } export type Partition = {