1- import { getArrowTableSchema } from "./arrow.mjs" ;
1+ import { getArrowTableSchema , isArrowTable } from "./arrow.mjs" ;
22import { arrow9 as arrow , duckdb } from "./dependencies.mjs" ;
33import { FileAttachment } from "./fileAttachment.mjs" ;
4+ import { cdn } from "./require.mjs" ;
45
56// Adapted from https://observablehq.com/@cmudig /duckdb-client
67// Copyright 2021 CMU Data Interaction Group
@@ -31,9 +32,6 @@ import {FileAttachment} from "./fileAttachment.mjs";
3132// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3233// POSSIBILITY OF SUCH DAMAGE.
3334
34- // TODO Allow this to be overridden using the Library’s resolver.
35- const cdn = "https://cdn.observableusercontent.com/npm/" ;
36-
3735export class DuckDBClient {
3836 constructor ( db ) {
3937 Object . defineProperties ( this , {
@@ -125,16 +123,22 @@ export class DuckDBClient {
125123 await db . open ( config ) ;
126124 await Promise . all (
127125 Object . entries ( sources ) . map ( async ( [ name , source ] ) => {
128- if ( "array" in source ) { // array + options
129- const { array, ...options } = source ;
130- await insertArray ( db , name , array , options ) ;
126+ if ( source instanceof FileAttachment ) { // bare file
127+ await insertFile ( db , name , source ) ;
128+ } else if ( isArrowTable ( source ) ) { // bare arrow table
129+ await insertArrowTable ( db , name , source ) ;
130+ } else if ( Array . isArray ( source ) ) { // bare array of objects
131+ await insertArray ( db , name , source ) ;
132+ } else if ( "data" in source ) { // data + options
133+ const { data, ...options } = source ;
134+ if ( isArrowTable ( data ) ) {
135+ await insertArrowTable ( db , name , data , options ) ;
136+ } else {
137+ await insertArray ( db , name , data , options ) ;
138+ }
131139 } else if ( "file" in source ) { // file + options
132140 const { file, ...options } = source ;
133141 await insertFile ( db , name , file , options ) ;
134- } else if ( source instanceof FileAttachment ) { // bare file
135- await insertFile ( db , name , source ) ;
136- } else if ( Array . isArray ( source ) ) { // bare data
137- await insertArray ( db , name , source ) ;
138142 } else {
139143 throw new Error ( `invalid source: ${ source } ` ) ;
140144 }
@@ -156,36 +160,40 @@ async function insertFile(database, name, file, options) {
156160 try {
157161 switch ( file . mimeType ) {
158162 case "text/csv" :
159- await connection . insertCSVFromPath ( file . name , {
163+ return await connection . insertCSVFromPath ( file . name , {
160164 name,
161165 schema : "main" ,
162166 ...options
163167 } ) ;
164- break ;
165168 case "application/json" :
166- await connection . insertJSONFromPath ( file . name , {
169+ return await connection . insertJSONFromPath ( file . name , {
167170 name,
168171 schema : "main" ,
169172 ...options
170173 } ) ;
171- break ;
172174 default :
173- if ( file . name . endsWith ( ".parquet" ) ) {
174- await connection . query (
175+ if ( / \. a r r o w $ / i. test ( file . name ) ) {
176+ const buffer = new Uint8Array ( await file . arrayBuffer ( ) ) ;
177+ return await connection . insertArrowFromIPCStream ( buffer , {
178+ name,
179+ schema : "main" ,
180+ ...options
181+ } ) ;
182+ }
183+ if ( / \. p a r q u e t $ / i. test ( file . name ) ) {
184+ return await connection . query (
175185 `CREATE VIEW '${ name } ' AS SELECT * FROM parquet_scan('${ file . name } ')`
176186 ) ;
177- } else {
178- throw new Error ( `unknown file type: ${ file . mimeType } ` ) ;
179187 }
188+ throw new Error ( `unknown file type: ${ file . mimeType } ` ) ;
180189 }
181190 } finally {
182191 await connection . close ( ) ;
183192 }
184193}
185194
186- async function insertArray ( database , name , array , options ) {
195+ async function insertArrowTable ( database , name , table , options ) {
187196 const arrow = await loadArrow ( ) ;
188- const table = arrow . tableFromJSON ( array ) ;
189197 const buffer = arrow . tableToIPC ( table ) ;
190198 const connection = await database . connect ( ) ;
191199 try {
@@ -199,6 +207,12 @@ async function insertArray(database, name, array, options) {
199207 }
200208}
201209
210+ async function insertArray ( database , name , array , options ) {
211+ const arrow = await loadArrow ( ) ;
212+ const table = arrow . tableFromJSON ( array ) ;
213+ return await insertArrowTable ( database , name , table , options ) ;
214+ }
215+
202216async function createDuckDB ( ) {
203217 const duck = await import ( `${ cdn } ${ duckdb . resolve ( ) } ` ) ;
204218 const bundle = await duck . selectBundle ( {
0 commit comments