-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.js
115 lines (99 loc) · 2.89 KB
/
mod.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
const escape = (value, delimiter) => (
delimiter +
String(value)
.replace(delimiter, delimiter + delimiter)
.replace(".", `${delimiter}.${delimiter}`) +
delimiter
);
class SqlStatement {
// target "" | "mysql" | "pgsql"
constructor(strings = [], values = [], target = "") {
let i = 0;
let query = "";
let params = [];
while (i < strings.length) {
query += strings[i];
if (i < values.length) {
// support nested tagged template literals
if (values[i] instanceof SqlStatement) {
query += values[i].query;
params = params.concat(values[i].params);
// escape sql identifiers
} else if (values[i] instanceof SqlIdentifier) {
const delimiter = target === "mysql" ? "`" : '"';
query += escape(values[i].toString(), delimiter);
// embed raw strings
} else if (values[i] instanceof SqlRawValue) {
query += values[i].toString();
// parametrize values
} else {
if (target === "pgsql") {
query += `\$${i + 1}`;
params.push(values[i]);
} else {
if (Array.isArray(values[i])) {
query += `(${values[i].map((_) => "?").join(", ")})`;
params.push(...values[i]);
} else {
query += "?";
params.push(values[i]);
}
}
}
}
i += 1;
}
this.query = query;
this.params = params;
}
append(statement) {
if (!(statement instanceof SqlStatement)) {
throw new Error("you can only append sql statements");
}
this.query += " " + statement.query;
this.params = this.params.concat(statement.params);
return this;
}
}
export function sql(strings, ...values) {
return new SqlStatement(strings, values);
}
export function mysql(strings, ...values) {
return new SqlStatement(strings, values, "mysql");
}
export function pgsql(strings, ...values) {
return new SqlStatement(strings, values, "pgsql");
}
class SqlValueWrapper {
constructor(value) {
this.value = value;
}
valueOf() {
return this.value;
}
toString() {
return String(this.value);
}
}
class SqlRawValue extends SqlValueWrapper {}
class SqlIdentifier extends SqlValueWrapper {}
sql.raw = (v) => new SqlRawValue(v);
sql.identifier = (v) => new SqlIdentifier(v);
sql.table = (v) => new SqlIdentifier(v);
sql.column = (v) => new SqlIdentifier(v);
// accepts a list of SqlStatement objects and a glue string
sql.join = (statements, glue = "") => {
let queries = [];
let values = [];
for (const s of statements) {
if (!(s instanceof SqlStatement)) {
throw new Error("you can only join sql statements");
}
queries = queries.concat(s.query);
values = values.concat(s.params);
}
const result = new SqlStatement();
result.query = queries.join(glue);
result.params = values;
return result;
};