@@ -3,6 +3,7 @@ package config
33import (
44 "errors"
55 "fmt"
6+ "slices"
67)
78
89type LakehouseFormat string
@@ -36,20 +37,18 @@ type CatalogAuth struct {
3637 Password string `yaml:"password,omitempty" json:"password,omitempty" mapstructure:"password"`
3738}
3839
39- func (auth * CatalogAuth ) IsAWS () bool {
40- if auth == nil {
41- return false
42- }
40+ func (auth CatalogAuth ) IsAWS () bool {
4341 return auth .AccessKey != "" && auth .SecretKey != ""
4442}
4543
46- func (auth * CatalogAuth ) IsPostgres () bool {
47- if auth == nil {
48- return false
49- }
44+ func (auth CatalogAuth ) IsPostgres () bool {
5045 return auth .Username != "" && auth .Password != ""
5146}
5247
48+ func (auth CatalogAuth ) IsZero () bool {
49+ return auth == (CatalogAuth {})
50+ }
51+
5352type CatalogConfig struct {
5453 Type CatalogType `yaml:"type" json:"type" mapstructure:"type"`
5554
@@ -66,7 +65,18 @@ type CatalogConfig struct {
6665 Database string `yaml:"database,omitempty" json:"database,omitempty" mapstructure:"database"`
6766
6867 // Authentication
69- Auth * CatalogAuth `yaml:"auth,omitempty" json:"auth,omitempty" mapstructure:"auth"`
68+ Auth CatalogAuth `yaml:"auth,omitempty" json:"auth,omitempty" mapstructure:"auth"`
69+ }
70+
71+ func (c CatalogConfig ) IsZero () bool {
72+ return c .Type == "" &&
73+ c .CatalogID == "" &&
74+ c .Region == "" &&
75+ c .Path == "" &&
76+ c .Host == "" &&
77+ c .Port == 0 &&
78+ c .Database == "" &&
79+ c .Auth .IsZero ()
7080}
7181
7282type StorageType string
@@ -76,72 +86,83 @@ const (
7686 // Future: StorageTypeGCS, StorageTypeLocal.
7787)
7888
89+ var (
90+ supportedCatalogTypes = []CatalogType {
91+ CatalogTypeGlue ,
92+ CatalogTypePostgres ,
93+ CatalogTypeDuckDB ,
94+ CatalogTypeSQLite ,
95+ }
96+ supportedStorageTypes = []StorageType {
97+ StorageTypeS3 ,
98+ }
99+ )
100+
79101type StorageAuth struct {
80102 // AWS S3 credentials
81103 AccessKey string `yaml:"access_key,omitempty" json:"access_key,omitempty" mapstructure:"access_key"`
82104 SecretKey string `yaml:"secret_key,omitempty" json:"secret_key,omitempty" mapstructure:"secret_key"`
83105 SessionToken string `yaml:"session_token,omitempty" json:"session_token,omitempty" mapstructure:"session_token"`
84106}
85107
86- func (a * StorageAuth ) IsS3 () bool {
87- if a == nil {
88- return false
89- }
108+ func (a StorageAuth ) IsS3 () bool {
90109 return a .AccessKey != "" && a .SecretKey != ""
91110}
92111
112+ func (a StorageAuth ) IsZero () bool {
113+ return a == (StorageAuth {})
114+ }
115+
93116type StorageConfig struct {
94- Type StorageType `yaml:"type" json:"type" mapstructure:"type"`
95- Path string `yaml:"path,omitempty" json:"path,omitempty" mapstructure:"path"`
96- Region string `yaml:"region,omitempty" json:"region,omitempty" mapstructure:"region"`
97- Auth * StorageAuth `yaml:"auth,omitempty" json:"auth,omitempty" mapstructure:"auth"`
117+ Type StorageType `yaml:"type" json:"type" mapstructure:"type"`
118+ Path string `yaml:"path,omitempty" json:"path,omitempty" mapstructure:"path"`
119+ Region string `yaml:"region,omitempty" json:"region,omitempty" mapstructure:"region"`
120+ Auth StorageAuth `yaml:"auth,omitempty" json:"auth,omitempty" mapstructure:"auth"`
121+ }
122+
123+ func (s StorageConfig ) IsZero () bool {
124+ return s .Type == "" &&
125+ s .Path == "" &&
126+ s .Region == "" &&
127+ s .Auth .IsZero ()
98128}
99129
100130type LakehouseConfig struct {
101131 Format LakehouseFormat `yaml:"format" json:"format" mapstructure:"format"`
102- Catalog * CatalogConfig `yaml:"catalog,omitempty" json:"catalog,omitempty" mapstructure:"catalog"`
103- Storage * StorageConfig `yaml:"storage,omitempty" json:"storage,omitempty" mapstructure:"storage"`
132+ Catalog CatalogConfig `yaml:"catalog,omitempty" json:"catalog,omitempty" mapstructure:"catalog"`
133+ Storage StorageConfig `yaml:"storage,omitempty" json:"storage,omitempty" mapstructure:"storage"`
134+ }
135+
136+ func (lh * LakehouseConfig ) IsZero () bool {
137+ if lh == nil {
138+ return true
139+ }
140+
141+ return lh .Format == "" && lh .Catalog .IsZero () && lh .Storage .IsZero ()
104142}
105143
106144// Validate performs basic structural validation of the LakehouseConfig (engine-agnostic).
107145func (lh * LakehouseConfig ) Validate () error {
146+ if lh == nil {
147+ return nil
148+ }
149+
108150 if lh .Format == "" {
109151 return errors .New ("lakehouse format is required" )
110152 }
111153
112- switch lh .Format {
113- case LakehouseFormatIceberg :
114- // valid format
115- case LakehouseFormatDuckLake :
116- // valid format
117- default :
154+ if ! slices .Contains ([]LakehouseFormat {LakehouseFormatIceberg , LakehouseFormatDuckLake }, lh .Format ) {
118155 return fmt .Errorf ("unsupported lakehouse format: %s (supported: iceberg, ducklake)" , lh .Format )
119156 }
120157
121158 // Validate catalog type if specified
122- if lh .Catalog != nil && lh .Catalog .Type != "" {
123- switch lh .Catalog .Type {
124- case CatalogTypeGlue :
125- // valid catalog type
126- case CatalogTypePostgres :
127- // valid catalog type
128- case CatalogTypeDuckDB :
129- // valid catalog type
130- case CatalogTypeSQLite :
131- // valid catalog type
132- default :
133- return fmt .Errorf ("unsupported catalog type: %s (supported: glue, postgres, duckdb, sqlite)" , lh .Catalog .Type )
134- }
159+ if lh .Catalog .Type == "" || ! slices .Contains (supportedCatalogTypes , lh .Catalog .Type ) {
160+ return errors .New ("empty or unsupported catalog type: (supported: glue, postgres, duckdb, sqlite)" )
135161 }
136162
137163 // Validate storage type if specified
138- if lh .Storage != nil && lh .Storage .Type != "" {
139- switch lh .Storage .Type {
140- case StorageTypeS3 :
141- // valid storage type
142- default :
143- return fmt .Errorf ("unsupported storage type: %s (supported: s3)" , lh .Storage .Type )
144- }
164+ if lh .Storage .Type == "" || ! slices .Contains (supportedStorageTypes , lh .Storage .Type ) {
165+ return errors .New ("empty or unsupported storage type: (supported: s3)" )
145166 }
146167
147168 return nil
0 commit comments