Skip to content

Commit 16bd3bf

Browse files
authored
Merge pull request #1 from nealwp/updates
Updates
2 parents 5dbce01 + 714804a commit 16bd3bf

8 files changed

+197
-38
lines changed

README.md

+60-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@ This CLI tool reads a JSON file and produces BigQuery compatible SQL views from
1010
## Usage
1111

1212
```bash
13-
npx @nealwp/blobview <filepath>
13+
npx @nealwp/blobview@latest [options] <filepath>
14+
```
15+
16+
```text
17+
Arguments:
18+
filepath path to valid JSON file
19+
20+
Options:
21+
-t TABLE, --table=TABLE specify a table name to use in FROM clause. default: "<table>"
22+
-d DATASET, --dataset=DATASET specify a dataset to use in FROM clause. default: "<dataset>"
23+
-h, --help show help
1424
```
1525

1626
## Examples:
@@ -19,9 +29,16 @@ Default output to STDOUT:
1929
npx @nealwp/blobview ./path/to/file.json
2030
```
2131

32+
Dataset and table as input options:
33+
```bash
34+
npx @nealwp/blobview --dataset=myDataset --table=myTable ./path/to/file.json
35+
# shorthand options
36+
npx @nealwp/blobview -d myDataset -t myTable ./path/to/file.json
37+
```
38+
2239
Redirect output to file:
2340
```bash
24-
npx @nealwp/blobview ./path/to/file.json > my-view-file.sql
41+
npx @nealwp/blobview@latest ./path/to/file.json > my-view-file.sql
2542
```
2643

2744
## Features
@@ -32,6 +49,7 @@ npx @nealwp/blobview ./path/to/file.json > my-view-file.sql
3249
* Auto-formats column names to snake_case from camelCase and PascalCase
3350
* Detects deeply-nested objects and formats to JSON string
3451
* Pre-populates FROM clause with BigQuery-style placeholders
52+
* BigQuery dataset and table name can be supplied as input options
3553

3654
## Limitations
3755
* Does not detect DATE or TIMESTAMP types, or other types like BOOLEAN
@@ -40,7 +58,7 @@ npx @nealwp/blobview ./path/to/file.json > my-view-file.sql
4058
* Does not create SQL views in any syntax other than BigQuery
4159
* Requires a local JSON file to read
4260
* Does not include option to write queries to separate files instead of STDOUT
43-
* BigQuery project, dataset, and datastream names cannot be supplied as input
61+
* BigQuery project name cannot be supplied as input
4462

4563
## Example Output
4664

@@ -100,20 +118,52 @@ SELECT
100118
, CAST(JSON_VALUE(json_blob.integerField) as INTEGER) as integer_field
101119
, CAST(JSON_VALUE(json_blob.decimalField) as DECIMAL) as decimal_field
102120
, TO_JSON_STRING(json_blob.exampleGeoJson) as example_geo_json
103-
FROM <project>.<datastream>.<dataset>
104-
--------
121+
FROM <project>.<dataset>.<table>
122+
/**/
123+
SELECT
124+
CAST(JSON_VALUE(json_blob.childField1.gender) as STRING) as gender
125+
, CAST(JSON_VALUE(json_blob.childField1.latitude) as DECIMAL) as latitude
126+
FROM <project>.<dataset>.<table>
127+
/**/
128+
SELECT
129+
CAST(JSON_VALUE(json_blob.childField2.favoriteFruit) as STRING) as favorite_fruit
130+
, CAST(JSON_VALUE(json_blob.childField2.longitude) as DECIMAL) as longitude
131+
FROM <project>.<dataset>.<table>
132+
/**/
133+
SELECT
134+
CAST(JSON_VALUE(json_blob.childWithNestedObject.isNormal) as STRING) as is_normal
135+
, TO_JSON_STRING(json_blob.childWithNestedObject.nestedObject) as nested_object
136+
FROM <project>.<dataset>.<table>
137+
```
138+
139+
```bash
140+
# terminal command with input options
141+
npx @nealwp/blobview --dataset=myDataset --table=myTable sample-data.json
142+
```
143+
144+
Will produce the following output:
145+
146+
```sql
147+
/* stdout */
148+
SELECT
149+
CAST(JSON_VALUE(json_blob.stringField) as STRING) as string_field
150+
, CAST(JSON_VALUE(json_blob.integerField) as INTEGER) as integer_field
151+
, CAST(JSON_VALUE(json_blob.decimalField) as DECIMAL) as decimal_field
152+
, TO_JSON_STRING(json_blob.exampleGeoJson) as example_geo_json
153+
FROM <project>.myDataset.myTable
154+
/**/
105155
SELECT
106156
CAST(JSON_VALUE(json_blob.childField1.gender) as STRING) as gender
107157
, CAST(JSON_VALUE(json_blob.childField1.latitude) as DECIMAL) as latitude
108-
FROM <project>.<datastream>.<dataset>
109-
--------
158+
FROM <project>.myDataset.myTable
159+
/**/
110160
SELECT
111161
CAST(JSON_VALUE(json_blob.childField2.favoriteFruit) as STRING) as favorite_fruit
112162
, CAST(JSON_VALUE(json_blob.childField2.longitude) as DECIMAL) as longitude
113-
FROM <project>.<datastream>.<dataset>
114-
--------
163+
FROM <project>.myDataset.myTable
164+
/**/
115165
SELECT
116166
CAST(JSON_VALUE(json_blob.childWithNestedObject.isNormal) as STRING) as is_normal
117167
, TO_JSON_STRING(json_blob.childWithNestedObject.nestedObject) as nested_object
118-
FROM <project>.<datastream>.<dataset>
168+
FROM <project>.myDataset.myTable
119169
```

