Skip to content

Commit 54cf1ae

Browse files
committed
build
1 parent 42cccb1 commit 54cf1ae

File tree

6 files changed

+46
-32
lines changed

6 files changed

+46
-32
lines changed

cjs/src/connection.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const tls = require('tls')
33
const crypto = require('crypto')
44
const Stream = require('stream')
55

6-
const { stringify, handleValue, arrayParser, arraySerializer } = require('./types.js')
6+
const { serialize, stringify, handleValue, arrayParser, arraySerializer } = require('./types.js')
77
const { Errors } = require('./errors.js')
88
const Result = require('./result.js')
99
const Queue = require('./queue.js')
@@ -180,7 +180,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
180180
throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
181181

182182
return q.options.simple
183-
? b().Q().str(q.strings[0] + b.N).end()
183+
? b().Q().str(q.statement.string + b.N).end()
184184
: q.describeFirst
185185
? Buffer.concat([describe(q), Flush])
186186
: q.prepare
@@ -912,7 +912,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
912912
type = types[i]
913913
parameters[i] = x = type in options.serializers
914914
? options.serializers[type](x)
915-
: '' + x
915+
: serialize(x)
916916

917917
prev = b.i
918918
b.inc(4).str(x).i32(b.i - prev - 4, prev)

cjs/src/types.js

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
const { Query } = require('./query.js')
22
const { Errors } = require('./errors.js')
33

4+
const serialize = module.exports.serialize = function serialize(x) {
5+
return typeof x === 'string' ? x :
6+
x instanceof Date ? types.date.serialize(x) :
7+
x instanceof Uint8Array ? types.bytea.serialize(x) :
8+
(x === true || x === false) ? types.boolean.serialize(x) :
9+
'' + x
10+
}
11+
412
const types = module.exports.types = {
513
string: {
614
to: 25,
715
from: null, // defaults to string
8-
serialize: x => '' + x
16+
serialize
917
},
1018
number: {
1119
to: 0,
@@ -66,10 +74,9 @@ const Builder = module.exports.Builder = class Builder extends NotTagged {
6674

6775
build(before, parameters, types, options) {
6876
const keyword = builders.map(([x, fn]) => ({ fn, i: before.search(x) })).sort((a, b) => a.i - b.i).pop()
69-
if (keyword.i === -1)
70-
throw new Error('Could not infer helper mode')
71-
72-
return keyword.fn(this.first, this.rest, parameters, types, options)
77+
return keyword.i === -1
78+
? escapeIdentifiers(this.first, options)
79+
: keyword.fn(this.first, this.rest, parameters, types, options)
7380
}
7481
}
7582

@@ -137,7 +144,7 @@ function values(first, rest, parameters, types, options) {
137144
function select(first, rest, parameters, types, options) {
138145
typeof first === 'string' && (first = [first].concat(rest))
139146
if (Array.isArray(first))
140-
return first.map(x => escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x)).join(',')
147+
return escapeIdentifiers(first, options)
141148

142149
let value
143150
const columns = rest.length ? rest.flat() : Object.keys(first)
@@ -170,9 +177,7 @@ const builders = Object.entries({
170177

171178
insert(first, rest, parameters, types, options) {
172179
const columns = rest.length ? rest.flat() : Object.keys(Array.isArray(first) ? first[0] : first)
173-
return '(' + columns.map(x =>
174-
escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x)
175-
).join(',') + ')values' +
180+
return '(' + escapeIdentifiers(columns, options) + ')values' +
176181
valuesBuilder(Array.isArray(first) ? first : [first], parameters, types, columns, options)
177182
}
178183
}).map(([x, fn]) => ([new RegExp('((?:^|[\\s(])' + x + '(?:$|[\\s(]))(?![\\s\\S]*\\1)', 'i'), fn]))
@@ -209,16 +214,18 @@ function typeHandlers(types) {
209214
}, { parsers: {}, serializers: {} })
210215
}
211216

217+
function escapeIdentifiers(xs, { transform: { column } }) {
218+
return xs.map(x => escapeIdentifier(column.to ? column.to(x) : x)).join(',')
219+
}
220+
212221
const escapeIdentifier = module.exports.escapeIdentifier = function escape(str) {
213222
return '"' + str.replace(/"/g, '""').replace(/\./g, '"."') + '"'
214223
}
215224

216225
const inferType = module.exports.inferType = function inferType(x) {
217226
return x instanceof Parameter
218227
? x.type
219-
: Array.isArray(x)
220-
? inferType(x[0])
221-
: 0
228+
: 0
222229
}
223230

224231
const escapeBackslash = /\\/g

cjs/tests/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ t('Point type array', async() => {
483483
})
484484

485485
await sql`create table test (x point[])`
486-
await sql`insert into test (x) values (${ sql.array([sql.types.point([10, 20]), sql.types.point([20, 30])]) })`
486+
await sql`insert into test (x) values (${ [sql.types.point([10, 20]), sql.types.point([20, 30])] })`
487487
return [30, (await sql`select x from test`)[0].x[1][1], await sql`drop table test`]
488488
})
489489

