Skip to content

Commit

Permalink
fix(ssloth-database): avoid concurrent initSetup
Browse files Browse the repository at this point in the history
  • Loading branch information
vinz243 committed Apr 24, 2018
1 parent f41833d commit 68f9000
Showing 1 changed file with 69 additions and 53 deletions.
122 changes: 69 additions & 53 deletions src/models/SlothDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export default class SlothDatabase<
changes: PouchDB.Core.Changes<S>
}[] = []

private _setupPromise?: Promise<any>

/**
* Create a new database instance
* @param factory the pouch factory to use
Expand All @@ -57,47 +59,81 @@ export default class SlothDatabase<

const { name } = getProtoData(model.prototype)

/* istanbul ignore if */
if (!name) {
throw new Error('SlothEntity decorator is required')
}

this._name = name
}

/**
* Queries and maps docs to Entity objects
* Run a query
*
* @param factory the pouch factory
* @param view the view identifier
* @param startKey the optional startkey
* @param endKey the optional endkey
* @param includeDocs include_docs
*/
queryDocs(
query(
factory: PouchFactory<S>,
view: V,
startKey = '',
endKey = join(startKey, '\uffff')
): Promise<E[]> {
endKey = join(startKey, '\uffff'),
includeDocs = false
): Promise<PouchDB.Query.Response<S>> {
return factory(this._name)
.query(view, {
.query<S>(view, {
startkey: startKey,
endkey: endKey,
include_docs: true
})
.then(({ rows }) => {
return rows.map(({ doc }) => new this._model(factory, doc as any))
include_docs: includeDocs
})
.catch(err => {
if (err.name === 'not_found') {
debug(`Design document '%s' is missing, generating views...`, view)
return this.initSetup(factory).then(() => {

/* istanbul ignore if */
if (this._setupPromise) {
this._setupPromise.then(() => {
return this.query(factory, view, startKey, endKey, includeDocs)
})
}

this._setupPromise = this.initSetup(factory)

return this._setupPromise.then(() => {
debug('Created design documents')
return this.queryDocs(factory, view, startKey, endKey)
this._setupPromise = undefined
return this.query(factory, view, startKey, endKey, includeDocs)
})
}
throw err
})
}
/**
* Queries and maps docs to Entity objects
*
* @param factory the pouch factory
* @param view the view identifier
* @param startKey the optional startkey
* @param endKey the optional endkey
*/
queryDocs(
factory: PouchFactory<S>,
view: V,
startKey = '',
endKey = join(startKey, '\uffff')
): Promise<E[]> {
return this.query(
factory,
view,
startKey,
endKey,
true
).then(({ rows }) => {
return rows.map(({ doc }) => new this._model(factory, doc as any))
})
}

/**
* Queries keys. Returns an array of emitted keys
Expand All @@ -113,25 +149,15 @@ export default class SlothDatabase<
startKey = '',
endKey = join(startKey, '\uffff')
): Promise<string[]> {
return factory(this._name)
.query(view, {
startkey: startKey,
endkey: endKey,
include_docs: false
})
.then(({ rows }) => {
return rows.map(({ key }) => key)
})
.catch(err => {
if (err.name === 'not_found') {
debug(`Design document '%s' is missing, generating views...`, view)
return this.initSetup(factory).then(() => {
debug('Created design documents')
return this.queryKeys(factory, view, startKey, endKey)
})
}
throw err
})
return this.query(
factory,
view,
startKey,
endKey,
false
).then(({ rows }) => {
return rows.map(({ key }) => key)
})
}

/**
Expand All @@ -148,28 +174,18 @@ export default class SlothDatabase<
startKey = '',
endKey = join(startKey, '\uffff')
): Promise<Dict<string>> {
return factory(this._name)
.query(view, {
startkey: startKey,
endkey: endKey,
include_docs: false
})
.then(({ rows }) => {
return rows.reduce(
(acc, { key, id }) => ({ ...acc, [key]: id }),
{} as Dict<string>
)
})
.catch(err => {
if (err.name === 'not_found') {
debug(`Design document '%s' is missing, generating views...`, view)
return this.initSetup(factory).then(() => {
debug('Created design documents')
return this.queryKeysIDs(factory, view, startKey, endKey)
})
}
throw err
})
return this.query(
factory,
view,
startKey,
endKey,
false
).then(({ rows }) => {
return rows.reduce(
(acc, { key, id }) => ({ ...acc, [key]: id }),
{} as Dict<string>
)
})
}

/**
Expand Down

0 comments on commit 68f9000

Please sign in to comment.