@malloydata/db-duckdb 0.0.15-dev221209192619 → 0.0.15-dev221209193631

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,8 @@ export declare type QueryOptionsReader = Partial<DuckDBQueryOptions> | (() => Pa
6
6
  export declare abstract class DuckDBCommon implements Connection, PersistSQLResults, StreamingConnection {
7
7
  private queryOptions?;
8
8
  static DEFAULT_QUERY_OPTIONS: DuckDBQueryOptions;
9
+ private schemaCache;
10
+ private sqlSchemaCache;
9
11
  readonly name: string;
10
12
  get dialectName(): string;
11
13
  private readQueryOptions;
@@ -28,6 +28,8 @@ const duckDBToMalloyTypes = {
28
28
  class DuckDBCommon {
29
29
  constructor(queryOptions) {
30
30
  this.queryOptions = queryOptions;
31
+ this.schemaCache = new Map();
32
+ this.sqlSchemaCache = new Map();
31
33
  this.name = "duckdb_common";
32
34
  }
33
35
  get dialectName() {
@@ -216,22 +218,42 @@ class DuckDBCommon {
216
218
  this.fillStructDefFromTypeMap(structDef, typeMap);
217
219
  }
218
220
  async fetchSchemaForSQLBlock(sqlRef) {
219
- try {
220
- return { structDef: await this.getSQLBlockSchema(sqlRef) };
221
- }
222
- catch (error) {
223
- return { error: error.message };
221
+ const key = sqlRef.name;
222
+ let inCache = this.sqlSchemaCache.get(key);
223
+ if (!inCache) {
224
+ try {
225
+ inCache = {
226
+ structDef: await this.getSQLBlockSchema(sqlRef),
227
+ };
228
+ }
229
+ catch (error) {
230
+ inCache = { error: error.message };
231
+ }
232
+ this.sqlSchemaCache.set(key, inCache);
224
233
  }
234
+ return inCache;
225
235
  }
226
236
  async fetchSchemaForTables(tables) {
227
237
  const schemas = {};
228
238
  const errors = {};
229
239
  for (const tableURL of tables) {
230
- try {
231
- schemas[tableURL] = await this.getTableSchema(tableURL);
240
+ let inCache = this.schemaCache.get(tableURL);
241
+ if (!inCache) {
242
+ try {
243
+ inCache = {
244
+ schema: await this.getTableSchema(tableURL),
245
+ };
246
+ this.schemaCache.set(tableURL, inCache);
247
+ }
248
+ catch (error) {
249
+ inCache = { error: error.message };
250
+ }
232
251
  }
233
- catch (error) {
234
- errors[tableURL] = error.toString();
252
+ if (inCache.schema !== undefined) {
253
+ schemas[tableURL] = inCache.schema;
254
+ }
255
+ else {
256
+ errors[tableURL] = inCache.error;
235
257
  }
236
258
  }
237
259
  return { schemas, errors };
@@ -7,7 +7,7 @@ export declare class DuckDBConnection extends DuckDBCommon {
7
7
  private workingDirectory;
8
8
  protected connection: import("duckdb").Connection;
9
9
  protected database: Database;
10
- protected isSetup: boolean;
10
+ protected isSetup: Promise<void> | undefined;
11
11
  constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
12
12
  protected setup(): Promise<void>;
13
13
  protected runDuckDBQuery(sql: string): Promise<{
@@ -44,7 +44,6 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
44
44
  super(queryOptions);
45
45
  this.name = name;
46
46
  this.workingDirectory = workingDirectory;
47
- this.isSetup = false;
48
47
  this.database = new duckdb_1.Database(databasePath, duckdb_1.OPEN_READWRITE, // databasePath === ":memory:" ? OPEN_READWRITE : OPEN_READONLY,
49
48
  (err) => {
50
49
  if (err) {
@@ -54,28 +53,31 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
54
53
  this.connection = this.database.connect();
55
54
  }
56
55
  async setup() {
57
- if (!this.isSetup) {
56
+ const doSetup = async () => {
58
57
  if (this.workingDirectory) {
59
- this.runDuckDBQuery(`SET FILE_SEARCH_PATH='${this.workingDirectory}'`);
58
+ await this.runDuckDBQuery(`SET FILE_SEARCH_PATH='${this.workingDirectory}'`);
59
+ }
60
+ try {
61
+ await this.runDuckDBQuery("INSTALL 'json'");
62
+ await this.runDuckDBQuery("LOAD 'json'");
63
+ }
64
+ catch (error) {
65
+ // eslint-disable-next-line no-console
66
+ console.error("Unable to load json extension", error);
60
67
  }
61
- // TODO: This is where we will load extensions once we figure
62
- // out how to better support them.
63
- // await this.runDuckDBQuery("INSTALL 'json'");
64
- // await this.runDuckDBQuery("LOAD 'json'");
65
- // await this.runDuckDBQuery("INSTALL 'httpfs'");
66
- // await this.runDuckDBQuery("LOAD 'httpfs'");
67
- // await this.runDuckDBQuery("DROP MACRO sum_distinct");
68
- // try {
69
- // await this.runDuckDBQuery(
70
- // `
71
- // create macro sum_distinct(l) as (
72
- // select sum(x.val) as value FROM (select unnest(l)) x
73
- // )
74
- // `
75
- // );
76
- // } catch (e) {}
68
+ try {
69
+ await this.runDuckDBQuery("INSTALL 'httpfs'");
70
+ await this.runDuckDBQuery("LOAD 'httpfs'");
71
+ }
72
+ catch (error) {
73
+ // eslint-disable-next-line no-console
74
+ console.error("Unable to load httpfs extension", error);
75
+ }
76
+ };
77
+ if (!this.isSetup) {
78
+ this.isSetup = doSetup();
77
79
  }
78
- this.isSetup = true;
80
+ await this.isSetup;
79
81
  }
80
82
  async runDuckDBQuery(sql) {
81
83
  return new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/db-duckdb",
3
- "version": "0.0.15-dev221209192619",
3
+ "version": "0.0.15-dev221209193631",
4
4
  "license": "GPL-2.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@duckdb/duckdb-wasm": "^1.17.0",
22
- "@malloydata/malloy": "^0.0.15-dev221209192619",
22
+ "@malloydata/malloy": "^0.0.15-dev221209193631",
23
23
  "duckdb": "0.6.1"
24
24
  }
25
25
  }