Skip to content

Commit

Permalink
Allow multi line pretty print for long column
Browse files Browse the repository at this point in the history
  • Loading branch information
takegue committed Jan 21, 2024
1 parent 164ad70 commit 3377736
Showing 1 changed file with 91 additions and 20 deletions.
111 changes: 91 additions & 20 deletions bigquery/@default/v0/@routines/ztable_stringify/ddl.sql
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ const prettyPrintTable = (data) => {
}
const defaultFormetter = (val) => val ? val.toString() : "null"
// If long string is included, set allowMultiline to true
const allowMultiline = (() => {
for (const row of data) {
for (const key in row) {
const val = JSON.stringify(row[key])
if (val && val.length > 30) {
return true
}
}
}
return false
})();
const formatter = {
'INTEGER': defaultFormetter,
'FLOAT': defaultFormetter,
Expand All @@ -69,11 +82,10 @@ const prettyPrintTable = (data) => {
'TIME': defaultFormetter,
'DATETIME': defaultFormetter,
'TIMESTAMP': defaultFormetter,
'ARRAY': (val) => JSON.stringify(val),
'RECORD_OR_JSON': (val) => JSON.stringify(val),
'ARRAY': (val) => JSON.stringify(val, null, allowMultiline ? 2 : null),
'RECORD_OR_JSON': (val) => JSON.stringify(val, null, allowMultiline ? 2 : null),
};
const estimatedTypes = (() => {
const agg = data.reduce((acc, cur) => {
for (const key in cur) {
Expand All @@ -90,11 +102,16 @@ const prettyPrintTable = (data) => {
return Object.entries(agg).reduce((acc, [key, examples]) => {
const type = estimateTypeFromExamples(examples)
const typeLength = Math.max(
key.length + 2,
key.length + 3,
...examples.map((e) => {
const f = formatter[type] ;
const s = (f ? f : defaultFormetter)(e)
return s && s.length ? s.length + 2: null;
// Calculate max line length of string by delimited by new line
const len = (s.split("\n")).reduce((acc, cur) => {
const _new = cur && cur.length ? cur.length + 2: null
return acc < _new ? _new : acc ;
}, 0);
return len;
}));
acc[key] = {
type,
Expand All @@ -119,18 +136,36 @@ const prettyPrintTable = (data) => {
const f = formatter[estimated.type];
const formated = (f ? f : defaultFormetter)(value);
return `${formated} `.padStart(length, ' ')
return `${formated}`
}
const formatRow = (row) => {
return Object.entries(row).map(formatField).join(sep)
const formatedFields = Object.entries(row).map(formatField)
const fields = formatedFields.map(s => s.split('\n'))
// transpose fields aligned with longet elements of arary
// argmax of elemtens length
const longest = fields.reduce((acc, cur) => {
return acc.length < cur.length ? cur : acc ;
})
const transposedFields = longest.map((_, colIndex) => fields.map(row => row[colIndex] ?? ""))
return transposedFields.map((columns) => {
c = columns.map(
(c, colIndex) => {
const estimated = estimatedTypes[Object.keys(row)[colIndex]]
const length = estimated.typeLength
return ` ${c}`.padEnd(length, ' ')
}).join(sep)
return `|${c}|`
}).join('\n')
}
const table = [
`/*${headerSepRow.join(sepGrid).substring(1)}+`,
`|${headerRow.join(sep)}|`,
`+${headerSepRow.join(sepGrid)}+`,
...data.map((row) => {
return `|${formatRow(row)}|`
}),
data.map((row) => {
return `${formatRow(row)}`
}).join(`\n`),
`+${headerSepRow.join(sepGrid).substring(0)}*/`
].join('\n')
return table
Expand All @@ -141,24 +176,60 @@ const prettyPrintTable = (data) => {
const _test = () => {
const data = [
// long record
{"int":1,"str":"hoge","float":3.2,"boolean":null,"ts":null,"dt":null,"d":null,"json":{"int":null,"str":null,"float":null,"boolean":null,"ts":"2023-01-01T00:00:00Z","dt":"2023-01-01T00:00:00","d":"2023-01-01","json":null,"arr":[1,2],"record":{"int":1}},"arr":null,"record":null},
// short
{"int":1,"str":"hoge","float":3.2,"boolean":null,"ts":null,"dt":null,"d":null,"json":null,"arr":null,"record":null},
{"int":null,"str":null,"float":null,"boolean":null,"ts":"2023-01-01T00:00:00Z","dt":"2023-01-01T00:00:00","d":"2023-01-01","json":null,"arr":[1,2],"record":{"int":1}}
{"int":null,"str":null,"float":null,"boolean":null,"ts":"2023-01-01T00:00:00Z","dt":"2023-01-01T00:00:00","d":"2023-01-01","json":null,"arr":[1,2],"record":{"int":1}},
]
const ret = prettyPrintTable(data)
return ret === `
/*-----+--------+-------+---------+----------------------+---------------------+------------+------+-------+-----------+
| int | str | float | boolean | ts | dt | d | json | arr | record |
+------+--------+-------+---------+----------------------+---------------------+------------+------+-------+-----------+
| 1 | "hoge" | 3.2 | null | null | null | null | null | null | null |
| null | null | null | null | 2023-01-01T00:00:00Z | 2023-01-01T00:00:00 | 2023-01-01 | null | [1,2] | {"int":1} |
+------+--------+-------+---------+----------------------+---------------------+------------+------+-------+-----------*/
`.trim()
const ret1 = prettyPrintTable(data.slice(1,))
console.log({ret1, assert: ret1 === `
/*-----+--------+--------+----------+----------------------+---------------------+------------+-------+-------+-----------+
| int | str | float | boolean | ts | dt | d | json | arr | record |
+------+--------+--------+----------+----------------------+---------------------+------------+-------+-------+-----------+
| 1 | "hoge" | 3.2 | null | null | null | null | null | null | null |
| null | null | null | null | 2023-01-01T00:00:00Z | 2023-01-01T00:00:00 | 2023-01-01 | null | [1,2] | {"int":1} |
+------+--------+--------+----------+----------------------+---------------------+------------+-------+-------+-----------*/
`.trim()})
const ret2 = prettyPrintTable(data, true)
console.log({ret2, assert: ret2 === `
/*-----+--------+--------+----------+----------------------+---------------------+------------+---------------------------------+------+------------+
| int | str | float | boolean | ts | dt | d | json | arr | record |
+------+--------+--------+----------+----------------------+---------------------+------------+---------------------------------+------+------------+
| 1 | "hoge" | 3.2 | null | null | null | null | { | null | null |
| | | | | | | | "int": null, | | |
| | | | | | | | "str": null, | | |
| | | | | | | | "float": null, | | |
| | | | | | | | "boolean": null, | | |
| | | | | | | | "ts": "2023-01-01T00:00:00Z", | | |
| | | | | | | | "dt": "2023-01-01T00:00:00", | | |
| | | | | | | | "d": "2023-01-01", | | |
| | | | | | | | "json": null, | | |
| | | | | | | | "arr": [ | | |
| | | | | | | | 1, | | |
| | | | | | | | 2 | | |
| | | | | | | | ], | | |
| | | | | | | | "record": { | | |
| | | | | | | | "int": 1 | | |
| | | | | | | | } | | |
| | | | | | | | } | | |
| 1 | "hoge" | 3.2 | null | null | null | null | null | null | null |
| null | null | null | null | 2023-01-01T00:00:00Z | 2023-01-01T00:00:00 | 2023-01-01 | null | [ | { |
| | | | | | | | | 1, | "int": 1 |
| | | | | | | | | 2 | } |
| | | | | | | | | ] | |
+------+--------+--------+----------+----------------------+---------------------+------------+---------------------------------+------+------------*/
`.trim()})
}
// _test()
try {
return prettyPrintTable(JSON.parse(json_like_string))
}
catch {
return null;
}
""";

0 comments on commit 3377736

Please sign in to comment.