@@ -18,6 +18,7 @@ import { InstantiationProgress } from '../bindings/progress';
1818import { arrowToSQLField } from '../json_typedef' ;
1919import { WebFile } from '../bindings/web_file' ;
2020import { DuckDBDataProtocol } from '../bindings' ;
21+ import { searchOPFSFiles , isOPFSProtocol } from "../utils/opfs_util" ;
2122
2223const TEXT_ENCODER = new TextEncoder ( ) ;
2324
@@ -45,6 +46,8 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
4546 protected _nextMessageId = 0 ;
4647 /** The pending requests */
4748 protected _pendingRequests : Map < number , WorkerTaskVariant > = new Map ( ) ;
49+ /** The DuckDBConfig */
50+ protected _config : DuckDBConfig = { } ;
4851
4952 constructor ( logger : Logger , worker : Worker | null = null ) {
5053 this . _logger = logger ;
@@ -59,6 +62,11 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
5962 return this . _logger ;
6063 }
6164
65+ /** Get the logger */
66+ public get config ( ) : DuckDBConfig {
67+ return this . _config ;
68+ }
69+
6270 /** Attach to worker */
6371 protected attach ( worker : Worker ) : void {
6472 this . _worker = worker ;
@@ -100,7 +108,7 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
100108 transfer : ArrayBuffer [ ] = [ ] ,
101109 ) : Promise < WorkerTaskReturnType < W > > {
102110 if ( ! this . _worker ) {
103- console . error ( 'cannot send a message since the worker is not set!' ) ;
111+ console . error ( 'cannot send a message since the worker is not set!:' + task . type + "," + task . data ) ;
104112 return undefined as any ;
105113 }
106114 const mid = this . _nextMessageId ++ ;
@@ -317,8 +325,8 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
317325 return await this . postTask ( task ) ;
318326 }
319327 /** Try to drop files */
320- public async dropFiles ( ) : Promise < null > {
321- const task = new WorkerTask < WorkerRequestType . DROP_FILES , null , null > ( WorkerRequestType . DROP_FILES , null ) ;
328+ public async dropFiles ( names ?: string [ ] ) : Promise < null > {
329+ const task = new WorkerTask < WorkerRequestType . DROP_FILES , string [ ] | undefined , null > ( WorkerRequestType . DROP_FILES , names ) ;
322330 return await this . postTask ( task ) ;
323331 }
324332 /** Flush all files */
@@ -360,6 +368,7 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
360368
361369 /** Open a new database */
362370 public async open ( config : DuckDBConfig ) : Promise < void > {
371+ this . _config = config ;
363372 const task = new WorkerTask < WorkerRequestType . OPEN , DuckDBConfig , null > ( WorkerRequestType . OPEN , config ) ;
364373 await this . postTask ( task ) ;
365374 }
@@ -394,6 +403,21 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
394403
395404 /** Run a query */
396405 public async runQuery ( conn : ConnectionID , text : string ) : Promise < Uint8Array > {
406+ if ( this . shouldOPFSFileHandling ( ) ) {
407+ const files = await this . registerOPFSFileFromSQL ( text ) ;
408+ try {
409+ return await this . _runQueryAsync ( conn , text ) ;
410+ } finally {
411+ if ( files . length > 0 ) {
412+ await this . dropFiles ( files ) ;
413+ }
414+ }
415+ } else {
416+ return await this . _runQueryAsync ( conn , text ) ;
417+ }
418+ }
419+
420+ private async _runQueryAsync ( conn : ConnectionID , text : string ) : Promise < Uint8Array > {
397421 const task = new WorkerTask < WorkerRequestType . RUN_QUERY , [ ConnectionID , string ] , Uint8Array > (
398422 WorkerRequestType . RUN_QUERY ,
399423 [ conn , text ] ,
@@ -406,6 +430,25 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
406430 conn : ConnectionID ,
407431 text : string ,
408432 allowStreamResult : boolean = false ,
433+ ) : Promise < Uint8Array | null > {
434+ if ( this . shouldOPFSFileHandling ( ) ) {
435+ const files = await this . registerOPFSFileFromSQL ( text ) ;
436+ try {
437+ return await this . _startPendingQueryAsync ( conn , text , allowStreamResult ) ;
438+ } finally {
439+ if ( files . length > 0 ) {
440+ await this . dropFiles ( files ) ;
441+ }
442+ }
443+ } else {
444+ return await this . _startPendingQueryAsync ( conn , text , allowStreamResult ) ;
445+ }
446+ }
447+
448+ private async _startPendingQueryAsync (
449+ conn : ConnectionID ,
450+ text : string ,
451+ allowStreamResult : boolean = false ,
409452 ) : Promise < Uint8Array | null > {
410453 const task = new WorkerTask <
411454 WorkerRequestType . START_PENDING_QUERY ,
@@ -414,6 +457,7 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
414457 > ( WorkerRequestType . START_PENDING_QUERY , [ conn , text , allowStreamResult ] ) ;
415458 return await this . postTask ( task ) ;
416459 }
460+
417461 /** Poll a pending query */
418462 public async pollPendingQuery ( conn : ConnectionID ) : Promise < Uint8Array | null > {
419463 const task = new WorkerTask < WorkerRequestType . POLL_PENDING_QUERY , ConnectionID , Uint8Array | null > (
@@ -647,4 +691,26 @@ export class AsyncDuckDB implements AsyncDuckDBBindings {
647691 ) ;
648692 await this . postTask ( task ) ;
649693 }
694+
695+ private shouldOPFSFileHandling ( ) :boolean {
696+ if ( isOPFSProtocol ( this . config . path ?? "" ) ) {
697+ return this . config . opfs ?. fileHandling == "auto" ;
698+ }
699+ return false ;
700+ }
701+
702+ private async registerOPFSFileFromSQL ( text : string ) {
703+ const files = searchOPFSFiles ( text ) ;
704+ const result : string [ ] = [ ] ;
705+ for ( const file of files ) {
706+ try {
707+ await this . registerOPFSFileName ( file ) ;
708+ result . push ( file ) ;
709+ } catch ( e ) {
710+ console . error ( e ) ;
711+ throw new Error ( "File Not found:" + file ) ;
712+ }
713+ }
714+ return result ;
715+ }
650716}
0 commit comments