@@ -15,6 +15,7 @@ import {
1515} from './runtime' ;
1616import { DuckDBModule } from './duckdb_module' ;
1717import * as udf from './udf_runtime' ;
18+ import { DuckDBAccessMode } from './config' ;
1819
1920const OPFS_PREFIX_LEN = 'opfs://' . length ;
2021const PATH_SEP_REGEX = / \/ | \\ / ;
@@ -110,8 +111,11 @@ export const BROWSER_RUNTIME: DuckDBRuntime & {
110111 BROWSER_RUNTIME . _opfsRoot = await navigator . storage . getDirectory ( ) ;
111112 }
112113 } ,
113- /** Prepare a file handle that could only be acquired aschronously */
114- async prepareFileHandles ( filePaths : string [ ] , protocol : DuckDBDataProtocol ) : Promise < PreparedDBFileHandle [ ] > {
114+ /** Prepare a file handle that could only be acquired asynchronously */
115+ async prepareFileHandles ( filePaths : string [ ] , protocol : DuckDBDataProtocol , accessMode ?: DuckDBAccessMode ) : Promise < PreparedDBFileHandle [ ] > {
116+ // DuckDBAccessMode.UNDEFINED will be treated as READ_WRITE
117+ // See: https://github.com/duckdb/duckdb/blob/5f5512b827df6397afd31daedb4bbdee76520019/src/main/database.cpp#L442-L444
118+ const isReadWrite = ! accessMode || accessMode === DuckDBAccessMode . READ_WRITE ;
115119 if ( protocol === DuckDBDataProtocol . BROWSER_FSACCESS ) {
116120 await BROWSER_RUNTIME . assignOPFSRoot ( ) ;
117121 const prepare = async ( path : string ) : Promise < PreparedDBFileHandle > => {
@@ -135,13 +139,16 @@ export const BROWSER_RUNTIME: DuckDBRuntime & {
135139 }
136140 // mkdir -p
137141 for ( const folder of folders ) {
138- dirHandle = await dirHandle . getDirectoryHandle ( folder , { create : true } ) ;
142+ dirHandle = await dirHandle . getDirectoryHandle ( folder , { create : isReadWrite } ) ;
139143 }
140144 }
141145 const fileHandle = await dirHandle . getFileHandle ( fileName , { create : false } ) . catch ( e => {
142146 if ( e ?. name === 'NotFoundError' ) {
143- console . debug ( `File ${ path } does not exists yet, creating...` ) ;
144- return dirHandle . getFileHandle ( fileName , { create : true } ) ;
147+ if ( isReadWrite ) {
148+ console . debug ( `File ${ path } does not exists yet, creating...` ) ;
149+ return dirHandle . getFileHandle ( fileName , { create : true } ) ;
150+ }
151+ console . debug ( `File ${ path } does not exists, aborting as we are in read-only mode` ) ;
145152 }
146153 throw e ;
147154 } ) ;
@@ -166,11 +173,11 @@ export const BROWSER_RUNTIME: DuckDBRuntime & {
166173 }
167174 throw new Error ( `Unsupported protocol ${ protocol } for paths ${ filePaths } with protocol ${ protocol } ` ) ;
168175 } ,
169- /** Prepare a file handle that could only be acquired aschronously */
170- async prepareDBFileHandle ( dbPath : string , protocol : DuckDBDataProtocol ) : Promise < PreparedDBFileHandle [ ] > {
176+ /** Prepare a file handle that could only be acquired asynchronously */
177+ async prepareDBFileHandle ( dbPath : string , protocol : DuckDBDataProtocol , accessMode ?: DuckDBAccessMode ) : Promise < PreparedDBFileHandle [ ] > {
171178 if ( protocol === DuckDBDataProtocol . BROWSER_FSACCESS && this . prepareFileHandles ) {
172179 const filePaths = [ dbPath , `${ dbPath } .wal` ] ;
173- return this . prepareFileHandles ( filePaths , protocol ) ;
180+ return this . prepareFileHandles ( filePaths , protocol , accessMode ) ;
174181 }
175182 throw new Error ( `Unsupported protocol ${ protocol } for path ${ dbPath } with protocol ${ protocol } ` ) ;
176183 } ,
0 commit comments