1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.escapeLiteral = exports.escapeIdentifier = exports.SqlFragment = undefined;
|
7 | exports.sqlStr = sqlStr;
|
8 | exports.identifier = identifier;
|
9 | exports.literal = literal;
|
10 | exports.insert_object = insert_object;
|
11 |
|
12 | var _util = require('util');
|
13 |
|
14 | var _pg = require('pg');
|
15 |
|
16 | var _pg2 = _interopRequireDefault(_pg);
|
17 |
|
18 | var _utils = require('pg/lib/utils');
|
19 |
|
20 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21 |
|
22 | let SQL;
|
23 |
|
24 | class SqlFragment {
|
25 |
|
26 |
|
27 | constructor(templateParts, templateValues) {
|
28 | this._parts = [];
|
29 | this.values = [];
|
30 |
|
31 | const length = templateValues.length;
|
32 | const text = [];
|
33 | let currentFragment = [];
|
34 | let argIndex = 1;
|
35 |
|
36 | let i = 0;
|
37 |
|
38 | const addText = str => {
|
39 | currentFragment.push(str);
|
40 | };
|
41 |
|
42 | const flushText = () => {
|
43 | const fragment = currentFragment.join('');
|
44 | currentFragment = [];
|
45 | this._parts.push(fragment);
|
46 | text.push(fragment);
|
47 | };
|
48 |
|
49 | const addValue = value => {
|
50 | flushText();
|
51 | this.values.push(value);
|
52 | text.push('$', argIndex++);
|
53 | };
|
54 |
|
55 | while (i < length) {
|
56 | const parts = templateParts[i].split('$');
|
57 | let value = templateValues.shift();
|
58 | if (typeof value === 'undefined') throw new Error(`Expected something, but got undefined. ` + `Value after SQL fragment: ${ text.join('') }${ templateParts[i] }`);
|
59 |
|
60 | while (parts.length > 1) value = SQL.transform(parts.pop(), value);
|
61 |
|
62 | addText(parts[0]);
|
63 |
|
64 | if (value && value.toSQL) value = value.toSQL();
|
65 |
|
66 | if (value instanceof SqlFragment) {
|
67 | const nestedValuesLength = value.values.length;
|
68 | let valueIndex = 0;
|
69 | while (valueIndex < nestedValuesLength) {
|
70 | addText(value._parts[valueIndex]);
|
71 | addValue(value.values[valueIndex]);
|
72 | valueIndex++;
|
73 | }
|
74 | addText(value._parts[valueIndex]);
|
75 | } else {
|
76 | addValue(value);
|
77 | }
|
78 | i++;
|
79 | }
|
80 |
|
81 | addText(templateParts[i]);
|
82 | flushText();
|
83 |
|
84 | this.text = text.join('');
|
85 | }
|
86 |
|
87 |
|
88 | toString() {
|
89 | if (this._asString) return this._asString;
|
90 |
|
91 | const text = [];
|
92 | const length = this.values.length;
|
93 | let i = 0;
|
94 | while (i < length) {
|
95 | text.push(this._parts[i]);
|
96 | const value = literal(this.values[i]);
|
97 | text.push(value);
|
98 | i++;
|
99 | }
|
100 | text.push(this._parts[i]);
|
101 | this._asString = text.join('');
|
102 | return this._asString;
|
103 | }
|
104 | }
|
105 |
|
106 | exports.SqlFragment = SqlFragment;
|
107 | SQL = function SQL(parts) {
|
108 | for (var _len = arguments.length, values = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
109 | values[_key - 1] = arguments[_key];
|
110 | }
|
111 |
|
112 |
|
113 |
|
114 | if (!Array.isArray(parts) && values.length === 0) {
|
115 | if (parts instanceof SqlFragment) return parts;
|
116 |
|
117 | parts = [parts];
|
118 | }
|
119 |
|
120 | return new SqlFragment(parts, values);
|
121 | };
|
122 |
|
123 | SQL.NULL = SQL('NULL');
|
124 | SQL.DEFAULT = SQL('DEFAULT');
|
125 |
|
126 | SQL._transforms = {};
|
127 | SQL.registerTransform = function () {
|
128 | for (var _len2 = arguments.length, names = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
129 | names[_key2] = arguments[_key2];
|
130 | }
|
131 |
|
132 | const transform = names.pop();
|
133 | if (typeof transform !== 'function') throw new Error('Last argument must be a function');
|
134 |
|
135 | const transforms = SQL._transforms;
|
136 | for (let i = 0; i < names.length; i++) {
|
137 | const name = names[i].trim().toLowerCase();
|
138 | if (transforms[name] && transforms[name] !== transform) throw new Error(`Transform ${ name } already registered`);
|
139 | transforms[names[i].toLowerCase()] = transform;
|
140 | }
|
141 | };
|
142 |
|
143 | SQL.transform = (name, value) => {
|
144 | name = name.trim().toLowerCase();
|
145 | const transform = SQL._transforms[name];
|
146 | if (!transform) throw new Error(`Unknown transform: "${ name }"`);
|
147 | return transform(value);
|
148 | };
|
149 |
|
150 | const escapeIdentifier = exports.escapeIdentifier = _pg2.default.Client.prototype.escapeIdentifier;
|
151 | const escapeLiteral = exports.escapeLiteral = _pg2.default.Client.prototype.escapeLiteral;
|
152 |
|
153 | function sqlStr(str) {
|
154 | if (typeof str !== 'string') throw new Error(`Expected string, got ${ (0, _util.inspect)(str) }`);
|
155 |
|
156 | return SQL(str);
|
157 | }
|
158 |
|
159 |
|
160 | function identifier(name) {
|
161 | if (!name) throw new Error(`Expected nonempty string, got ${ (0, _util.inspect)(name) }`);
|
162 |
|
163 | return SQL(escapeIdentifier(name));
|
164 | }
|
165 |
|
166 |
|
167 | function literal(value) {
|
168 | if (value instanceof SqlFragment) return value;
|
169 |
|
170 | if (typeof value === 'undefined') throw new Error(`Expected something, but got undefined.`);
|
171 |
|
172 | if (value === null) return SQL.NULL;
|
173 |
|
174 | if (value.toPostgres) return SQL(escapeLiteral(value.toPostgres(_utils.prepareValue)));
|
175 |
|
176 | if (value.toSQL) return SQL(value.toSQL());
|
177 |
|
178 | return SQL(escapeLiteral(value.toString()));
|
179 | }
|
180 |
|
181 | function insert_object(data) {
|
182 | const keys = Object.keys(data);
|
183 | const length = keys.length;
|
184 | const sqlFragments = new Array(length);
|
185 | const values = new Array(length - 1);
|
186 | const sb = [];
|
187 |
|
188 | sb.push('(');
|
189 | let i = 0;
|
190 | while (i < length) {
|
191 | const column = keys[i];
|
192 | values[i] = data[column];
|
193 | i++;
|
194 | sb.push(escapeIdentifier(column), ',');
|
195 | sqlFragments[i] = ',';
|
196 | }
|
197 | sb[sb.length - 1] = ') VALUES (';
|
198 | sqlFragments[0] = sb.join('');
|
199 | sqlFragments[i] = ')';
|
200 |
|
201 | return new SqlFragment(sqlFragments, values);
|
202 | }
|
203 |
|
204 | SQL.registerTransform('id', 'ident', 'identifier', 'name', identifier);
|
205 | SQL.registerTransform('', 'literal', literal);
|
206 | SQL.registerTransform('!', 'raw', sqlStr);
|
207 | SQL.registerTransform('insert_object', 'insert', insert_object);
|
208 |
|
209 | exports.default = SQL; |
\ | No newline at end of file |