|
|
@ -3,6 +3,7 @@ |
|
|
|
var util = require('util'); |
|
|
|
var assert = require('assert'); |
|
|
|
var From = require(__dirname + '/../node/from'); |
|
|
|
var Select = require(__dirname + '/../node/select'); |
|
|
|
var Parameter = require(__dirname + '/../node/parameter'); |
|
|
|
var Postgres = function() { |
|
|
|
this.output = []; |
|
|
@ -70,7 +71,6 @@ Postgres.prototype.visitSelect = function(select) { |
|
|
|
|
|
|
|
Postgres.prototype.visitInsert = function(insert) { |
|
|
|
var self = this; |
|
|
|
this._visitedFrom = true; |
|
|
|
//don't use table.column for inserts
|
|
|
|
this._visitedInsert = true; |
|
|
|
|
|
|
@ -98,7 +98,6 @@ Postgres.prototype.visitInsert = function(insert) { |
|
|
|
|
|
|
|
Postgres.prototype.visitUpdate = function(update) { |
|
|
|
//don't auto-generate from clause
|
|
|
|
this._visitedFrom = true; |
|
|
|
var params = []; |
|
|
|
/*jshint boss: true */ |
|
|
|
for(var i = 0, node; node = update.nodes[i]; i++) { |
|
|
@ -124,7 +123,6 @@ Postgres.prototype.visitDelete = function() { |
|
|
|
Postgres.prototype.visitCreate = function(create) { |
|
|
|
this._visitingCreate = true; |
|
|
|
//don't auto-generate from clause
|
|
|
|
this._visitedFrom = true; |
|
|
|
var table = this._queryNode.table; |
|
|
|
var col_nodes = table.columns.map(function(col) { return col.toNode(); }); |
|
|
|
|
|
|
@ -138,7 +136,6 @@ Postgres.prototype.visitCreate = function(create) { |
|
|
|
|
|
|
|
Postgres.prototype.visitDrop = function(drop) { |
|
|
|
//don't auto-generate from clause
|
|
|
|
this._visitedFrom = true; |
|
|
|
var result = ['DROP TABLE']; |
|
|
|
result = result.concat(drop.nodes.map(this.visit.bind(this))); |
|
|
|
result.push(this.visit(this._queryNode.table.toNode())); |
|
|
@ -148,7 +145,6 @@ Postgres.prototype.visitDrop = function(drop) { |
|
|
|
Postgres.prototype.visitAlter = function(alter) { |
|
|
|
this._visitingAlter = true; |
|
|
|
//don't auto-generate from clause
|
|
|
|
this._visitedFrom = true; |
|
|
|
var table = this._queryNode.table; |
|
|
|
var col_nodes = table.columns.map(function(col) { return col.toNode(); }); |
|
|
|
var result = [ |
|
|
@ -161,7 +157,6 @@ Postgres.prototype.visitAlter = function(alter) { |
|
|
|
}; |
|
|
|
|
|
|
|
Postgres.prototype.visitFrom = function(from) { |
|
|
|
this._visitedFrom = true; |
|
|
|
var result = []; |
|
|
|
result.push('FROM'); |
|
|
|
for(var i = 0; i < from.nodes.length; i++) { |
|
|
@ -214,17 +209,53 @@ Postgres.prototype.visitUnary = function(unary) { |
|
|
|
|
|
|
|
Postgres.prototype.visitQuery = function(queryNode) { |
|
|
|
this._queryNode = queryNode; |
|
|
|
for(var i = 0; i < queryNode.nodes.length; i ++) { |
|
|
|
var res = this.visit(queryNode.nodes[i]); |
|
|
|
//need to sort the top level query nodes on visitation priority
|
|
|
|
//so select/insert/update/delete comes before from comes before where
|
|
|
|
var sortedNodes = []; |
|
|
|
var missingFrom = true; |
|
|
|
var actions = []; |
|
|
|
var targets = []; |
|
|
|
var filters = []; |
|
|
|
for(var i = 0; i < queryNode.nodes.length; i++) { |
|
|
|
var node = queryNode.nodes[i]; |
|
|
|
switch(node.type) { |
|
|
|
case "SELECT": |
|
|
|
case "DELETE": |
|
|
|
actions.push(node); |
|
|
|
break; |
|
|
|
case "INSERT": |
|
|
|
case "UPDATE": |
|
|
|
case "CREATE": |
|
|
|
case "DROP": |
|
|
|
case "ALTER": |
|
|
|
actions.push(node); |
|
|
|
missingFrom = false; |
|
|
|
break; |
|
|
|
case "FROM": |
|
|
|
missingFrom = false; |
|
|
|
targets.push(node); |
|
|
|
break; |
|
|
|
default: |
|
|
|
filters.push(node); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if(!actions.length) { |
|
|
|
console.log('missing select') |
|
|
|
//if no actions are given, guess it's a select
|
|
|
|
actions.push(new Select().add('*')); |
|
|
|
} |
|
|
|
if(missingFrom) { |
|
|
|
console.log('missing from') |
|
|
|
targets.push(new From().add(queryNode.table)); |
|
|
|
} |
|
|
|
//lazy-man sorting
|
|
|
|
var sortedNodes = actions.concat(targets).concat(filters); |
|
|
|
for(var i = 0; i < sortedNodes.length; i++) { |
|
|
|
var res = this.visit(sortedNodes[i]); |
|
|
|
this.output = this.output.concat(res); |
|
|
|
} |
|
|
|
//implicit 'from'
|
|
|
|
if(!this._visitedFrom) { |
|
|
|
var select = this.output.slice(0, this._selectOrDeleteEndIndex); |
|
|
|
var from = this.visitFrom(new From().add(queryNode.table.toNode())); |
|
|
|
var rest = this.output.slice(this._selectOrDeleteEndIndex); |
|
|
|
this.output = select.concat(from).concat(rest); |
|
|
|
} |
|
|
|
return this; |
|
|
|
}; |
|
|
|
|
|
|
|