Skip to content

Commit

Permalink
0.4.0. Now supports and, or, nor, and type
Browse files Browse the repository at this point in the history
  • Loading branch information
balupton committed Aug 13, 2011
1 parent 3170446 commit a05d3f8
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 14 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ Query-Engine supports the exact same queries as [MongoDb](http://www.mongodb.org

## History

- v0.3.1 August 13, 2011
- v0.4.0 August 13, 2011
- Find will now return a ID associated object always
- Before it was only doing it when the object we were finding was an ID associated object
- Now supports `$and`, `$or` and `$nor`, as well as `$type`

- v0.3.0 August 11, 2011
- Now supports models as well as native javascript objects
Expand Down
94 changes: 82 additions & 12 deletions lib/query-engine.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,41 @@ Object::find = (query={},next) ->
# Matches
matches = {}
length = 0
$nor = false
$or = false
$and = false
matchType = 'and'

# Determine matching type
if query.$type
matchType = query.$type
delete query.$type

# The $nor operator lets you use a boolean or expression to do queries. You give $nor a list of expressions, none of which can satisfy the query.
if query.$nor
$nor = query.$nor
delete query.$nor

# The $or operator lets you use a boolean or expression to do queries. You give $or a list of expressions, any of which can satisfy the query.
if query.$or
$or = query.$or
delete query.$or

# The $and operator lets you use boolean and in a query. You give $and an array of expressions, all of which must match to satisfy the query.
if query.$and
$and = query.$and
delete query.$and

# Start with entire set
for own id,record of @
# Match
match = false
matchAll = true
matchAny = false
empty = true

# Selectors
for own field, selector of query
match = false
empty = false
selectorType = typeof selector
value = get(record,field)
Expand All @@ -75,14 +101,6 @@ Object::find = (query={},next) ->

# Conditional Operators
else if selector instanceof Object
# The $nor operator lets you use a boolean or expression to do queries. You give $nor a list of expressions, none of which can satisfy the query.
if selector.$nor
match = false

# The $or operator lets you use a boolean or expression to do queries. You give $or a list of expressions, any of which can satisfy the query.
if selector.$or
match = false

# The $all operator is similar to $in, but instead of matching any value in the specified array all values in the array must be matched.
if selector.$all
if exists and value.hasAll(selector.$all)
Expand Down Expand Up @@ -147,12 +165,64 @@ Object::find = (query={},next) ->
if selector.$gte
if exists and value >= selector.$gte
match = true

# Matched
if match
matchAny = true
else
matchAll = false

# Match all
if matchAll and !matchAny
matchAll = false

# Append
if match or empty
++length
matches[id] = record
append = false
if empty
append = true
else
switch matchType
when 'none','nor'
append = true unless matchAny

when 'any','or'
append = true if matchAny

#when 'all','and'
else
append = true if matchAll

# Append
matches[id] = record if append

# The $nor operator lets you use a boolean or expression to do queries. You give $nor a list of expressions, none of which can satisfy the query.
if $nor
newMatches = {}
for expression in $nor
for own key,value of matches.find expression
newMatches[key] = value
for own key,value of newMatches
if matches[key]?
delete matches[key]

# The $or operator lets you use a boolean or expression to do queries. You give $or a list of expressions, any of which can satisfy the query.
if $or
newMatches = {}
for expression in $or
for own key,value of matches.find expression
newMatches[key] = value
matches = newMatches

# The $and operator lets you use boolean and in a query. You give $and an array of expressions, all of which must match to satisfy the query.
if $and
for expression in $and
matches = matches.find expression

# Calculate length
length = 0
for own match of matches
++length

# Async
if next?
next false, matches, length
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "query-engine",
"version": "0.3.1",
"version": "0.4.0",
"description": "A NoSQL (and MongoDB compliant) Query Engine coded in CoffeeScript for Server-Side use with Node.js and Client-Side use with Web-Browsers",
"homepage": "https://github.com/balupton/query-engine.npm",
"keywords": [
Expand Down
41 changes: 41 additions & 0 deletions test/query-engine.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,21 @@ store =
content: 'this is the index page'
tags: []
position: 1
category: 1
'jquery':
id: 'jquery'
title: 'jQuery'
content: 'this is about jQuery'
tags: ['jquery']
position: 2
category: 1
'history':
id: 'history'
title: 'History.js'
content: 'this is about History.js'
tags: ['jquery','html5','history']
position: 3
category: 1

associatedModels:
'index': new model
Expand All @@ -71,18 +74,21 @@ store =
content: 'this is the index page'
tags: []
position: 1
category: 1
'jquery': new model
id: 'jquery'
title: 'jQuery'
content: 'this is about jQuery'
tags: ['jquery']
position: 2
category: 1
'history': new model
id: 'history'
title: 'History.js'
content: 'this is about History.js'
tags: ['jquery','html5','history']
position: 3
category: 1


# -------------------------------------
Expand Down Expand Up @@ -115,6 +121,41 @@ generateTestSuite = (name,docs) ->
assert.deepEqual actual.getData(), expected.getData()
assert.equal length, 2

'joint': ->
actual = docs.find id: 'index', category: 1
expected = 'index': docs.index
assert.deepEqual actual.getData(), expected.getData()

'type-and': ->
actual = docs.find $type: 'and', id: 'index', category: 1
expected = 'index': docs.index
assert.deepEqual actual.getData(), expected.getData()

'type-or': ->
actual = docs.find $type: 'or', id: 'index', position: 2
expected = 'index': docs.index, 'jquery': docs.jquery
assert.deepEqual actual.getData(), expected.getData()

'type-nor': ->
actual = docs.find $type: 'nor', id: 'index', position: 2
expected = 'history': docs.history
assert.deepEqual actual.getData(), expected.getData()

'$and': ->
actual = docs.find $all: [{id: 'index'}, {position: 2}]
expected = {}
assert.deepEqual actual.getData(), expected.getData()

'$or': ->
actual = docs.find $or: [{id: 'index'}, {position: 2}]
expected = 'index': docs.index, 'jquery': docs.jquery
assert.deepEqual actual.getData(), expected.getData()

'$nor': ->
actual = docs.find $nor: [{id: 'index'}, {position: 2}]
expected = 'history': docs.history
assert.deepEqual actual.getData(), expected.getData()

'$ne': ->
actual = docs.find id: $ne: 'index'
expected = 'jquery': docs.jquery, 'history': docs.history
Expand Down

0 comments on commit a05d3f8

Please sign in to comment.