UNPKG

5.37 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.4.0
2/*
3Dialects are responsible for rendering an AST to a SQL string compatible with
4a particular DBMS. They are rarely used directly, instead a query is usually bound
5to an `engine <Engines>`_ that will delegate rendering to it's dialect instance.
6*/
7
8var BaseDialect, Delete, Insert, MySQLDialect, PostgresDialect, SQLite3Dialect, Select, Update, keywords, kwFile, read, _ref,
9 __hasProp = {}.hasOwnProperty,
10 __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; };
11
12read = require('fs').readFileSync;
13
14kwFile = __dirname + '/sql_keywords.txt';
15
16keywords = read(kwFile, 'ascii').split('\n').filter(Boolean);
17
18_ref = require('./nodes'), Select = _ref.Select, Update = _ref.Update, Delete = _ref.Delete, Insert = _ref.Insert;
19
20BaseDialect = (function() {
21 var doubleQuote, needsQuote;
22
23 function BaseDialect() {
24 this.path = [];
25 }
26
27 BaseDialect.prototype.render = function(node) {
28 var custom, name, string, _ref1, _ref2;
29 if (!this.path.length) {
30 this.paramCount = 1;
31 }
32 this.path.push(node);
33 name = node != null ? (_ref1 = node.__proto__) != null ? (_ref2 = _ref1.constructor) != null ? _ref2.name : void 0 : void 0 : void 0;
34 if (name && (custom = this['render' + name])) {
35 string = custom.call(this, node);
36 } else {
37 string = node.render(this, this.path);
38 }
39 this.path.pop(node);
40 return string;
41 };
42
43 BaseDialect.prototype.renderString = function(s) {
44 var path;
45 path = this.path.map(function(p) {
46 var _ref1;
47 return (_ref1 = p.constructor) != null ? _ref1.name : void 0;
48 }).join(' > ');
49 this.path = [];
50 throw new Error("raw string rendered! " + path);
51 };
52
53 needsQuote = /\s|"|\./;
54
55 doubleQuote = /"/g;
56
57 BaseDialect.prototype.quote = function(s) {
58 if ((s != null ? s.match(needsQuote) : void 0) || this.isKeyword(s)) {
59 return '"' + s.replace(doubleQuote, '\\"') + '"';
60 } else {
61 return s;
62 }
63 };
64
65 BaseDialect.prototype.isKeyword = function(word) {
66 return keywords.indexOf(word.toUpperCase()) !== -1;
67 };
68
69 BaseDialect.prototype.maybeParens = function(it) {
70 if (/\s/.exec(it)) {
71 return "(" + it + ")";
72 } else {
73 return it;
74 }
75 };
76
77 BaseDialect.prototype.operator = function(op) {
78 switch (op.toLowerCase()) {
79 case 'ne':
80 case '!=':
81 case '<>':
82 return '!=';
83 case 'eq':
84 case '=':
85 return '=';
86 case 'lt':
87 case '<':
88 return '<';
89 case 'gt':
90 case '>':
91 return '>';
92 case 'lte':
93 case '<=':
94 return '<=';
95 case 'gte':
96 case '>=':
97 return '>=';
98 case 'like':
99 return 'LIKE';
100 case 'ilike':
101 return 'ILIKE';
102 case 'in':
103 return 'IN';
104 case 'is':
105 return 'IS';
106 default:
107 throw new Error("Unsupported comparison operator: " + op);
108 }
109 };
110
111 BaseDialect.prototype.renderParameter = function(node) {
112 return "$" + (this.paramCount++);
113 };
114
115 return BaseDialect;
116
117})();
118
119PostgresDialect = (function(_super) {
120
121 __extends(PostgresDialect, _super);
122
123 function PostgresDialect() {
124 return PostgresDialect.__super__.constructor.apply(this, arguments);
125 }
126
127 PostgresDialect.prototype.render = function(node) {
128 return PostgresDialect.__super__.render.call(this, node);
129 };
130
131 PostgresDialect.prototype.operator = function(op) {
132 switch (op.toLowerCase()) {
133 case 'hasKey':
134 return '?';
135 case '->':
136 return '->';
137 default:
138 return PostgresDialect.__super__.operator.call(this, op);
139 }
140 };
141
142 PostgresDialect.prototype.isKeyword = function(s) {
143 return (s != null) && s !== '*';
144 };
145
146 return PostgresDialect;
147
148})(BaseDialect);
149
150MySQLDialect = (function(_super) {
151
152 __extends(MySQLDialect, _super);
153
154 function MySQLDialect() {
155 return MySQLDialect.__super__.constructor.apply(this, arguments);
156 }
157
158 MySQLDialect.prototype.renderParameter = function() {
159 return '?';
160 };
161
162 MySQLDialect.prototype.quote = function(s) {
163 /* Do not quote column names in insert column list
164 */
165 if (this.path.some(function(node) {
166 return node instanceof Insert.ColumnList;
167 })) {
168 return s;
169 } else {
170 return MySQLDialect.__super__.quote.apply(this, arguments);
171 }
172 };
173
174 return MySQLDialect;
175
176})(BaseDialect);
177
178SQLite3Dialect = (function(_super) {
179
180 __extends(SQLite3Dialect, _super);
181
182 function SQLite3Dialect() {
183 return SQLite3Dialect.__super__.constructor.apply(this, arguments);
184 }
185
186 SQLite3Dialect.prototype.renderParameter = function() {
187 return '?';
188 };
189
190 SQLite3Dialect.prototype.renderInsertData = function(node) {
191 var string;
192 if (node.nodes.length < 2) {
193 return node.render(this, this.path);
194 } else {
195 node.glue = ' UNION ALL SELECT ';
196 string = node.render(this, this.path).replace('VALUES', 'SELECT').replace(/[()]/g, '');
197 node.glue = ', ';
198 return string;
199 }
200 };
201
202 return SQLite3Dialect;
203
204})(BaseDialect);
205
206module.exports = {
207 base: BaseDialect,
208 postgres: PostgresDialect,
209 mysql: MySQLDialect,
210 sqlite3: SQLite3Dialect
211};