Skip to content

Instantly share code, notes, and snippets.

@infernoboy
Created September 6, 2015 00:06
Show Gist options
  • Save infernoboy/600667ef9ad97acf3835 to your computer and use it in GitHub Desktop.
Save infernoboy/600667ef9ad97acf3835 to your computer and use it in GitHub Desktop.
{BaseController} = require './base'
class QueryController extends BaseController
constructor: (@table) ->
super()
@map =
gt: '>'
gte: '>='
lt: '<'
lte: '<='
'not': '!='
'in': ['IN', (value) => "(#{value.map((v) => '?').join ','})"]
'notin': ['NOT IN', (value) => "(#{value.map((v) => '?').join ','})"]
ilike: 'ILIKE'
notilike: 'NOT ILIKE'
like: 'LIKE'
notlike: 'NOT LIKE'
hex: ['=', (value) => "CAST(x? AS int)"]
@map.hex_gt = ['>', @map.hex[1]]
@map.hex_lt = ['<', @map.hex[1]]
@map.hex_gte = ['>=', @map.hex[1]]
@map.hex_lte = ['<=', @map.hex[1]]
@reset()
format: (value) ->
return 'NULL' if typeof value is 'undefined' or value is null
return "#{value}" if typeof value is 'number'
return 'true' if value is true
return 'false' if value is false
value = value.replace /'/g, "''"
"'#{value}'"
'new': ->
@query.where = ['']
delete @query.order
delete @query.limit
delete @query.include
delete @query.attributes
@
openGroup: (join="and") =>
@query.where[0] += " #{join} ("
@
closeGroup: =>
@query.where[0] += ') '
@
chain: (field, operator, value, join="and", push=yes) ->
@query.where[0] += " #{join} "
@query.where[0] +=
if field is 'created' then "cast(\"#{@table}\".\"created\" as int8) #{operator} "
else "\"#{@table}\".\"#{field}\" #{operator} "
if push
@query.where[0] += '?'
@query.where.push value
else
@query.where[0] += "#{value}"
@
where: (args...) ->
@openGroup if typeof args[0] is 'string' then args.shift() else ''
for chain, index in args
counter = 0
@openGroup if index then 'or' else ''
for field, value of chain
ref = field.split('__')
mapped = @map[ref[1]] or ''
transform_value = if mapped instanceof Array then mapped[1](value) else null
@chain(ref[0], (if transform_value then mapped[0] else mapped or '='), transform_value or value, counter++ and 'and' or ' ', if transform_value then no else yes)
if transform_value
if value instanceof Array
@query.where.push item for item in value
else
@query.where.push value
@closeGroup()
@closeGroup()
@
order: (field, desc=no) ->
@query.order = "\"#{@table}\".\"#{field}\" #{if desc then 'DESC' else 'ASC'}"
@
limit: (amount) ->
@query.limit = Math.abs amount
@
since: (time) -> @chain 'created', '>=', time
until: (time) -> @chain 'created', '<=', time
last: (amount) ->
@order('created', if amount > 0 then no else yes).limit amount
@reverse = if amount < 0 then true else false
@
include: (what) ->
@query.include = [] unless @query.include instanceof Array
@query.include.push what
@
reset: ->
@reverse = false
@query = where: ['']
@_reset?()
@
exports.QueryController = QueryController
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment