@malloydata/db-postgres 0.0.195-dev241003204819 → 0.0.195-dev241007154000

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.
@@ -45,34 +45,23 @@ describe('PostgresConnection', () => {
45
45
  beforeEach(async () => {
46
46
  getTableSchema = jest
47
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- .spyOn(postgres_connection_1.PostgresConnection.prototype, 'getTableSchema')
48
+ .spyOn(postgres_connection_1.PostgresConnection.prototype, 'fetchTableSchema')
49
49
  .mockResolvedValue({
50
- type: 'struct',
50
+ type: 'table',
51
51
  dialect: 'postgres',
52
52
  name: 'name',
53
- structSource: { type: 'table', tablePath: 'test' },
54
- structRelationship: {
55
- type: 'basetable',
56
- connectionName: 'postgres',
57
- },
58
- fields: [],
53
+ tablePath: 'test',
54
+ connection: 'postgres',
59
55
  });
60
56
  getSQLBlockSchema = jest
61
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
- .spyOn(postgres_connection_1.PostgresConnection.prototype, 'getSQLBlockSchema')
58
+ .spyOn(postgres_connection_1.PostgresConnection.prototype, 'fetchSelectSchema')
63
59
  .mockResolvedValue({
64
- type: 'struct',
60
+ type: 'sql select',
65
61
  dialect: 'postgres',
66
62
  name: 'name',
67
- structSource: {
68
- type: 'sql',
69
- method: 'subquery',
70
- sqlBlock: SQL_BLOCK_1,
71
- },
72
- structRelationship: {
73
- type: 'basetable',
74
- connectionName: 'postgres',
75
- },
63
+ selectStr: SQL_BLOCK_1.selectStr,
64
+ connection: 'postgres',
76
65
  fields: [],
77
66
  });
78
67
  });
@@ -92,23 +81,26 @@ describe('PostgresConnection', () => {
92
81
  expect(getTableSchema).toBeCalledTimes(2);
93
82
  });
94
83
  it('caches sql schema', async () => {
95
- await connection.fetchSchemaForSQLBlock(SQL_BLOCK_1, {});
84
+ await connection.fetchSchemaForSQLStruct(SQL_BLOCK_1, {});
96
85
  expect(getSQLBlockSchema).toBeCalledTimes(1);
97
- await connection.fetchSchemaForSQLBlock(SQL_BLOCK_1, {});
86
+ await connection.fetchSchemaForSQLStruct(SQL_BLOCK_1, {});
98
87
  expect(getSQLBlockSchema).toBeCalledTimes(1);
99
88
  });
100
89
  it('refreshes sql schema', async () => {
101
- await connection.fetchSchemaForSQLBlock(SQL_BLOCK_2, {});
90
+ await connection.fetchSchemaForSQLStruct(SQL_BLOCK_2, {});
102
91
  expect(getSQLBlockSchema).toBeCalledTimes(1);
103
- await connection.fetchSchemaForSQLBlock(SQL_BLOCK_2, {
92
+ await connection.fetchSchemaForSQLStruct(SQL_BLOCK_2, {
104
93
  refreshTimestamp: Date.now() + 10,
105
94
  });
106
95
  expect(getSQLBlockSchema).toBeCalledTimes(2);
107
96
  });
108
97
  });
109
98
  const SQL_BLOCK_1 = {
110
- type: 'sqlBlock',
99
+ type: 'sql_select',
111
100
  name: 'block1',
101
+ dialect: 'postgres',
102
+ connection: 'postgres',
103
+ fields: [],
112
104
  selectStr: `
113
105
  SELECT
114
106
  created_at,
@@ -124,8 +116,11 @@ FROM "inventory_items.parquet"
124
116
  `,
125
117
  };
126
118
  const SQL_BLOCK_2 = {
127
- type: 'sqlBlock',
119
+ type: 'sql_select',
128
120
  name: 'block2',
121
+ dialect: 'postgres',
122
+ connection: 'postgres',
123
+ fields: [],
129
124
  selectStr: `
130
125
  SELECT
131
126
  created_at,
@@ -1,4 +1,4 @@
1
- import { Connection, ConnectionConfig, FetchSchemaOptions, MalloyQueryData, PersistSQLResults, PooledConnection, QueryDataRow, QueryOptionsReader, QueryRunStats, RunSQLOptions, SQLBlock, StreamingConnection, StructDef } from '@malloydata/malloy';
1
+ import { Connection, ConnectionConfig, MalloyQueryData, PersistSQLResults, PooledConnection, QueryDataRow, QueryOptionsReader, QueryRunStats, RunSQLOptions, SQLSourceDef, TableSourceDef, StreamingConnection } from '@malloydata/malloy';
2
2
  import { BaseConnection } from '@malloydata/malloy/connection';
3
3
  import { Client, Pool } from 'pg';
4
4
  interface PostgresConnectionConfiguration {
@@ -17,8 +17,6 @@ export declare class PostgresConnection extends BaseConnection implements Connec
17
17
  private queryOptionsReader;
18
18
  private configReader;
19
19
  private readonly dialect;
20
- private schemaCache;
21
- private sqlSchemaCache;
22
20
  constructor(options: PostgresConnectionOptions, queryOptionsReader?: QueryOptionsReader);
23
21
  constructor(name: string, queryOptionsReader?: QueryOptionsReader, configReader?: PostgresConnectionConfigurationReader);
24
22
  private readQueryConfig;
@@ -28,22 +26,11 @@ export declare class PostgresConnection extends BaseConnection implements Connec
28
26
  canPersist(): this is PersistSQLResults;
29
27
  canStream(): this is StreamingConnection;
30
28
  get supportsNesting(): boolean;
31
- fetchSchemaForTables(missing: Record<string, string>, { refreshTimestamp }: FetchSchemaOptions): Promise<{
32
- schemas: Record<string, StructDef>;
33
- errors: Record<string, string>;
34
- }>;
35
- fetchSchemaForSQLBlock(sqlRef: SQLBlock, { refreshTimestamp }: FetchSchemaOptions): Promise<{
36
- structDef: StructDef;
37
- error?: undefined;
38
- } | {
39
- error: string;
40
- structDef?: undefined;
41
- }>;
42
29
  protected getClient(): Promise<Client>;
43
30
  protected runPostgresQuery(sqlCommand: string, _pageSize: number, _rowIndex: number, deJSON: boolean): Promise<MalloyQueryData>;
44
- private getSQLBlockSchema;
31
+ fetchSelectSchema(sqlRef: SQLSourceDef): Promise<SQLSourceDef | string>;
45
32
  private schemaFromQuery;
46
- private getTableSchema;
33
+ fetchTableSchema(tableKey: string, tablePath: string): Promise<TableSourceDef | string>;
47
34
  test(): Promise<void>;
48
35
  connectionSetup(client: Client): Promise<void>;
49
36
  runSQL(sql: string, { rowLimit }?: RunSQLOptions, rowIndex?: number): Promise<MalloyQueryData>;
@@ -68,8 +68,6 @@ class PostgresConnection extends connection_1.BaseConnection {
68
68
  this.queryOptionsReader = {};
69
69
  this.configReader = {};
70
70
  this.dialect = new malloy_1.PostgresDialect();
71
- this.schemaCache = new Map();
72
- this.sqlSchemaCache = new Map();
73
71
  if (typeof arg === 'string') {
74
72
  this.name = arg;
75
73
  if (configReader) {
@@ -116,54 +114,6 @@ class PostgresConnection extends connection_1.BaseConnection {
116
114
  get supportsNesting() {
117
115
  return true;
118
116
  }
119
- async fetchSchemaForTables(missing, { refreshTimestamp }) {
120
- const schemas = {};
121
- const errors = {};
122
- for (const tableKey in missing) {
123
- let inCache = this.schemaCache.get(tableKey);
124
- if (!inCache ||
125
- (refreshTimestamp && refreshTimestamp > inCache.timestamp)) {
126
- const tablePath = missing[tableKey];
127
- const timestamp = refreshTimestamp || Date.now();
128
- try {
129
- inCache = {
130
- schema: await this.getTableSchema(tableKey, tablePath),
131
- timestamp,
132
- };
133
- this.schemaCache.set(tableKey, inCache);
134
- }
135
- catch (error) {
136
- inCache = { error: error.message, timestamp };
137
- }
138
- }
139
- if (inCache.schema !== undefined) {
140
- schemas[tableKey] = inCache.schema;
141
- }
142
- else {
143
- errors[tableKey] = inCache.error || 'Unknown schema fetch error';
144
- }
145
- }
146
- return { schemas, errors };
147
- }
148
- async fetchSchemaForSQLBlock(sqlRef, { refreshTimestamp }) {
149
- const key = sqlRef.name;
150
- let inCache = this.sqlSchemaCache.get(key);
151
- if (!inCache ||
152
- (refreshTimestamp && refreshTimestamp > inCache.timestamp)) {
153
- const timestamp = refreshTimestamp !== null && refreshTimestamp !== void 0 ? refreshTimestamp : Date.now();
154
- try {
155
- inCache = {
156
- structDef: await this.getSQLBlockSchema(sqlRef),
157
- timestamp,
158
- };
159
- }
160
- catch (error) {
161
- inCache = { error: error.message, timestamp };
162
- }
163
- this.sqlSchemaCache.set(key, inCache);
164
- }
165
- return inCache;
166
- }
167
117
  async getClient() {
168
118
  const { username: user, password, databaseName: database, port, host, connectionString, } = await this.readConfig();
169
119
  return new pg_1.Client({
@@ -194,22 +144,8 @@ class PostgresConnection extends connection_1.BaseConnection {
194
144
  totalRows: result.rows.length,
195
145
  };
196
146
  }
197
- async getSQLBlockSchema(sqlRef) {
198
- const structDef = {
199
- type: 'struct',
200
- dialect: 'postgres',
201
- name: sqlRef.name,
202
- structSource: {
203
- type: 'sql',
204
- method: 'subquery',
205
- sqlBlock: sqlRef,
206
- },
207
- structRelationship: {
208
- type: 'basetable',
209
- connectionName: this.name,
210
- },
211
- fields: [],
212
- };
147
+ async fetchSelectSchema(sqlRef) {
148
+ const structDef = { ...sqlRef, fields: [] };
213
149
  const tempTableName = `tmp${(0, crypto_1.randomUUID)()}`.replace(/-/g, '');
214
150
  const infoQuery = `
215
151
  drop table if exists ${tempTableName};
@@ -226,7 +162,7 @@ class PostgresConnection extends connection_1.BaseConnection {
226
162
  await this.schemaFromQuery(infoQuery, structDef);
227
163
  }
228
164
  catch (error) {
229
- throw new Error(`Error fetching schema for ${sqlRef.name}: ${error}`);
165
+ return `Error fetching schema for ${sqlRef.name}: ${error}`;
230
166
  }
231
167
  return structDef;
232
168
  }
@@ -237,53 +173,36 @@ class PostgresConnection extends connection_1.BaseConnection {
237
173
  }
238
174
  for (const row of rows) {
239
175
  const postgresDataType = row['data_type'];
240
- let s = structDef;
241
- let malloyType = this.dialect.sqlTypeToMalloyType(postgresDataType);
242
- let name = row['column_name'];
176
+ const name = row['column_name'];
243
177
  if (postgresDataType === 'ARRAY') {
244
- malloyType = this.dialect.sqlTypeToMalloyType(row['element_type']);
245
- s = {
246
- type: 'struct',
247
- name: row['column_name'],
178
+ const elementType = this.dialect.sqlTypeToMalloyType(row['element_type']);
179
+ structDef.fields.push({
180
+ type: 'array',
181
+ elementTypeDef: elementType,
182
+ name,
248
183
  dialect: this.dialectName,
249
- structRelationship: {
250
- type: 'nested',
251
- fieldName: name,
252
- isArray: true,
253
- },
254
- structSource: { type: 'nested' },
255
- fields: [],
256
- };
257
- structDef.fields.push(s);
258
- name = 'value';
259
- }
260
- if (malloyType) {
261
- s.fields.push({ ...malloyType, name });
184
+ join: 'many',
185
+ fields: (0, malloy_1.arrayEachFields)(elementType),
186
+ });
262
187
  }
263
188
  else {
264
- s.fields.push({
265
- type: 'sql native',
266
- rawType: postgresDataType.toLowerCase(),
267
- name,
268
- });
189
+ const malloyType = this.dialect.sqlTypeToMalloyType(postgresDataType);
190
+ structDef.fields.push({ ...malloyType, name });
269
191
  }
270
192
  }
271
193
  }
272
- async getTableSchema(tableKey, tablePath) {
194
+ async fetchTableSchema(tableKey, tablePath) {
273
195
  const structDef = {
274
- type: 'struct',
196
+ type: 'table',
275
197
  name: tableKey,
276
198
  dialect: 'postgres',
277
- structSource: { type: 'table', tablePath },
278
- structRelationship: {
279
- type: 'basetable',
280
- connectionName: this.name,
281
- },
199
+ tablePath,
200
+ connection: this.name,
282
201
  fields: [],
283
202
  };
284
203
  const [schema, table] = tablePath.split('.');
285
204
  if (table === undefined) {
286
- throw new Error('Default schema not yet supported in Postgres');
205
+ return 'Default schema not yet supported in Postgres';
287
206
  }
288
207
  const infoQuery = `
289
208
  SELECT column_name, c.data_type, e.data_type as element_type
@@ -297,7 +216,7 @@ class PostgresConnection extends connection_1.BaseConnection {
297
216
  await this.schemaFromQuery(infoQuery, structDef);
298
217
  }
299
218
  catch (error) {
300
- throw new Error(`Error fetching schema for ${tablePath}: ${error}`);
219
+ return `Error fetching schema for ${tablePath}: ${error.message}`;
301
220
  }
302
221
  return structDef;
303
222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/db-postgres",
3
- "version": "0.0.195-dev241003204819",
3
+ "version": "0.0.195-dev241007154000",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "prepublishOnly": "npm run build"
23
23
  },
24
24
  "dependencies": {
25
- "@malloydata/malloy": "^0.0.195-dev241003204819",
25
+ "@malloydata/malloy": "^0.0.195-dev241007154000",
26
26
  "@types/pg": "^8.6.1",
27
27
  "pg": "^8.7.1",
28
28
  "pg-query-stream": "4.2.3"