Significant enhancements to UsergridQuery builder pattern
diff --git a/lib/query.js b/lib/query.js
index 4461f08..fb6c772 100644
--- a/lib/query.js
+++ b/lib/query.js
@@ -1,11 +1,15 @@
 'use strict'
 
 var helpers = require('../helpers'),
-    util = require('util')
+    util = require('util'),
+    _ = require('underscore')
+
+_.mixin(require('underscore.string'))
 
 var UsergridQuery = function(type) {
 
-    var eq, gt, gte, lt, lte, contains, locationWithin, sort
+    var query = '',
+        sort
 
     // builder pattern
     var self = {
@@ -22,51 +26,67 @@
             return self
         },
         eq: function(key, value) {
-            eq = util.format('%s = %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s = %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         gt: function(key, value) {
-            gt = util.format('%s > %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s > %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         gte: function(key, value) {
-            gte = util.format('%s >= %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s >= %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         lt: function(key, value) {
-            lt = util.format('%s < %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s < %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         lte: function(key, value) {
-            lte = util.format('%s <= %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s <= %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         contains: function(key, value) {
-            contains = util.format('%s contains %s', key, helpers.query.useQuotesIfRequired(value))
+            query = self.andJoin(util.format('%s contains %s', key, helpers.query.useQuotesIfRequired(value)))
             return self
         },
         locationWithin: function(distanceInMeters, lat, lng) {
-            locationWithin = util.format('location within %s of %s, %s', distanceInMeters, lat, lng)
+            query = self.andJoin(util.format('location within %s of %s, %s', distanceInMeters, lat, lng))
             return self
         },
         asc: function(key) {
-            this.sort(key, 'asc')
+            self.sort(key, 'asc')
             return self
         },
         desc: function(key) {
-            this.sort(key, 'desc')
+            self.sort(key, 'desc')
             return self
         },
         sort: function(key, order) {
             sort = (key && order) ? util.format(' order by %s %s', key, order) : ''
             return self
         },
-        or: function() {
+        fromString: function(string) {
+            self._ql = string
             return self
         },
-        fromString: function(string) {
-            self.ql = string
-            return self
+        andJoin: function(append) {
+            if ((/s?_NOT_/).test(query)) {
+                query = query.replace(/\s?_NOT_/, '')
+                append = util.format("not %s", append)
+            }
+            if (!append) {
+                return query
+            } else if (query.length === 0) {
+                return append
+            } else {
+                return (_(query).endsWith('and') || _(query).endsWith('or')) ? util.format('%s %s', query, append) : util.format('%s and %s', query, append)
+            }
+        },
+        orJoin: function() {
+            return (query.length > 0 && !_(query).endsWith('or')) ? util.format('%s or', query) : query
+        },
+        notJoin: function() {
+            return (query.length > 0 && !_(query).endsWith('_NOT_')) ? util.format('%s _NOT_', query) : query
         }
     }
 
@@ -76,7 +96,28 @@
     // public accessors
     Object.defineProperty(self, '_ql', {
         get: function() {
-            return util.format('select * where %s%s', eq || gt || gte || lt || lte || contains || '', sort || '')
+            return util.format('select * where %s%s', query || '', sort || '')
+        }
+    })
+
+    Object.defineProperty(self, 'and', {
+        get: function() {
+            query = self.andJoin('')
+            return self
+        }
+    })
+
+    Object.defineProperty(self, 'or', {
+        get: function() {
+            query = self.orJoin()
+            return self
+        }
+    })
+
+    Object.defineProperty(self, 'not', {
+        get: function() {
+            query = self.notJoin()
+            return self
         }
     })
 
diff --git a/tests/lib/query.js b/tests/lib/query.js
index ef017db..505563c 100644
--- a/tests/lib/query.js
+++ b/tests/lib/query.js
@@ -1,7 +1,8 @@
 'use strict'
 
 var should = require('should'),
-    UsergridQuery = require('../../lib/query')
+    UsergridQuery = require('../../lib/query'),
+    util = require('util')
 
 describe('type', function() {
     it('query._type should equal "cats" when passing "type" as a parameter to UsergridQuery', function() {
@@ -27,14 +28,16 @@
     })
 })
 
-describe('eq', function() {
-    var queryString = "select * where color = 'black'"
+describe('builder pattern', function() {
+    var queryString = "select * where weight > 2.4 and color contains 'bl*' and not color = 'blue' or color = 'orange'"
     it(util.format('query._ql should equal %s', queryString), function() {
-        var query = new UsergridQuery().collection('cats').eq('color', 'black')
+        var query = new UsergridQuery('cats')
+            .gt('weight', 2.4)
+            .contains('color', 'bl*')
+            .not
+            .eq('color', 'blue')
+            .or
+            .eq('color', 'orange')
         query.should.have.property('_ql').equal(queryString)
     })
-})
-
-// console.log(.desc('color').ql)
-// console.log(new UsergridQuery().collection('cats').gt('weight', 2.4).desc('color').ql)
-// console.log(new UsergridQuery().collection('cats').limit(10).limit)
\ No newline at end of file
+})
\ No newline at end of file