Skip to content

Commit 635259f

Browse files
committed
bigquery connector
1 parent 2c1b55d commit 635259f

File tree

4 files changed

+171
-1
lines changed

4 files changed

+171
-1
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,17 @@
8080
},
8181
"peerDependencies": {
8282
"@duckdb/node-api": "^1.3.2-alpha.26",
83+
"@google-cloud/bigquery": "^8.1.1",
8384
"postgres": "^3.4.7",
8485
"snowflake-sdk": "^2.1.3"
8586
},
8687
"peerDependenciesMeta": {
8788
"@duckdb/node-api": {
8889
"optional": true
8990
},
91+
"@google-cloud/bigquery": {
92+
"optional": true
93+
},
9094
"postgres": {
9195
"optional": true
9296
},

src/databases/bigquery.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {BigQuery} from "@google-cloud/bigquery";
2+
import type {TableField, TableSchema} from "@google-cloud/bigquery";
3+
import type {BigQueryConfig, QueryTemplateFunction} from "./index.js";
4+
import type {ColumnSchema} from "../runtime/index.js";
5+
6+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
7+
export default function bigquery({type, ...options}: BigQueryConfig): QueryTemplateFunction {
8+
return async (strings, ...params) => {
9+
const bigquery = new BigQuery(options);
10+
const date = new Date();
11+
const [job] = await bigquery.createQueryJob({query: strings.join("?"), params});
12+
const [rows, , response] = await job.getQueryResults();
13+
return {rows, schema: getTableSchema(response!.schema!), duration: Date.now() - +date, date};
14+
};
15+
}
16+
17+
function getTableSchema({fields}: TableSchema): ColumnSchema[] {
18+
return fields!.map(getColumnSchema);
19+
}
20+
21+
function getColumnSchema(field: TableField): ColumnSchema {
22+
return {name: field.name!, type: getColumnType(field)};
23+
}
24+
25+
function getColumnType({type, mode}: TableField): ColumnSchema["type"] {
26+
switch (mode) {
27+
case "REPEATED":
28+
return "array";
29+
}
30+
switch (type) {
31+
case "DATE":
32+
case "DATETIME":
33+
case "TIMESTAMP":
34+
return "date";
35+
case "BOOL":
36+
case "BOOLEAN":
37+
return "boolean";
38+
case "STRUCT":
39+
case "RECORD":
40+
case "GEOGRAPHY":
41+
return "object";
42+
case "BYTES":
43+
return "buffer";
44+
case "FLOAT":
45+
case "FLOAT64":
46+
return "number";
47+
case "INT64":
48+
case "INTEGER":
49+
return "number";
50+
case "NUMERIC":
51+
return "number";
52+
case "STRING":
53+
case "TIME":
54+
default:
55+
return "string";
56+
}
57+
}

src/databases/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@ import {isEnoent} from "../lib/error.js";
55
import {hash as getQueryHash, nameHash as getNameHash} from "../lib/hash.js";
66
import type {ColumnSchema, QueryParam} from "../runtime/index.js";
77

8-
export type DatabaseConfig = DuckDBConfig | SQLiteConfig | SnowflakeConfig | PostgresConfig;
8+
export type DatabaseConfig =
9+
| BigQueryConfig
10+
| DuckDBConfig
11+
| SQLiteConfig
12+
| SnowflakeConfig
13+
| PostgresConfig;
14+
15+
export type BigQueryConfig = {
16+
type: "bigquery";
17+
apiKey?: string;
18+
keyFilename?: string;
19+
keyFile?: string;
20+
projectId?: string;
21+
};
922

1023
export type DuckDBConfig = {
1124
type: "duckdb";
@@ -78,6 +91,8 @@ export async function getDatabaseConfig(
7891

7992
export async function getDatabase(config: DatabaseConfig): Promise<QueryTemplateFunction> {
8093
switch (config.type) {
94+
case "bigquery":
95+
return (await import("./bigquery.js")).default(config);
8196
case "duckdb":
8297
return (await import("./duckdb.js")).default(config);
8398
case "sqlite":

yarn.lock

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,37 @@
10861086
resolved "https://registry.yarnpkg.com/@fontsource/spline-sans-mono/-/spline-sans-mono-5.2.6.tgz#2326a45fcc772ac69dab1bd68f9511b093d5395d"
10871087
integrity sha512-TPAQoRX/UH6qqd38stFqJvBcDw/E6Nqnm/b5qxr/fV7jhvsRjIxcC0GR7EdVqPOELVAy1HtmQtO/bDz5S9VbPw==
10881088

1089+
"@google-cloud/bigquery@^8.1.1":
1090+
version "8.1.1"
1091+
resolved "https://registry.yarnpkg.com/@google-cloud/bigquery/-/bigquery-8.1.1.tgz#2dd48c497a0229f653e39ff14499c7cd4378df1f"
1092+
integrity sha512-2GHlohfA/VJffTvibMazMsZi6jPRx8MmaMberyDTL8rnhVs/frKSXVVRtLU83uSAy2j/5SD4mOs4jMQgJPON2g==
1093+
dependencies:
1094+
"@google-cloud/common" "^6.0.0"
1095+
"@google-cloud/paginator" "^6.0.0"
1096+
"@google-cloud/precise-date" "^5.0.0"
1097+
"@google-cloud/promisify" "^5.0.0"
1098+
arrify "^3.0.0"
1099+
big.js "^6.2.2"
1100+
duplexify "^4.1.3"
1101+
extend "^3.0.2"
1102+
stream-events "^1.0.5"
1103+
teeny-request "^10.0.0"
1104+
1105+
"@google-cloud/common@^6.0.0":
1106+
version "6.0.0"
1107+
resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-6.0.0.tgz#776d4f747f0a3844f4ce13e06a2268743064b563"
1108+
integrity sha512-IXh04DlkLMxWgYLIUYuHHKXKOUwPDzDgke1ykkkJPe48cGIS9kkL2U/o0pm4ankHLlvzLF/ma1eO86n/bkumIA==
1109+
dependencies:
1110+
"@google-cloud/projectify" "^4.0.0"
1111+
"@google-cloud/promisify" "^4.0.0"
1112+
arrify "^2.0.0"
1113+
duplexify "^4.1.3"
1114+
extend "^3.0.2"
1115+
google-auth-library "^10.0.0-rc.1"
1116+
html-entities "^2.5.2"
1117+
retry-request "^8.0.0"
1118+
teeny-request "^10.0.0"
1119+
10891120
"@google-cloud/paginator@^5.0.0":
10901121
version "5.0.2"
10911122
resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-5.0.2.tgz#86ad773266ce9f3b82955a8f75e22cd012ccc889"
@@ -1094,6 +1125,18 @@
10941125
arrify "^2.0.0"
10951126
extend "^3.0.2"
10961127

1128+
"@google-cloud/paginator@^6.0.0":
1129+
version "6.0.0"
1130+
resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-6.0.0.tgz#27d477c2e75f7839da13ca681f6427e015ad75d1"
1131+
integrity sha512-g5nmMnzC+94kBxOKkLGpK1ikvolTFCC3s2qtE4F+1EuArcJ7HHC23RDQVt3Ra3CqpUYZ+oXNKZ8n5Cn5yug8DA==
1132+
dependencies:
1133+
extend "^3.0.2"
1134+
1135+
"@google-cloud/precise-date@^5.0.0":
1136+
version "5.0.0"
1137+
resolved "https://registry.yarnpkg.com/@google-cloud/precise-date/-/precise-date-5.0.0.tgz#31891974143ecdcacce0a6835c285a77b0968477"
1138+
integrity sha512-9h0Gvw92EvPdE8AK8AgZPbMnH5ftDyPtKm7/KUfcJVaPEPjwGDsJd1QV0H8esBDV4II41R/2lDWH1epBqIoKUw==
1139+
10971140
"@google-cloud/projectify@^4.0.0":
10981141
version "4.0.0"
10991142
resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-4.0.0.tgz#d600e0433daf51b88c1fa95ac7f02e38e80a07be"
@@ -1104,6 +1147,16 @@
11041147
resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-4.0.0.tgz#a906e533ebdd0f754dca2509933334ce58b8c8b1"
11051148
integrity sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==
11061149

1150+
"@google-cloud/promisify@^4.0.0":
1151+
version "4.1.0"
1152+
resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-4.1.0.tgz#df8b060f0121c6462233f5420738dcda09c6df4a"
1153+
integrity sha512-G/FQx5cE/+DqBbOpA5jKsegGwdPniU6PuIEMt+qxWgFxvxuFOzVmp6zYchtYuwAWV5/8Dgs0yAmjvNZv3uXLQg==
1154+
1155+
"@google-cloud/promisify@^5.0.0":
1156+
version "5.0.0"
1157+
resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-5.0.0.tgz#94e44ba4e5ea410d3c82a03fcb37ca34dbc5d1d5"
1158+
integrity sha512-N8qS6dlORGHwk7WjGXKOSsLjIjNINCPicsOX6gyyLiYk7mq3MtII96NZ9N2ahwA2vnkLmZODOIH9rlNniYWvCQ==
1159+
11071160
"@google-cloud/storage@^7.7.0":
11081161
version "7.16.0"
11091162
resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-7.16.0.tgz#62c04ee4f80190992ef06cb033a90c054bcea575"
@@ -2310,6 +2363,11 @@ arrify@^2.0.0:
23102363
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
23112364
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
23122365

2366+
arrify@^3.0.0:
2367+
version "3.0.0"
2368+
resolved "https://registry.yarnpkg.com/arrify/-/arrify-3.0.0.tgz#ccdefb8eaf2a1d2ab0da1ca2ce53118759fd46bc"
2369+
integrity sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==
2370+
23132371
asn1.js-rfc2560@^5.0.0, asn1.js-rfc2560@^5.0.1:
23142372
version "5.0.1"
23152373
resolved "https://registry.yarnpkg.com/asn1.js-rfc2560/-/asn1.js-rfc2560-5.0.1.tgz#cff99b903e714756b29503ad49de01c72f131e60"
@@ -2380,6 +2438,11 @@ big-integer@^1.6.43:
23802438
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85"
23812439
integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==
23822440

2441+
big.js@^6.2.2:
2442+
version "6.2.2"
2443+
resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.2.tgz#be3bb9ac834558b53b099deef2a1d06ac6368e1a"
2444+
integrity sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==
2445+
23832446
bignumber.js@^9.0.0, bignumber.js@^9.1.2:
23842447
version "9.3.1"
23852448
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.1.tgz#759c5aaddf2ffdc4f154f7b493e1c8770f88c4d7"
@@ -3163,6 +3226,19 @@ globals@^16.2.0:
31633226
resolved "https://registry.yarnpkg.com/globals/-/globals-16.2.0.tgz#19efcd1ddde2bd5efce128e5c2e441df1abc6f7c"
31643227
integrity sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==
31653228

3229+
google-auth-library@^10.0.0-rc.1:
3230+
version "10.3.0"
3231+
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-10.3.0.tgz#d44d005d546bf6b8956529caf0f9e70a07960c04"
3232+
integrity sha512-ylSE3RlCRZfZB56PFJSfUCuiuPq83Fx8hqu1KPWGK8FVdSaxlp/qkeMMX/DT/18xkwXIHvXEXkZsljRwfrdEfQ==
3233+
dependencies:
3234+
base64-js "^1.3.0"
3235+
ecdsa-sig-formatter "^1.0.11"
3236+
gaxios "^7.0.0"
3237+
gcp-metadata "^7.0.0"
3238+
google-logging-utils "^1.0.0"
3239+
gtoken "^8.0.0"
3240+
jws "^4.0.0"
3241+
31663242
google-auth-library@^10.1.0:
31673243
version "10.2.1"
31683244
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-10.2.1.tgz#9d2513dd92d797cd058a1696011b0cd4f0213b50"
@@ -3988,6 +4064,14 @@ retry-request@^7.0.0:
39884064
extend "^3.0.2"
39894065
teeny-request "^9.0.0"
39904066

4067+
retry-request@^8.0.0:
4068+
version "8.0.2"
4069+
resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-8.0.2.tgz#c9b247b79e6347eb7cbae0cf5f1b981b87c29083"
4070+
integrity sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==
4071+
dependencies:
4072+
extend "^3.0.2"
4073+
teeny-request "^10.0.0"
4074+
39914075
retry@0.13.1:
39924076
version "0.13.1"
39934077
resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
@@ -4275,6 +4359,16 @@ symbol-tree@^3.2.4:
42754359
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
42764360
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
42774361

4362+
teeny-request@^10.0.0:
4363+
version "10.1.0"
4364+
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-10.1.0.tgz#02a4e246bd97e508c75342a5d83b64189ed851df"
4365+
integrity sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==
4366+
dependencies:
4367+
http-proxy-agent "^5.0.0"
4368+
https-proxy-agent "^5.0.0"
4369+
node-fetch "^3.3.2"
4370+
stream-events "^1.0.5"
4371+
42784372
teeny-request@^9.0.0:
42794373
version "9.0.0"
42804374
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-9.0.0.tgz#18140de2eb6595771b1b02203312dfad79a4716d"

0 commit comments

Comments
 (0)