CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/database/pool/multi-insert.ts
Views: 687
1
/*
2
The pg driver doesn't support inserting multiple rows in a single
3
query. There is a simple workaround at
4
5
https://github.com/brianc/node-postgres/issues/957#issuecomment-426852393
6
7
which I think would work for up to 100000/n rows, n is the number of values.
8
I copied it here.
9
10
Example:
11
12
var videos = [["Peru is a nice country.", "limaGuy"], ["Breaking bad is a great show.", "mikeGuy"], ["I like the winter.", "novemberGuy"]]
13
14
Query(
15
`INSERT INTO videos (title, author) VALUES ${expand(videos.length, 2)}`,
16
flatten(videos)
17
)
18
*/
19
20
// expand(3, 2) returns "($1, $2), ($3, $4), ($5, $6)"
21
function expand(rowCount: number, columnCount: number, startAt = 1): string {
22
let index = startAt;
23
return Array(rowCount)
24
.fill(0)
25
.map(
26
() =>
27
`(${Array(columnCount)
28
.fill(0)
29
.map(() => `$${index++}`)
30
.join(", ")})`
31
)
32
.join(", ");
33
}
34
35
// flatten([[1, 2], [3, 4]]) returns [1, 2, 3, 4]
36
function flatten(arr: any[][]): any[] {
37
const newArr: any[] = [];
38
arr.forEach((v) => v.forEach((p) => newArr.push(p)));
39
return newArr;
40
}
41
42
export default function format(
43
query: string, // the usual query, but without the VALUES part, e.g., "INSERT INTO videos (title, author)".
44
values: any[][] // the values as an array of arrays (the rows)
45
): { query: string; values: any[] } {
46
return {
47
query: `${query} VALUES ${expand(values.length, values?.[0].length ?? 0)}`,
48
values: flatten(values),
49
};
50
}
51
52