Skip to content

Commit 0db611e

Browse files
committed
update main and add sample data
1 parent ed9b2fa commit 0db611e

File tree

5 files changed

+85
-60
lines changed

5 files changed

+85
-60
lines changed

sample-data/sample.json

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"id": "64ea4cc2d2a30b1df2401816",
3+
"index": 0,
4+
"guid": "0ae4cc55-adf6-48c9-865c-839eebeb3515",
5+
"accountBalance": "$3,280.97",
6+
"picture": "http://placehold.it/32x32",
7+
"age": 20,
8+
"eyeColor": "blue",
9+
"name": "Shaw Fulton",
10+
"profileInfo": {
11+
"gender": "male",
12+
"company": "LIMOZEN",
13+
"email": "[email protected]",
14+
"phone": "+1 (827) 443-2267",
15+
"address": "637 Guernsey Street, Driftwood, Missouri, 5848",
16+
"about": "Deserunt aliquip commodo minim qui qui non eiusmod nisi mollit veniam. Ullamco velit elit labore do aliqua et amet. Et ex quis voluptate laborum occaecat mollit. Adipisicing aliquip aliqua exercitation officia ex ex dolore id adipisicing ullamco.\r\n"
17+
},
18+
"otherDataPoints": {
19+
"registered": "2015-02-10T12:39:26 +08:00",
20+
"latitude": 32.667598,
21+
"longitude": 4.219472,
22+
"greeting": "Hello, Shaw Fulton! You have 3 unread messages.",
23+
"favoriteFruit": "banana"
24+
},
25+
"mixedInNestedObjects": {
26+
"isNormal": "i sure hope so",
27+
"whatItsAllAbout": "hokey-pokey",
28+
"funkyPlaceholder": {"favoritePhilosopher": "Kant", "shoeSize": 14.5},
29+
"corporateAlliances": {"centristEpicenter": "total", "garbageCollectionCycles": "Seasonal"},
30+
"steakhousePortaits": {"fieldGoal": 42, "campsiteWebsite": "dogetoutmore.com"}
31+
},
32+
"dogParkGeoJson": {
33+
"type": "FeatureCollection",
34+
"features": [
35+
{
36+
"type": "Feature",
37+
"id": 16,
38+
"geometry": {
39+
"type": "Polygon",
40+
"coordinates": [
41+
[
42+
[-32.667598, -4.239272],
43+
[-32.767999, -4.319272],
44+
[-32.687588, -4.649872],
45+
[-32.617548, -4.219892],
46+
[-32.622598, -4.159472],
47+
[-32.667533, -4.169472],
48+
[-32.567598, -4.789222],
49+
[-32.617191, -4.919373]
50+
]
51+
]
52+
}
53+
}
54+
]
55+
}
56+
}

src/index.spec.ts

+2-25
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,10 @@ import { main } from '.'
22

