Skip to content

Commit

Permalink
Allows "include" syntax
Browse files Browse the repository at this point in the history
```
MyModel.find({
  include: {
    model: OtherModel,
    as: “otherModelForeignKey”
  }
})
```
  • Loading branch information
OKNoah committed Sep 4, 2017
1 parent 48f3cdb commit 55584b9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 19 deletions.
13 changes: 13 additions & 0 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ test('check list is sorted', async () => {
expect(isEqual(posts, sorted)).toBe(true)
})

test('find with include', async () => {
const posts = await Post.find({
include: {
model: User,
as: 'creator'
}
})

expect(posts[0]).toHaveProperty('creator.name')
expect(posts[0]).toHaveProperty('_key')
expect(posts[0]).toHaveProperty('body')
})

test('remove item', async () => {
const userToRemove = await User.findOne({
where: { name: username }
Expand Down
69 changes: 51 additions & 18 deletions models/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export default class Model {
static async save (model) {
this._validate(model)
const document = this._modelToDocument(model)
document.updateddAt = new Date().toISOString()
document.updatedAt = new Date().toISOString()
const newHandle = await this._call('update', model._id, document)
model._rev = newHandle._rev
return model
Expand All @@ -169,31 +169,64 @@ export default class Model {

static async find (args) {
const db = await this._getDatabase()
const { skip, limit, where, attributes, sort } = args
const { skip, limit, where, attributes, sort, include } = args
const item = this.name.toLowerCase()
let query = `for ${item} in ${this.name} filter ${item}._removed != true`
if (where) {

const getWhere = () => {
const wheres = []
for (const key in where) {
query += ` filter ${item}.${key} == "${where[key]}"`
wheres.push(` filter ${item}.${key} == "${where[key]}"`)
}

return wheres.join(' ')
}
if (limit || skip) {
query += ` limit ${skip ? skip + ', ' : ''}${limit || 100}`
}
if (sort) {
query += ` sort ${sort}`
}
if (attributes) {
query += ` return {`

const getAttributesString = (attributes, results) =>
attributes.map((attribute, index) => {
query += `${attribute}: ${item}.${attribute}${index + 1 !== attributes.length && ', '} `
})
query += `}`
} else {
query += ` return ${item}`
return `${attribute}: ${results}.${attribute}${index + 1 !== attributes.length && ', '} `
}).join(' ')

const getAttributes = () => {
const includeModel = include && include.model.name.toLowerCase()
const includes = include && `${include.as}s`

if (include) {
return `
let ${includes} = (
for ${includeModel} in ${include.model.name}
filter ${includeModel}._removed != true
filter ${item}.${include.as} == ${includeModel}._id
limit ${include.limit || '1'}
return ${include.attributes ?
`{ ${getAttributesString(attributes, includeModel)} }`
: includeModel }
)
filter length(${includes}) != 0
return MERGE(
${attributes ? `{ ${getAttributesString(attributes, item)} }` : item}, {
${include.as}: ${includes}[${include.limit || '0'}]}
)
`
}

return `return { ${getAttributesString(attributes, item)} }`
}

let query = `
for ${item} in ${this.name} filter ${item}._removed != true
${where ? getWhere() : ''}
${(limit || skip) ? ` limit ${skip ? skip + ', ' : ''}${limit || 100}` : ''}
${(sort) ? ` sort ${sort}` : ''}
${(attributes || include) ? getAttributes() : `return ${item}`}
`

const cursor = await db.query(query)
const documents = await cursor.all()

if (include || attributes) {
return documents
}

return documents.map((doc) => {
return this._createModelByDocument(doc)
})
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": "ormjs",
"version": "1.0.0-alpha.2",
"version": "1.0.0-alpha.3",
"scripts": {
"prepublish": "npm run build",
"babel-build": "./node_modules/.bin/babel . -d dist --ignore dist",
Expand Down

0 comments on commit 55584b9

Please sign in to comment.