Skip to content

Commit efffa1e

Browse files
authored
Merge pull request #1970 from neo4j/triple-quotes-bug-fix
removing triple quotes from csv exports
2 parents 514f530 + ad88cb5 commit efffa1e

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

src/browser/modules/Stream/CypherFrame/CypherFrame.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ export class CypherFrame extends Component<CypherFrameProps, CypherFrameState> {
429429

430430
const exportData = stringifyResultArray(
431431
csvFormat,
432-
[keys].concat(records.map(record => recordToStringArray(record)))
432+
[keys].concat(records.map(record => recordToStringArray(record, true)))
433433
)
434434
const data = exportData.slice()
435435
const csv = CSVSerializer(data.shift())

src/browser/modules/Stream/CypherFrame/helpers.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,31 @@ describe('helpers', () => {
648648
// Then
649649
expect(res).toEqual([['"P1M2DT3.000000004S"']])
650650
})
651+
652+
test('recordToStringArray handles strings correctly when double quotes are disabled', () => {
653+
const records = [
654+
new Record(
655+
['x', 'y', 'n', 'z', '{}'],
656+
[
657+
'xRecord',
658+
neo4j.int(10),
659+
new neo4j.types.Duration(1, 2, 3, 4),
660+
new (neo4j.types.Node as any)('1', ['Person'], { prop1: 'prop1' }),
661+
{}
662+
]
663+
)
664+
]
665+
const res = records.map(record => recordToStringArray(record, true))
666+
expect(res).toEqual([
667+
[
668+
'xRecord',
669+
'10',
670+
'P1M2DT3.000000004S',
671+
'(:Person {prop1: prop1})',
672+
'{}'
673+
]
674+
])
675+
})
651676
})
652677

653678
describe('recordToJSONMapper', () => {

src/browser/modules/Stream/CypherFrame/helpers.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import neo4j, { Node, Path, Record, Relationship } from 'neo4j-driver'
3535
import bolt from 'services/bolt/bolt'
3636
import { recursivelyExtractGraphItems } from 'services/bolt/boltMappings'
3737
import { stringModifier } from 'services/bolt/cypherTypesFormatting'
38-
import { stringifyMod, unescapeDoubleQuotesForDisplay } from 'services/utils'
38+
import { stringifyMod } from 'services/utils'
3939
import * as viewTypes from 'shared/modules/frames/frameViewTypes'
4040
import { BrowserRequestResult } from 'shared/modules/requests/requestsDuck'
4141

@@ -231,14 +231,13 @@ export const initialView = (props: any, state: any = {}) => {
231231
*/
232232
export const stringifyResultArray = (
233233
formatter = stringModifier,
234-
arr: any[] = [],
235-
unescapeDoubleQuotes = false
234+
arr: any[] = []
236235
) => {
237236
return arr.map(col => {
238237
if (!col) return col
239238
return col.map((fVal: any) => {
240239
const res = stringifyMod(fVal, formatter)
241-
return unescapeDoubleQuotes ? unescapeDoubleQuotesForDisplay(res) : res
240+
return res
242241
})
243242
})
244243
}
@@ -423,7 +422,10 @@ function isNeo4jValue(value: any) {
423422
}
424423
}
425424

426-
export const recordToStringArray = (record: Record): string[] => {
425+
export const recordToStringArray = (
426+
record: Record,
427+
discardDoubleQuotes?: boolean
428+
): string[] => {
427429
const recursiveStringify = (value: CypherDataType): string => {
428430
if (Array.isArray(value)) {
429431
if (value.length === 0) return '[]'
@@ -432,7 +434,13 @@ export const recordToStringArray = (record: Record): string[] => {
432434

433435
if (isCypherPropertyType(value)) {
434436
//Note: later we should use propertyToString here but needs to be updated to show year in durations.
435-
return stringifyMod(value, stringModifier, true)
437+
return stringifyMod(
438+
value,
439+
(v: any) => stringModifier(v, discardDoubleQuotes),
440+
true,
441+
false,
442+
discardDoubleQuotes
443+
)
436444
}
437445

438446
// We have nodes, relationships, paths and cypher maps left.

src/shared/services/bolt/cypherTypesFormatting.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ export const csvFormat = (anything: any) => {
1919
return undefined
2020
}
2121

22-
export const stringModifier = (anything: any) => {
22+
export const stringModifier = (
23+
anything: any,
24+
discardDoubleQuotes?: boolean
25+
) => {
2326
if (typeof anything === 'number') {
2427
return numberFormat(anything)
2528
}
@@ -30,7 +33,9 @@ export const stringModifier = (anything: any) => {
3033
return spacialFormat(anything)
3134
}
3235
if (isTemporalType(anything)) {
33-
return `"${anything.toString()}"`
36+
return discardDoubleQuotes
37+
? anything.toString()
38+
: `"${anything.toString()}"`
3439
}
3540
return undefined
3641
}

src/shared/services/utils.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ export const stringifyMod = (
307307
value: any,
308308
modFn: any = null,
309309
pretty: boolean | number = false,
310-
skipOpeningIndentation = false
310+
skipOpeningIndentation = false,
311+
discardDoubleQuotes = false
311312
): string => {
312313
const prettyLevel = isNumber(pretty) ? pretty : +pretty
313314
const nextPrettyLevel = prettyLevel ? prettyLevel + 1 : false
@@ -386,7 +387,9 @@ export const stringifyMod = (
386387
)}${newLine}${endIndentation}}`
387388
}
388389
}
389-
return `${indentation}"${value.toString().replace(escRE, escFunc)}"`
390+
return discardDoubleQuotes
391+
? `${indentation}${value.toString().replace(escRE, escFunc)}`
392+
: `${indentation}"${value.toString().replace(escRE, escFunc)}"`
390393
}
391394

392395
export const unescapeDoubleQuotesForDisplay = (str: any) =>

0 commit comments

Comments
 (0)