33
describe('main', () => {
44

5-
it('should log unknown command message if no command is passed', () => {
5+
it('should log error if no filepath is passed', () => {
66
process.argv = ['foo', 'bar']
77
console.log = jest.fn()
88
main()
9-
expect(console.log).toHaveBeenCalledWith('Unknown command: undefined')
10-
})
11-
12-
it('should log unknown command message if unknown command is passed', () => {
13-
process.argv = ['foo', 'bar', 'baz']
14-
console.log = jest.fn()
15-
main()
16-
expect(console.log).toHaveBeenCalledWith('Unknown command: baz')
17-
})
18-
19-
describe('hello', () => {
20-
it('should print hello world if no arguments are passed', () => {
21-
process.argv = ['foo', 'bar', 'hello']
22-
console.log = jest.fn()
23-
main()
24-
expect(console.log).toHaveBeenCalledWith('Hello world!')
25-
})
26-
27-
it('should print hello message with input argument', () => {
28-
process.argv = ['foo', 'bar', 'hello', 'charlie']
29-
console.log = jest.fn()
30-
main()
31-
expect(console.log).toHaveBeenCalledWith('Hello charlie')
32-
})
9+
expect(console.log).toHaveBeenCalled()
3310
})
3411
})

src/index.ts

+21-23
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
#!/usr/bin/env node
22

3+
import { readJsonFileContent, writeToStdOut } from "./io"
4+
import { jsonToSqlView } from "./parser"
5+
36
export const main = () => {
47
const args = process.argv.slice(2)
5-
const command = args[0]
8+
const inputFilePath = args[0]
9+
10+
if(!inputFilePath) {
11+
printHelp();
12+
return
13+
}
614

7-
switch (command) {
8-
case "hello":
9-
const helloArgs = args.slice(1)
10-
if (helloArgs[0]) {
11-
console.log(`Hello ${helloArgs[0]}`)
12-
} else {
13-
console.log(`Hello world!`)
14-
}
15-
break
16-
case "help":
17-
showHelp()
18-
default:
19-
console.log(`Unknown command: ${command}`)
15+
try {
16+
const fileContent = readJsonFileContent(inputFilePath)
17+
const sqlOutput = jsonToSqlView(fileContent)
18+
writeToStdOut(sqlOutput.parentSql)
19+
sqlOutput.childQueries.forEach(q => writeToStdOut(q))
20+
} catch(err) {
21+
console.log(err)
2022
}
2123
}
2224

23-
main();
25+
function printHelp() {
26+
const msg = `Error: no file path provided.\nUsage:\n\nnpx @nealwp/blobview <filepath>\n`
27+
console.log(msg)
28+
}
2429

25-
const showHelp = () => {
26-
console.log(`
27-
Available commands:
28-
29-
hello <name> prints a hello message
30-
help prints this message
30+
main();
3131

32-
`)
33-
}

src/parser.spec.ts

+5-10
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ describe('parser', () => {
1212
}
1313
}
1414

15-
const json = JSON.stringify(testObj)
1615
const expectedResult = ['SELECT\nCAST(JSON_VALUE(json_blob.topKey.nestedKey1) as INTEGER) as nested_key_1\n, CAST(JSON_VALUE(json_blob.topKey.nestedKey2) as STRING) as nested_key_2\n, CAST(JSON_VALUE(json_blob.topKey.nestedKey3) as DECIMAL) as nested_key_3\nFROM <project>.<datastream>.<dataset>']
17-
const output = jsonToSqlView(json)
16+
const output = jsonToSqlView(testObj)
1817
expect(output.childQueries).toEqual(expectedResult)
1918
})
2019

@@ -26,13 +25,12 @@ describe('parser', () => {
2625
topKey3: { nestedKey3: 3.14 }
2726
}
2827

29-
const json = JSON.stringify(testObj)
3028
const expectedResult = [
3129
'SELECT\nCAST(JSON_VALUE(json_blob.topKey1.nestedKey1) as STRING) as nested_key_1\nFROM <project>.<datastream>.<dataset>',
3230
'SELECT\nCAST(JSON_VALUE(json_blob.topKey2.nestedKey2) as INTEGER) as nested_key_2\nFROM <project>.<datastream>.<dataset>',
3331
'SELECT\nCAST(JSON_VALUE(json_blob.topKey3.nestedKey3) as DECIMAL) as nested_key_3\nFROM <project>.<datastream>.<dataset>',
3432
]
35-
const output = jsonToSqlView(json)
33+
const output = jsonToSqlView(testObj)
3634
expect(output.childQueries).toEqual(expectedResult)
3735
})
3836

@@ -42,9 +40,8 @@ describe('parser', () => {
4240
key2: 'abcd',
4341
key3: 3.14
4442
}
45-
const json = JSON.stringify(testObj)
4643
const expectedResult = 'SELECT\nCAST(JSON_VALUE(json_blob.key1) as INTEGER) as key_1\n, CAST(JSON_VALUE(json_blob.key2) as STRING) as key_2\n, CAST(JSON_VALUE(json_blob.key3) as DECIMAL) as key_3\nFROM <project>.<datastream>.<dataset>'
47-
const output = jsonToSqlView(json)
44+
const output = jsonToSqlView(testObj)
4845
expect(output.parentSql).toEqual(expectedResult)
4946
})
5047

@@ -59,18 +56,16 @@ describe('parser', () => {
5956
features: ["feature", "collection", "here"]
6057
}
6158
}
62-
const json = JSON.stringify(testObj)
6359
const expectedResult = 'SELECT\nTO_JSON_STRING(json_blob.geoJsonThing1) as geo_json_thing_1\n, TO_JSON_STRING(json_blob.geoJsonThing2) as geo_json_thing_2\nFROM <project>.<datastream>.<dataset>'
64-
const output = jsonToSqlView(json)
60+
const output = jsonToSqlView(testObj)
6561
expect(output.parentSql).toEqual(expectedResult)
6662
})
6763

6864
it('should json string deeply nested objects', () => {
6965
const testObj = { nestedKey: { deeplyNestedKey: { some: 'key' } } }
7066

71-
const json = JSON.stringify(testObj)
7267
const expectedResult = ['SELECT\nTO_JSON_STRING(json_blob.nestedKey.deeplyNestedKey) as deeply_nested_key\nFROM <project>.<datastream>.<dataset>']
73-
const output = jsonToSqlView(json)
68+
const output = jsonToSqlView(testObj)
7469
expect(output.childQueries).toEqual(expectedResult)
7570
})
7671
})

src/parser.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ export function snakeCase(str: string) {
4343
});
4444
}
4545

46-
export function jsonToSqlView(rawJson: string) {
47-
const json = JSON.parse(rawJson)
46+
export function jsonToSqlView(json: any) {
4847
const keys = Object.keys(json)
4948
const childQueries = [];
5049

0 commit comments

Comments
 (0)