Verified Commit a668e8ca authored by Aral Balkan's avatar Aral Balkan
Browse files

Closes #12: Attempt to create query on non-array throws TypeError

parent 84b50ce3
......@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.5] - 2020-10-31
### Improved
- Attempt to create a query on a non-array object now throws `TypeError`. (#12)
## [1.1.4] - 2020-10-29
### Fixed
......
......@@ -254,6 +254,8 @@ const db = JSDB.open('db')
console.log(db.people.where('age').isLessThan(21).get())
```
Note that you can only run queries on arrays. Attempting to run them on plain or custom objects (that are not subclasses of `Array`) will result in a `TypeError`. Furthermore, queries only make sense when used on arrays of objects. Running a query on an array of simple data types will not throw an error but will return an empty result set.
For details, see the [JSQL Reference](#jsql-reference) section.
......
......@@ -73,9 +73,15 @@ class DataProxy {
//
// Note that queries as well as data set operations execute synchronously
// so you will not encounter race conditions when using them in web routes.
if (property === 'where') return (function (property) {
return new IncompleteQueryProxy(this.table, this.data, `valueOf.${property}`)
}).bind(this)
if (property === 'where') {
if (Array.isArray(this.data)) {
return (function (property) {
return new IncompleteQueryProxy(this.table, this.data, `valueOf.${property}`)
}).bind(this)
} else {
throw new TypeError('Queries can only be applied to arrays.')
}
}
// For more complicated queries (e.g., those involving parentheticals, etc.),
// you can pass the query string directly.
......@@ -83,9 +89,15 @@ class DataProxy {
// Note that when you do this, you will have to prefix your property names with valueOf.
// e.g., The query string for where('age').isGreaterThanOrEqualTo(21).and('name').startsWith('A') would be
// 'valueOf.age >= 21 && valueOf.name.startsWith("A")'
if (property === 'whereIsTrue') return (function (predicate) {
return new QueryProxy(this.table, this.data, predicate)
}).bind(this)
if (property === 'whereIsTrue') {
if (Array.isArray(this.data)) {
return (function (predicate) {
return new QueryProxy(this.table, this.data, predicate)
}).bind(this)
} else {
throw new TypeError('Queries can only be applied to arrays.')
}
}
return Reflect.get(this.data, property, receiver)
}
......
{
"name": "@small-tech/jsdb",
"version": "1.1.4",
"version": "1.1.5",
"description": "A transparent, in-memory, streaming write-on-update JavaScript database for Small Web applications that persists to a JavaScript transaction log.",
"keywords": [
"js",
......
......@@ -373,6 +373,17 @@ test('Basic queries', t => {
const db = JSDB.open(databasePath, { deleteIfExists: true })
//
// Queries can only be performed on arrays.
//
db.objectTableForQueryTest = {}
t.throws(() => { db.objectTableForQueryTest.where('something') }, 'attempt to start a where query on object table throws')
t.throws(() => { db.objectTableForQueryTest.whereIsTrue('something') }, 'attempt to start a whereIsTrue query on object table throws')
// Note: I know nothing about cars. This is randomly generated data. And I added the tags myself
// ===== to test the includes operator on an array property.
const cars = [
......@@ -390,6 +401,12 @@ test('Basic queries', t => {
db.cars = cars
//
// Error checking.
//
t.throws(() => { cars[0].where('something') }, 'attempt to start where query on object child of array table throws')
t.throws(() => { cars[0].whereIsTrue('something') }, 'attempt to start whereIsTrue query on object child of array table throws')
//
// Relational operators.
//
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment