@@ -30,6 +30,8 @@ type QueryClient struct {
3030 DataDir string
3131 DB * sql.DB
3232 DefaultTimeRange int64 // 10 minutes in nanoseconds
33+
34+ layers map [string ]querierLayerDesc
3335}
3436
3537// NewQueryClient creates a new QueryClient
@@ -48,6 +50,16 @@ func (q *QueryClient) Initialize() error {
4850 return fmt .Errorf ("failed to initialize DuckDB: %v" , err )
4951 }
5052 q .DB = db
53+ q .layers = map [string ]querierLayerDesc {}
54+
55+ for _ , l := range config .Config .Gigapi .Layers {
56+ desc , err := getQuerierLayerDesc (l )
57+ if err != nil {
58+ return fmt .Errorf ("failed to initialize layer %s: %v" , l .Name , err )
59+ }
60+ q .layers [l .Name ] = desc
61+ }
62+
5163 return nil
5264}
5365
@@ -422,7 +434,7 @@ func getTableIndex(table *shared.Table) (metadata.TableIndex, error) {
422434
423435// Find relevant parquet files based on time range
424436func (q * QueryClient ) FindRelevantFiles (ctx context.Context , dbName , measurement string ,
425- timeRange TimeRange ) ([]string , error ) {
437+ timeRange TimeRange ) ([]* metadata. IndexEntry , error ) {
426438 // If no time range specified, get all files
427439 var relevantFiles []string
428440 // log.Printf("Getting relevant files for %s.%s within time range %v to %v", dbName, measurement,
@@ -451,19 +463,13 @@ func (q *QueryClient) FindRelevantFiles(ctx context.Context, dbName, measurement
451463 }
452464
453465 ies , err := idx .GetQuerier ().Query (opts )
454- layersMap := make (map [string ]string )
455- for _ , l := range config .Config .Gigapi .Layers {
456- layersMap [l .Name ] = strings .TrimPrefix (l .URL , "file://" )
457- }
458- for _ , ie := range ies {
459- relevantFiles = append (relevantFiles , filepath .Join (layersMap [ie .Layer ], dbName , measurement , "data" , ie .Path ))
466+ if err != nil {
467+ return nil , err
460468 }
461-
462- if len (relevantFiles ) == 0 {
469+ if len (ies ) == 0 {
463470 log .Printf ("No files found in any directory for %s.%s" , dbName , measurement )
464471 }
465-
466- return relevantFiles , nil
472+ return ies , err
467473}
468474
469475// Find all files for a measurement
@@ -660,6 +666,49 @@ func (c *QueryClient) getDBIndex(ctx context.Context) (metadata.DBIndex, error)
660666 return nil , fmt .Errorf ("unsupported metadata type: %s" , config .Config .Gigapi .Metadata .Type )
661667}
662668
669+ func (c * QueryClient ) buildFilesList (db string , table string , files []* metadata.IndexEntry ) ([]string , error ) {
670+ var fileList []string
671+ s3Layers := map [string ]bool {}
672+
673+ for _ , f := range files {
674+ l , ok := c .layers [f .Layer ]
675+ if ! ok {
676+ return nil , fmt .Errorf ("layer %s not found" , f .Layer )
677+ }
678+ switch l .layer .Type {
679+ case "fs" :
680+ fileList = append (fileList , filepath .Join (l .path , db , table , "data" , f .Path ))
681+ case "s3" :
682+ _path := l .path
683+ if _path != "" {
684+ _path += "/"
685+ }
686+ path := fmt .Sprintf ("s3://%s%s/%s/%s" , _path , db , table , f .Path )
687+ fileList = append (fileList , path )
688+ s3Layers [l .layer .Name ] = true
689+ }
690+ }
691+ for lName , _ := range s3Layers {
692+ sanitizedLName := lName
693+ sanitizedLName = regexp .MustCompile ("[^a-zA-Z0-9_]" ).ReplaceAllString (sanitizedLName , "_" )
694+ secretName := fmt .Sprintf ("secret_%s" , sanitizedLName )
695+ l := c .layers [lName ]
696+ _ , err := c .DB .Exec (fmt .Sprintf (`CREATE OR REPLACE SECRET %s (
697+ TYPE s3,
698+ USE_SSL %t,
699+ KEY_ID %s,
700+ SECRET %s,
701+ ENDPOINT '%s',
702+ SCOPE 's3://%s',
703+ URL_STYLE '%s'
704+ );` , secretName , l .secure , l .key , l .secret , l .hostname , l .bucket , l .urlStyle ))
705+ if err != nil {
706+ return nil , fmt .Errorf ("failed to create secret: %v" , err )
707+ }
708+ }
709+ return fileList , nil
710+ }
711+
663712// Query executes a query against the database
664713func (c * QueryClient ) Query (ctx context.Context , query , dbName string ) ([]map [string ]interface {}, error ) {
665714 // Ensure we have a context
@@ -766,9 +815,13 @@ func (c *QueryClient) Query(ctx context.Context, query, dbName string) ([]map[st
766815 }
767816
768817 // Find relevant files
769- files , err := c .FindRelevantFiles (ctx , parsed .DbName , parsed .Measurement , parsed .TimeRange )
770- if err != nil || len (files ) == 0 {
771- return nil , fmt .Errorf ("no relevant files found for query" )
818+ entries , err := c .FindRelevantFiles (ctx , parsed .DbName , parsed .Measurement , parsed .TimeRange )
819+ if err != nil {
820+ return nil , err
821+ }
822+ files , err := c .buildFilesList (parsed .DbName , parsed .Measurement , entries )
823+ if err != nil {
824+ return nil , err
772825 }
773826
774827 start := time .Now ()
0 commit comments