@@ -13,17 +13,46 @@ import type { DatetimeFilter } from "../store/datetime";
1313import type { StacItemCollection } from "../types/stac" ;
1414
1515export const SUPPORTED_GEOMETRY_TYPES = [ "point" , "polygon" ] as const ;
16+
17+ export async function executeDuckdbQuery ( {
18+ connection,
19+ select,
20+ href,
21+ where,
22+ hivePartitioning,
23+ } : {
24+ connection : AsyncDuckDBConnection ;
25+ select : string ;
26+ href : string ;
27+ where ?: string ;
28+ hivePartitioning : boolean ;
29+ } ) {
30+ let query = `SELECT ${ select } FROM read_parquet('${ href } ', hive_partitioning = ${ hivePartitioning } )` ;
31+ if ( where ) {
32+ query += ` WHERE ${ where } ` ;
33+ }
34+ console . log ( query ) ;
35+
36+ return await connection . query ( query ) ;
37+ }
1638export type SupportedGeometryType = ( typeof SUPPORTED_GEOMETRY_TYPES ) [ number ] ;
1739
1840export async function fetchStacGeoparquet ( {
1941 href,
2042 connection,
43+ hivePartitioning,
2144} : {
2245 href : string ;
2346 connection : AsyncDuckDBConnection ;
47+ hivePartitioning : boolean ;
2448} ) : Promise < StacItemCollection > {
25- const query = `SELECT COUNT(*) as count, MIN(bbox.xmin) as xmin, MIN(bbox.ymin) as ymin, MAX(bbox.xmax) as xmax, MAX(bbox.ymax) as ymax FROM read_parquet('${ href } ')` ;
26- const result = await connection . query ( query ) ;
49+ const result = await executeDuckdbQuery ( {
50+ connection,
51+ href,
52+ hivePartitioning,
53+ select :
54+ "COUNT(*) as count, MIN(bbox.xmin) as xmin, MIN(bbox.ymin) as ymin, MAX(bbox.xmax) as xmax, MAX(bbox.ymax) as ymax" ,
55+ } ) ;
2756 const row = result . toArray ( ) . map ( ( row ) => row . toJSON ( ) ) [ 0 ] ;
2857 return {
2958 type : "FeatureCollection" ,
@@ -43,15 +72,25 @@ export async function fetchStacGeoparquet({
4372export async function fetchStacGeoparquetDatetimeBounds ( {
4473 href,
4574 connection,
75+ hivePartitioning,
4676} : {
4777 href : string ;
4878 connection : AsyncDuckDBConnection ;
79+ hivePartitioning : boolean ;
4980} ) : Promise < { start : Date ; end : Date } | null > {
5081 const { startDatetimeColumnName, endDatetimeColumnName } =
51- await fetchStacGeoparquetDatetimeColumns ( href , connection ) ;
82+ await fetchStacGeoparquetDatetimeColumns (
83+ href ,
84+ connection ,
85+ hivePartitioning
86+ ) ;
5287 if ( ! startDatetimeColumnName || ! endDatetimeColumnName ) return null ;
53- const query = `SELECT MIN(${ startDatetimeColumnName } ) as start, MAX(${ endDatetimeColumnName } ) as end FROM read_parquet('${ href } ')` ;
54- const result = await connection . query ( query ) ;
88+ const result = await executeDuckdbQuery ( {
89+ connection,
90+ href,
91+ hivePartitioning,
92+ select : `MIN(${ startDatetimeColumnName } ) as start, MAX(${ endDatetimeColumnName } ) as end` ,
93+ } ) ;
5594 const row = result . toArray ( ) . map ( ( row ) => row . toJSON ( ) ) [ 0 ] ;
5695 return {
5796 start : new Date ( row . start ) ,
@@ -63,20 +102,33 @@ export async function fetchStacGeoparquetTable({
63102 href,
64103 connection,
65104 datetimeFilter,
105+ hivePartitioning,
66106} : {
67107 href : string ;
68108 connection : AsyncDuckDBConnection ;
69109 datetimeFilter : DatetimeFilter | null ;
110+ hivePartitioning : boolean ;
70111} ) {
71- let query = `SELECT ST_AsWKB(geometry) AS geometry, ST_GeometryType(geometry) AS geometry_type, id FROM read_parquet(' ${ href } ')` ;
112+ let where : string | undefined ;
72113 if ( datetimeFilter ) {
73114 const { startDatetimeColumnName, endDatetimeColumnName } =
74- await fetchStacGeoparquetDatetimeColumns ( href , connection ) ;
115+ await fetchStacGeoparquetDatetimeColumns (
116+ href ,
117+ connection ,
118+ hivePartitioning
119+ ) ;
75120 if ( ! startDatetimeColumnName || ! endDatetimeColumnName ) return null ;
76121 const { start, end } = datetimeFilter ;
77- query + = ` WHERE ${ startDatetimeColumnName } >= '${ start . toISOString ( ) } ' AND ${ endDatetimeColumnName } <= '${ end . toISOString ( ) } '` ;
122+ where = `${ startDatetimeColumnName } >= '${ start . toISOString ( ) } ' AND ${ endDatetimeColumnName } <= '${ end . toISOString ( ) } '` ;
78123 }
79- const result = await connection . query ( query ) ;
124+ const result = await executeDuckdbQuery ( {
125+ connection,
126+ href,
127+ hivePartitioning,
128+ select :
129+ "ST_AsWKB(geometry) AS geometry, ST_GeometryType(geometry) AS geometry_type, id" ,
130+ where,
131+ } ) ;
80132 const geometry : Uint8Array [ ] = result . getChildAt ( 0 ) ?. toArray ( ) ;
81133 const geometryType = result . getChildAt ( 1 ) ?. toArray ( ) [ 0 ] ?. toLowerCase ( ) as
82134 | string
@@ -136,25 +188,32 @@ export async function fetchStacGeoparquetItem({
136188 id,
137189 href,
138190 connection,
191+ hivePartitioning,
139192} : {
140193 id : string ;
141194 href : string ;
142195 connection : AsyncDuckDBConnection ;
196+ hivePartitioning : boolean ;
143197} ) {
144- const result = await connection . query (
145- `SELECT * REPLACE ST_AsGeoJSON(geometry) as geometry FROM read_parquet('${ href } ') WHERE id = '${ id } '`
146- ) ;
198+ const result = await executeDuckdbQuery ( {
199+ connection,
200+ href,
201+ hivePartitioning,
202+ select : "* REPLACE ST_AsGeoJSON(geometry) as geometry" ,
203+ where : `id = '${ id } '` ,
204+ } ) ;
147205 const item = stacWasm . arrowToStacJson ( result ) [ 0 ] ;
148206 item . geometry = JSON . parse ( item . geometry ) ;
149207 return item ;
150208}
151209
152210async function fetchStacGeoparquetDatetimeColumns (
153211 href : string ,
154- connection : AsyncDuckDBConnection
212+ connection : AsyncDuckDBConnection ,
213+ hivePartitioning : boolean
155214) {
156215 const describeResult = await connection . query (
157- `DESCRIBE SELECT * FROM read_parquet('${ href } ')`
216+ `DESCRIBE SELECT * FROM read_parquet('${ href } ', hive_partitioning = ${ hivePartitioning } )`
158217 ) ;
159218 const describe = describeResult . toArray ( ) . map ( ( row ) => row . toJSON ( ) ) ;
160219 const columnNames = describe . map ( ( row ) => row . column_name ) ;
0 commit comments