deno/src/connection.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { tls } from '../polyfills.js'
77
import crypto from 'https://deno.land/[email protected]/node/crypto.ts'
88
import Stream from 'https://deno.land/[email protected]/node/stream.ts'
99

10-
import { stringify, handleValue, arrayParser, arraySerializer } from './types.js'
10+
import { serialize, stringify, handleValue, arrayParser, arraySerializer } from './types.js'
1111
import { Errors } from './errors.js'
1212
import Result from './result.js'
1313
import Queue from './queue.js'
@@ -184,7 +184,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
184184
throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
185185

186186
return q.options.simple
187-
? b().Q().str(q.strings[0] + b.N).end()
187+
? b().Q().str(q.statement.string + b.N).end()
188188
: q.describeFirst
189189
? Buffer.concat([describe(q), Flush])
190190
: q.prepare
@@ -916,7 +916,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
916916
type = types[i]
917917
parameters[i] = x = type in options.serializers
918918
? options.serializers[type](x)
919-
: '' + x
919+
: serialize(x)
920920

921921
prev = b.i
922922
b.inc(4).str(x).i32(b.i - prev - 4, prev)

deno/src/types.js

+19-12
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ import { Buffer } from 'https://deno.land/[email protected]/node/buffer.ts'
22
import { Query } from './query.js'
33
import { Errors } from './errors.js'
44

5+
export const serialize = function serialize(x) {
6+
return typeof x === 'string' ? x :
7+
x instanceof Date ? types.date.serialize(x) :
8+
x instanceof Uint8Array ? types.bytea.serialize(x) :
9+
(x === true || x === false) ? types.boolean.serialize(x) :
10+
'' + x
11+
}
12+
513
export const types = {
614
string: {
715
to: 25,
816
from: null, // defaults to string
9-
serialize: x => '' + x
17+
serialize
1018
},
1119
number: {
1220
to: 0,
@@ -67,10 +75,9 @@ export class Builder extends NotTagged {
6775

6876
build(before, parameters, types, options) {
6977
const keyword = builders.map(([x, fn]) => ({ fn, i: before.search(x) })).sort((a, b) => a.i - b.i).pop()
70-
if (keyword.i === -1)
71-
throw new Error('Could not infer helper mode')
72-
73-
return keyword.fn(this.first, this.rest, parameters, types, options)
78+
return keyword.i === -1
79+
? escapeIdentifiers(this.first, options)
80+
: keyword.fn(this.first, this.rest, parameters, types, options)
7481
}
7582
}
7683

@@ -138,7 +145,7 @@ function values(first, rest, parameters, types, options) {
138145
function select(first, rest, parameters, types, options) {
139146
typeof first === 'string' && (first = [first].concat(rest))
140147
if (Array.isArray(first))
141-
return first.map(x => escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x)).join(',')
148+
return escapeIdentifiers(first, options)
142149

143150
let value
144151
const columns = rest.length ? rest.flat() : Object.keys(first)
@@ -171,9 +178,7 @@ const builders = Object.entries({
171178

172179
insert(first, rest, parameters, types, options) {
173180
const columns = rest.length ? rest.flat() : Object.keys(Array.isArray(first) ? first[0] : first)
174-
return '(' + columns.map(x =>
175-
escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x)
176-
).join(',') + ')values' +
181+
return '(' + escapeIdentifiers(columns, options) + ')values' +
177182
valuesBuilder(Array.isArray(first) ? first : [first], parameters, types, columns, options)
178183
}
179184
}).map(([x, fn]) => ([new RegExp('((?:^|[\\s(])' + x + '(?:$|[\\s(]))(?![\\s\\S]*\\1)', 'i'), fn]))
@@ -210,16 +215,18 @@ function typeHandlers(types) {
210215
}, { parsers: {}, serializers: {} })
211216
}
212217

218+
function escapeIdentifiers(xs, { transform: { column } }) {
219+
return xs.map(x => escapeIdentifier(column.to ? column.to(x) : x)).join(',')
220+
}
221+
213222
export const escapeIdentifier = function escape(str) {
214223
return '"' + str.replace(/"/g, '""').replace(/\./g, '"."') + '"'
215224
}
216225

217226
export const inferType = function inferType(x) {
218227
return x instanceof Parameter
219228
? x.type
220-
: Array.isArray(x)
221-
? inferType(x[0])
222-
: 0
229+
: 0
223230
}
224231

225232
const escapeBackslash = /\\/g

deno/tests/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ t('Point type array', async() => {
485485
})
486486

487487
await sql`create table test (x point[])`
488-
await sql`insert into test (x) values (${ sql.array([sql.types.point([10, 20]), sql.types.point([20, 30])]) })`
488+
await sql`insert into test (x) values (${ [sql.types.point([10, 20]), sql.types.point([20, 30])] })`
489489
return [30, (await sql`select x from test`)[0].x[1][1], await sql`drop table test`]
490490
})
491491

0 commit comments

Comments
 (0)