-
Notifications
You must be signed in to change notification settings - Fork 14
/
util.js
127 lines (106 loc) · 3.05 KB
/
util.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
exports.updateSpecialKeys = ['$currentDate', '$inc', '$min', '$max', '$mul', '$rename', '$set', '$setOnInsert', '$unset', '$push', '$pull', '$pullAll', '$addToSet']
exports.countUpdateSpecialKeys = function(doc) {
return Object.keys(doc).filter(function(n) {
return exports.updateSpecialKeys.includes(n)
}).length
}
function quoteReplacer(key, value) {
if (typeof value == 'string') {
return exports.stringEscape(value)
}
return value
}
exports.quote = function(data) {
if (typeof data == 'string')
return '\'' + exports.stringEscape(data) + '\''
return '\''+JSON.stringify(data)+'\'::jsonb'
}
exports.quote2 = function(data) {
if (typeof data == 'string')
return '\'"' + exports.stringEscape(data) + '"\''
return '\''+JSON.stringify(data, quoteReplacer)+'\'::jsonb'
}
exports.stringEscape = function(str) {
return str.replace(/'/g, '\'\'')
}
exports.pathToText = function(path, isString) {
var text = exports.stringEscape(path[0])
if (isString && path.length === 1) {
return text + ' #>>\'{}\''
}
for (var i = 1; i < path.length; i++) {
text += (i == path.length-1 && isString ? '->>' : '->')
if (/^\d+$/.test(path[i]))
text += path[i] //don't wrap numbers in quotes
else
text += '\'' + exports.stringEscape(path[i]) + '\''
}
return text
}
exports.pathToObject = function(path) {
if (path.length === 1) {
return exports.quote2(path[0])
}
return '\'' + exports.pathToObjectHelper(path) + '\''
}
exports.pathToObjectHelper = function(path) {
if (path.length === 1) {
if (typeof path[0] == 'string') {
return `"${path[0]}"`
} else {
return JSON.stringify(path[0])
}
}
const [head, ...tail] = path
return `{ "${head}": ${exports.pathToObjectHelper(tail)} }`
}
exports.convertDotNotation = function(path, pathDotNotation) {
return exports.pathToText([path].concat(pathDotNotation.split('.')), true)
}
exports.toPostgresPath = function(path) {
return '\'{' + path.join(',') + '}\''
}
exports.toNumeric = function(path) {
return 'COALESCE(Cast(' + path + ' as numeric),0)'
}
const typeMapping = {
1: 'number',
2: 'string',
3: 'object',
4: 'array',
8: 'boolean',
10: 'null',
16: 'number',
18: 'number',
19: 'number'
}
exports.getPostgresTypeName = function(type) {
if (!['string', 'number'].includes(typeof type)) {
throw { errmsg: 'argument to $type is not a number or a string', code: 14 }
}
return typeMapping[type] || type
}
function isIntegerStrict(val) {
return val != 'NaN' && parseInt(val).toString() == val
}
exports.getPathSortedArray = function(keys) {
return keys.sort((a, b) => {
if (a == b) {
return 0
}
var aArr = a.split('.')
var bArr = b.split('.')
for (var i = 0; i < aArr.length; i++) {
if (i >= bArr.length) {
return -1
}
if (aArr[i] == bArr[i]) {
continue
}
var aItem = isIntegerStrict(aArr[i]) ? parseInt(aArr[i]) : aArr[i]
var bItem = isIntegerStrict(bArr[i]) ? parseInt(bArr[i]) : bArr[i]
return aItem > bItem ? -1 : 1
}
return 1
})
}