Files
windmill/backend/parsers/windmill-parser/src/asset_parser.rs
e6f1211d31 feat: Ducklake native support (#6268)
* upgrade duckdb

* basic ducklake works

* ducklake works with custom db catalogs

* fix: pwsh skip already installed modules outside of cache (#6037)

* improve query performance of user stats

* separate ducklake_catalog db

* ducklake settings

* DucklakeSettings frontend

* Ducklake ws settings saved in backend

* fetch ducklake catalog resource

* Ducklake works with configured s3 storage

* Ducklake as asset

* ducklake asset icon

* Fix duckdb array and object args not working properly (#6254)

* Fix bug with comments in duckdb

* Avoid multiple queries when doing ATTACH ducklake

* trunc sig no longer needed now that comments are trimmed

* cache DuckdbConnectionSettingsResponse

* duplicated code

* transform_attach_ducklake contributes to duckdb_connection_settings_cache

* eliminate the need for used_storages

* nit

* cleaner management of the bigquery credentials file

* DBManagerDrawer refactor to prepare for Ducklake

* get ducklake schema

* implement delete for ducklake

* load column metadata for ducklake

* Select query works for ducklake, basic db explorer works !

* duckdb count query

* Support all db ops for ducklake

* clean migrations

* SQL repl for Ducklake

* fix broken database studio

* nit

* assert function

* Ducklake in Editor Bar

* default ducklake syntax + allow extra args

* DucklakeCatalogWizard UI

* nit + remove extra $

* modal when databases do not exist

* cannot be windmill

* Ducklake works safely with instance database

* Avoid sending instance db credentials on network

* resource leak security

* remove fetch_attach_db_conn_str

* prevent instance pg password leak

* hide asset usage count when not available

* case unsensitivity duckdb

* warnings

* disable instance catalog

* use shorthand syntax when inserting with EditorBar

* Instance ducklake catalog is now safe to use

* use safer argon2 pwd

* update package json parsers

* update package json

* better msgs

* tooltips

* disable explore button until saved

* nit

* fix warnings

* better ducklake_user password management

* nit

* Sanitize passwords from errors in ducklake

* DisplayResult broken in job result

* remove superadmin requirement to check databases_exist

* duckdb_connection_settings_v2_inner

* Ducklake works on agent worker (finally)

* ci

* #[allow(dead_code)]

* fix openapi missing response

* Separate +Database button for DuckDB in EditorBar

* Fix dropdown in ducklake settings

* Attempt to fix migration race condition in CI

* update sqlx failing for some offline queries

* avoid temp password for ducklake_user

* nits

* ducklake settings nits

* update duckdb default script

* fix sql repl resetting text on refresh

* avoid pgcrypto extension

---------

Co-authored-by: HugoCasa <hugo@casademont.ch>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2025-08-06 13:55:36 +00:00

66 lines
1.9 KiB
Rust

use serde::Serialize;
#[derive(Serialize, PartialEq, Clone, Copy)]
#[serde(rename_all(serialize = "lowercase"))]
pub enum AssetUsageAccessType {
R,
W,
RW,
}
use AssetUsageAccessType::*;
#[derive(Serialize, PartialEq, Clone, Copy)]
#[serde(rename_all(serialize = "lowercase"))]
pub enum AssetKind {
S3Object,
Resource,
Ducklake,
}
#[derive(Serialize)]
pub struct ParseAssetsResult<S: AsRef<str>> {
pub kind: AssetKind,
pub path: S,
#[serde(skip_serializing_if = "Option::is_none")]
pub access_type: Option<AssetUsageAccessType>, // None in case of ambiguity
}
pub fn merge_assets<S: AsRef<str>>(assets: Vec<ParseAssetsResult<S>>) -> Vec<ParseAssetsResult<S>> {
let mut arr: Vec<ParseAssetsResult<S>> = vec![];
for asset in assets {
// Remove duplicates
if let Some(existing) = arr
.iter_mut()
.find(|x| x.path.as_ref() == asset.path.as_ref() && x.kind == asset.kind)
{
// merge access types
existing.access_type = match (asset.access_type, existing.access_type) {
(None, _) | (_, None) => None,
(Some(R), Some(W)) | (Some(W), Some(R)) => Some(RW),
(Some(RW), _) | (_, Some(RW)) => Some(RW),
(Some(R), Some(R)) => Some(R),
(Some(W), Some(W)) => Some(W),
};
} else {
arr.push(asset);
}
}
arr.sort_by(|a, b| a.path.as_ref().cmp(b.path.as_ref()));
arr
}
pub fn parse_asset_syntax(s: &str) -> Option<(AssetKind, &str)> {
if s.starts_with("s3://") {
Some((AssetKind::S3Object, &s[5..]))
} else if s.starts_with("res://") {
Some((AssetKind::Resource, &s[6..]))
} else if s.starts_with("$res:") {
Some((AssetKind::Resource, &s[5..]))
} else if s.starts_with("ducklake://") {
Some((AssetKind::Ducklake, &s[11..]))
} else {
None
}
}