1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var BaseDialect, Delete, Insert, MySQLDialect, PostgresDialect, SQLite3Dialect, Select, Update, keywords, kwFile, read, _ref,
|
10 | __hasProp = {}.hasOwnProperty,
|
11 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
12 |
|
13 | read = require('fs').readFileSync;
|
14 |
|
15 | kwFile = __dirname + '/sql_keywords.txt';
|
16 |
|
17 | keywords = read(kwFile, 'ascii').split('\n').filter(Boolean);
|
18 |
|
19 | _ref = require('./nodes'), Select = _ref.Select, Update = _ref.Update, Delete = _ref.Delete, Insert = _ref.Insert;
|
20 |
|
21 | BaseDialect = (function() {
|
22 | var Visitor, doubleQuote, needsQuote;
|
23 |
|
24 | function BaseDialect() {}
|
25 |
|
26 | BaseDialect.prototype.reset = function() {};
|
27 |
|
28 | BaseDialect.prototype.compile = function(root) {
|
29 | var text, visitor;
|
30 | visitor = new Visitor(this);
|
31 | text = visitor.compile(root);
|
32 | return [text, visitor.params];
|
33 | };
|
34 |
|
35 | BaseDialect.prototype.renderString = function(s) {
|
36 | var path;
|
37 | path = this.path.map(function(p) {
|
38 | var _ref1;
|
39 | return (_ref1 = p.constructor) != null ? _ref1.name : void 0;
|
40 | }).join(' > ');
|
41 | this.path = [];
|
42 | throw new Error("raw string compiled! " + path);
|
43 | };
|
44 |
|
45 | needsQuote = /\s|"|\./;
|
46 |
|
47 | doubleQuote = /"/g;
|
48 |
|
49 | BaseDialect.prototype.quote = function(s) {
|
50 | if ((s != null ? s.match(needsQuote) : void 0) || this.isKeyword(s)) {
|
51 | return '"' + s.replace(doubleQuote, '\\"') + '"';
|
52 | } else {
|
53 | return s;
|
54 | }
|
55 | };
|
56 |
|
57 | BaseDialect.prototype.isKeyword = function(word) {
|
58 | return keywords.indexOf(word.toUpperCase()) !== -1;
|
59 | };
|
60 |
|
61 | BaseDialect.prototype.operator = function(op) {
|
62 | switch (op.toLowerCase()) {
|
63 | case 'ne':
|
64 | case '!=':
|
65 | case '<>':
|
66 | return '!=';
|
67 | case 'eq':
|
68 | case '=':
|
69 | return '=';
|
70 | case 'lt':
|
71 | case '<':
|
72 | return '<';
|
73 | case 'gt':
|
74 | case '>':
|
75 | return '>';
|
76 | case 'lte':
|
77 | case '<=':
|
78 | return '<=';
|
79 | case 'gte':
|
80 | case '>=':
|
81 | return '>=';
|
82 | case 'like':
|
83 | return 'LIKE';
|
84 | case 'ilike':
|
85 | return 'ILIKE';
|
86 | case 'in':
|
87 | return 'IN';
|
88 | case 'notin':
|
89 | return 'NOT IN';
|
90 | case 'is':
|
91 | return 'IS';
|
92 | default:
|
93 | throw new Error("Unsupported comparison operator: " + op);
|
94 | }
|
95 | };
|
96 |
|
97 | BaseDialect.prototype.placeholder = function(position) {
|
98 | return "$" + position;
|
99 | };
|
100 |
|
101 | Visitor = (function() {
|
102 |
|
103 | function Visitor(dialect) {
|
104 | this.dialect = dialect;
|
105 | this.path = [];
|
106 | this.params = [];
|
107 | }
|
108 |
|
109 | Visitor.prototype.compile = function(node) {
|
110 | var custom, name, string, _ref1, _ref2;
|
111 | this.path.push(node);
|
112 | name = node != null ? (_ref1 = node.__proto__) != null ? (_ref2 = _ref1.constructor) != null ? _ref2.name : void 0 : void 0 : void 0;
|
113 | if (name && (custom = this.dialect['render' + name])) {
|
114 | string = custom.call(this, node);
|
115 | } else {
|
116 | string = node.compile(this, this.path);
|
117 | }
|
118 | this.path.pop(node);
|
119 | return string;
|
120 | };
|
121 |
|
122 | Visitor.prototype.maybeParens = function(it) {
|
123 | if (/\s/.exec(it)) {
|
124 | return "(" + it + ")";
|
125 | } else {
|
126 | return it;
|
127 | }
|
128 | };
|
129 |
|
130 | Visitor.prototype.operator = function(string) {
|
131 | return this.dialect.operator(string);
|
132 | };
|
133 |
|
134 | Visitor.prototype.parameter = function(val) {
|
135 | this.params.push(val);
|
136 | return this.dialect.placeholder(this.params.length);
|
137 | };
|
138 |
|
139 | Visitor.prototype.quote = function(string) {
|
140 | return this.dialect.quote(string, this.path);
|
141 | };
|
142 |
|
143 | return Visitor;
|
144 |
|
145 | })();
|
146 |
|
147 | return BaseDialect;
|
148 |
|
149 | })();
|
150 |
|
151 | PostgresDialect = (function(_super) {
|
152 |
|
153 | __extends(PostgresDialect, _super);
|
154 |
|
155 | function PostgresDialect() {
|
156 | return PostgresDialect.__super__.constructor.apply(this, arguments);
|
157 | }
|
158 |
|
159 | PostgresDialect.prototype.operator = function(op) {
|
160 | switch (op.toLowerCase()) {
|
161 | case 'hasKey':
|
162 | return '?';
|
163 | case '->':
|
164 | return '->';
|
165 | default:
|
166 | return PostgresDialect.__super__.operator.call(this, op);
|
167 | }
|
168 | };
|
169 |
|
170 | PostgresDialect.prototype.isKeyword = function(s) {
|
171 | return (s != null) && s !== '*';
|
172 | };
|
173 |
|
174 | return PostgresDialect;
|
175 |
|
176 | })(BaseDialect);
|
177 |
|
178 | MySQLDialect = (function(_super) {
|
179 |
|
180 | __extends(MySQLDialect, _super);
|
181 |
|
182 | function MySQLDialect() {
|
183 | return MySQLDialect.__super__.constructor.apply(this, arguments);
|
184 | }
|
185 |
|
186 | MySQLDialect.prototype.placeholder = function() {
|
187 | return '?';
|
188 | };
|
189 |
|
190 | MySQLDialect.prototype.quote = function(s, path) {
|
191 | |
192 |
|
193 | if (path.some(function(node) {
|
194 | return node instanceof Insert.ColumnList;
|
195 | })) {
|
196 | return s;
|
197 | } else {
|
198 | return MySQLDialect.__super__.quote.apply(this, arguments);
|
199 | }
|
200 | };
|
201 |
|
202 | return MySQLDialect;
|
203 |
|
204 | })(BaseDialect);
|
205 |
|
206 | SQLite3Dialect = (function(_super) {
|
207 |
|
208 | __extends(SQLite3Dialect, _super);
|
209 |
|
210 | function SQLite3Dialect() {
|
211 | return SQLite3Dialect.__super__.constructor.apply(this, arguments);
|
212 | }
|
213 |
|
214 | SQLite3Dialect.prototype.placeholder = function() {
|
215 | return '?';
|
216 | };
|
217 |
|
218 | SQLite3Dialect.prototype.renderInsertData = function(node) {
|
219 | var string;
|
220 | if (node.nodes.length < 2) {
|
221 | return node.compile(this, this.path);
|
222 | } else {
|
223 | node.glue = ' UNION ALL SELECT ';
|
224 | string = node.compile(this, this.path).replace('VALUES', 'SELECT').replace(/[()]/g, '');
|
225 | node.glue = ', ';
|
226 | return string;
|
227 | }
|
228 | };
|
229 |
|
230 | return SQLite3Dialect;
|
231 |
|
232 | })(BaseDialect);
|
233 |
|
234 | module.exports = {
|
235 | base: BaseDialect,
|
236 | postgres: PostgresDialect,
|
237 | mysql: MySQLDialect,
|
238 | sqlite3: SQLite3Dialect
|
239 | };
|