Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1afa554

Browse files
authored
perf: improve speed of parsing (bendrucker#16)
1 parent 9e9ba83 commit 1afa554

File tree

1 file changed

+66
-74
lines changed

1 file changed

+66
-74
lines changed

index.js

Lines changed: 66 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,89 @@
11
'use strict'
22

33
exports.parse = function (source, transform) {
4-
return new ArrayParser(source, transform).parse()
4+
return parsePostgresArray(source, transform)
55
}
66

7-
class ArrayParser {
8-
constructor (source, transform) {
9-
this.source = source
10-
this.transform = transform || identity
11-
this.position = 0
12-
this.entries = []
13-
this.recorded = []
14-
this.dimension = 0
15-
}
7+
function parsePostgresArray (source, transform, nested = false) {
8+
let character = ''
9+
let quote = false
10+
let position = 0
11+
let dimension = 0
12+
const entries = []
13+
let recorded = ''
1614

17-
isEof () {
18-
return this.position >= this.source.length
19-
}
15+
const newEntry = function (includeEmpty) {
16+
let entry = recorded
2017

21-
nextCharacter () {
22-
const character = this.source[this.position++]
23-
if (character === '\\') {
24-
return {
25-
value: this.source[this.position++],
26-
escaped: true
18+
if (entry.length > 0 || includeEmpty) {
19+
if (entry === 'NULL' && !includeEmpty) {
20+
entry = null
2721
}
28-
}
29-
return {
30-
value: character,
31-
escaped: false
22+
23+
if (entry !== null && transform) {
24+
entry = transform(entry)
25+
}
26+
27+
entries.push(entry)
28+
recorded = ''
3229
}
3330
}
3431

35-
record (character) {
36-
this.recorded.push(character)
37-
}
32+
if (source[0] === '[') {
33+
while (position < source.length) {
34+
const char = source[position++]
3835

39-
newEntry (includeEmpty) {
40-
let entry
41-
if (this.recorded.length > 0 || includeEmpty) {
42-
entry = this.recorded.join('')
43-
if (entry === 'NULL' && !includeEmpty) {
44-
entry = null
45-
}
46-
if (entry !== null) entry = this.transform(entry)
47-
this.entries.push(entry)
48-
this.recorded = []
36+
if (char === '=') { break }
4937
}
5038
}
5139

52-
consumeDimensions () {
53-
if (this.source[0] === '[') {
54-
while (!this.isEof()) {
55-
const char = this.nextCharacter()
56-
if (char.value === '=') break
57-
}
40+
while (position < source.length) {
41+
let escaped = false
42+
character = source[position++]
43+
44+
if (character === '\\') {
45+
character = source[position++]
46+
escaped = true
5847
}
59-
}
6048

61-
parse (nested) {
62-
let character, parser, quote
63-
this.consumeDimensions()
64-
while (!this.isEof()) {
65-
character = this.nextCharacter()
66-
if (character.value === '{' && !quote) {
67-
this.dimension++
68-
if (this.dimension > 1) {
69-
parser = new ArrayParser(this.source.substr(this.position - 1), this.transform)
70-
this.entries.push(parser.parse(true))
71-
this.position += parser.position - 2
72-
}
73-
} else if (character.value === '}' && !quote) {
74-
this.dimension--
75-
if (!this.dimension) {
76-
this.newEntry()
77-
if (nested) return this.entries
49+
if (character === '{' && !quote) {
50+
dimension++
51+
52+
if (dimension > 1) {
53+
const parser = parsePostgresArray(source.substr(position - 1), transform, true)
54+
55+
entries.push(parser.entries)
56+
position += parser.position - 2
57+
}
58+
} else if (character === '}' && !quote) {
59+
dimension--
60+
61+
if (!dimension) {
62+
newEntry()
63+
64+
if (nested) {
65+
return {
66+
entries,
67+
position
68+
}
7869
}
79-
} else if (character.value === '"' && !character.escaped) {
80-
if (quote) this.newEntry(true)
81-
quote = !quote
82-
} else if (character.value === ',' && !quote) {
83-
this.newEntry()
84-
} else {
85-
this.record(character.value)
8670
}
71+
} else if (character === '"' && !escaped) {
72+
if (quote) {
73+
newEntry(true)
74+
}
75+
76+
quote = !quote
77+
} else if (character === ',' && !quote) {
78+
newEntry()
79+
} else {
80+
recorded += character
8781
}
88-
if (this.dimension !== 0) {
89-
throw new Error('array dimension not balanced')
90-
}
91-
return this.entries
9282
}
93-
}
9483

95-
function identity (value) {
96-
return value
84+
if (dimension !== 0) {
85+
throw new Error('array dimension not balanced')
86+
}
87+
88+
return entries
9789
}

0 commit comments

Comments
 (0)