package-lock.json

+17-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nealwp/blobview",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "Generate BigQuery SQL views from JSON",
55
"bin": {
66
"@nealwp/blobview": "./index.js"
@@ -23,6 +23,7 @@
2323
"license": "ISC",
2424
"devDependencies": {
2525
"@types/jest": "^29.5.0",
26+
"@types/minimist": "^1.2.2",
2627
"@typescript-eslint/eslint-plugin": "^5.57.1",
2728
"@typescript-eslint/parser": "^5.57.1",
2829
"copyfiles": "^2.4.1",
@@ -36,5 +37,8 @@
3637
"ts-jest": "^29.1.0",
3738
"ts-node": "^10.9.1",
3839
"typescript": "^5.0.3"
40+
},
41+
"dependencies": {
42+
"minimist": "^1.2.8"
3943
}
4044
}

src/index.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ describe('main', () => {
55
it('should log error if no filepath is passed', () => {
66
process.argv = ['foo', 'bar']
77
console.log = jest.fn()
8-
main()
8+
const args = {_: []}
9+
main(args)
910
expect(console.log).toHaveBeenCalled()
1011
})
1112
})

src/index.ts

+50-8
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,72 @@
11
#!/usr/bin/env node
22

3+
import minimist from 'minimist'
34
import { readJsonFileContent, writeToStdOut } from "./io"
45
import { jsonToSqlView } from "./parser"
56

6-
export const main = () => {
7-
const args = process.argv.slice(2)
8-
const inputFilePath = args[0]
7+
export const main = (args: minimist.ParsedArgs) => {
8+
const inputFilePath = args._[0]
9+
10+
let table = '<table>'
11+
let dataset = '<dataset>'
912

13+
if(args.help || args.h) {
14+
printHelp()
15+
return
16+
}
17+
1018
if(!inputFilePath) {
11-
printHelp();
19+
printError("No file path provided!");
1220
return
1321
}
1422

23+
if (args.table) {
24+
table = args.table
25+
} else if (args.t) {
26+
table = args.t
27+
}
28+
29+
if (args.dataset) {
30+
dataset = args.dataset
31+
} else if (args.d) {
32+
dataset = args.d
33+
}
34+
1535
try {
1636
const fileContent = readJsonFileContent(inputFilePath)
17-
const sqlOutput = jsonToSqlView(fileContent)
37+
const sqlOutput = jsonToSqlView(fileContent, {table, dataset})
1838
writeToStdOut(sqlOutput)
1939
} catch(err) {
2040
console.log(err)
2141
}
2242
}
2343

2444
function printHelp() {
25-
const msg = `Error: no file path provided.\nUsage:\n\nnpx @nealwp/blobview <filepath>\n`
26-
console.log(msg)
45+
const helpText = `Generate BigQuery SQL views from JSON.
46+
47+
Usage:
48+
@nealwp/blobview [options] <filepath>
49+
50+
Arguments:
51+
filepath path to valid JSON file
52+
53+
Options:
54+
-t TABLE, --table=TABLE specify a table name to use in FROM clause. default: "<table>"
55+
-d DATASET, --dataset=DATASET specify a dataset to use in FROM clause. default: "<dataset>"
56+
-h, --help show help`
57+
58+
console.log(helpText)
2759
}
2860

29-
main();
61+
function printError(message: string) {
62+
console.log(`Error: ${message}`)
63+
console.log('Run "@nealwp/blobview --help" to display help.')
64+
}
65+
66+
const args = minimist(process.argv.slice(2), {
67+
stopEarly: true,
68+
boolean: false
69+
})
70+
71+
main(args);
3072

src/io.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function readJsonFileContent(path: string) {
88
export function writeToStdOut(data: {parentSql: string, childQueries: string[]}) {
99
console.log(data.parentSql)
1010
data.childQueries.forEach(q => {
11-
console.log("--------")
11+
console.log("/**/")
1212
console.log(q)
1313
})
1414
}

0 commit comments

Comments
 (0)