Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix #65

Merged
merged 4 commits into from
Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
machine:
node:
version: 6
version: 6.10.0

test:
override:
Expand All @@ -10,4 +10,4 @@ test:

notify:
webhooks:
- url: http://teambition.vvlyn.com/api/circle
- url: http://teambition.vvlyn.com/api/circle
2 changes: 1 addition & 1 deletion src/shared/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class Logger {
if (!logger) {
const ctxLogger = new ContextLogger(name, level || Logger.defaultLevel, formatter)
Logger.contextMap.set(name, ctxLogger)
logger.destroy = () => Logger.contextMap.delete(name)
ctxLogger.destroy = () => Logger.contextMap.delete(name)
return ctxLogger
}

Expand Down
111 changes: 67 additions & 44 deletions src/storage/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class Database {
private schemas = new Map<string, ParsedSchema>()
private schemaBuilder: lf.schema.Builder
private connected = false
// note thin cache will be unreliable in some eage case
private storedIds = new Set<string>()
private subscription: Subscription

Expand Down Expand Up @@ -89,11 +90,20 @@ export class Database {

load(data: any) {
assert(!this.connected, Exception.DatabaseIsNotEmpty())
return this.database$.concatMap(db => db.import(data))
.do(() => {

return this.database$
.concatMap(db => {
forEach(data.tables, (entities: any[], name: string) => {
const schema = this.findSchema(name)
entities.forEach(entity => this.storedIds.add(entity[schema.pk]))
entities.forEach((entity: any) =>
this.storedIds.add(fieldIdentifier(name, entity[schema.pk])))
})
return db.import(data).catch(() => {
forEach(data.tables, (entities: any[], name: string) => {
const schema = this.findSchema(name)
entities.forEach((entity: any) =>
this.storedIds.delete(fieldIdentifier(name, entity[schema.pk])))
})
})
})
}
Expand Down Expand Up @@ -137,8 +147,9 @@ export class Database {
})

const { contextIds, queries } = Mutation.aggregate(db, muts, [])
return this.executor(queries)
.do(() => contextIds.forEach(id => this.storedIds.add(id)))
contextIds.forEach(id => this.storedIds.add(id))
return this.executor(db, queries)
.do({ error: () => contextIds.forEach(id => this.storedIds.delete(id)) })
})
}

Expand Down Expand Up @@ -191,7 +202,7 @@ export class Database {
}
})

return this.executor([query])
return this.executor(db, [query])
})
}

Expand All @@ -212,9 +223,14 @@ export class Database {
return Observable.fromPromise(prefetch.exec())
.concatMap((scopedIds) => {
const query = predicatableQuery(db, table, provider.getPredicate(), StatementType.Delete)
return this.executor([query])
.do(() => scopedIds.forEach((entity: any) =>
this.storedIds.delete(fieldIdentifier(tableName, entity[pk]))))

scopedIds.forEach((entity: any) =>
this.storedIds.delete(fieldIdentifier(tableName, entity[pk])))

return this.executor(db, [query]).do({ error: () => {
scopedIds.forEach((entity: any) =>
this.storedIds.add(fieldIdentifier(tableName, entity[pk])))
}})
})
})
}
Expand All @@ -233,10 +249,9 @@ export class Database {

this.traverseCompound(db, tableName, clone(raw), insert, update, sharing)
const { contextIds, queries } = Mutation.aggregate(db, insert, update)
return this.executor(queries)
.do(() => {
contextIds.forEach(id => this.storedIds.add(id))
})
contextIds.forEach(id => this.storedIds.add(id))
return this.executor(db, queries)
.do({ error: () => contextIds.forEach(id => this.storedIds.delete(id)) })
})
}

Expand Down Expand Up @@ -265,13 +280,15 @@ export class Database {
if (disposeHandler) {
const scope = this.createScopedHandler<T>(db, queries, removedIds)
return disposeHandler(rootEntities, scope)
.concatMap(() => this.executor(queries))
.do(() => removedIds.forEach((id: string) => this.storedIds.delete(id)))
.concatMap(() => this.executor(db, queries))
} else {
return this.executor(queries)
removedIds.forEach((id: string) => this.storedIds.delete(id))
return this.executor(db, queries)
}
})
.do(() => {
removedIds.forEach((id: string) => this.storedIds.delete(id))
.do({ error: () =>
removedIds.forEach((id: string) => this.storedIds.add(id))
})
})
}
Expand All @@ -284,15 +301,16 @@ export class Database {
const cleanup = this.database$.map(db =>
db.getSchema().tables().map(t => db.delete().from(t)))

return cleanup.concatMap(queries => this.executor(queries))
.concatMapTo(this.database$)
.do(db => {
db.close()
this.schemas.clear()
this.storedIds.clear()
this.schemaBuilder = null
this.subscription.unsubscribe()
})
return this.database$.concatMap(db => {
return cleanup.concatMap(queries => this.executor(db, queries))
.do(() => {
db.close()
this.schemas.clear()
this.storedIds.clear()
this.schemaBuilder = null
this.subscription.unsubscribe()
})
})
}

private buildTables() {
Expand Down Expand Up @@ -492,8 +510,8 @@ export class Database {
navigators.push(nav)
})

const onlyNavigator = fieldsValue.size === navigators.length &&
navigators.every((nav) => fieldsValue.has(nav))
const onlyNavigator = Array.from(fieldsValue.keys())
.every(key => contains(key, navigators))
assert(!onlyNavigator, Exception.InvalidQuery())

if (!hasKey) {
Expand Down Expand Up @@ -575,6 +593,7 @@ export class Database {
const ret =
this.traverseQueryFields(db, assocaiation.name, new Set(fields), containKey, glob, path.slice(0), context)
handleAdvanced(ret, ctx.key, assocaiation)
ctx.skip()
break
}
})
Expand Down Expand Up @@ -620,6 +639,11 @@ export class Database {
const isColumn = schema.columns.has(key)
const mapper = (isColumn && schema.mapper.get(key)) || null

if (!(isColumn || isNavigator || ctx.isRoot)) {
// 若当前节点非 有效节点、叶子节点或者根节点中任意一种时,直接停止子节点的迭代
ctx.skip()
}

return (ctx.isRoot || (!isColumn && !isNavigator)) ? false : {
mapper,
visited,
Expand All @@ -628,8 +652,9 @@ export class Database {
})

traversable.forEach((ctx, node) => {
// 考虑到叶节点可能存在`Object` type, 所以无论分支节点还是叶节点,其后的结构都不迭代
ctx.skip()
if (ctx.isNavigatorLeaf) {
ctx.skip()
const ref = schema.associations.get(ctx.key).name
return this.traverseCompound(db, ref, node, insertMutList, updateMutList, sharing)
}
Expand Down Expand Up @@ -707,22 +732,20 @@ export class Database {
}
}

private executor(queries: lf.query.Builder[]) {
return this.database$.concatMap(db => {
const tx = db.createTransaction()
const handler = {
error: () => warn(`Execute failed, transaction is already marked for rollback.`)
}
private executor(db: lf.Database, queries: lf.query.Builder[]) {
const tx = db.createTransaction()
const handler = {
error: () => warn(`Execute failed, transaction is already marked for rollback.`)
}

return Observable.fromPromise(tx.exec(queries))
.do(handler)
.map((ret) => {
return {
result: true,
...mergeTransactionResult(queries, ret)
}
})
})
return Observable.fromPromise(tx.exec(queries))
.do(handler)
.map((ret) => {
return {
result: true,
...mergeTransactionResult(queries, ret)
}
})
}

}
6 changes: 5 additions & 1 deletion src/storage/helper/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import * as Exception from '../../exception'
export function revise(relation: Relationship, def: Object) {
switch (relation) {
case Relationship.oneToOne:
forEach(def, (value) => value.id = value.id ? false : value.id)
forEach(def, (value) => {
if (value.id) {
value.id = false
}
})
break
case Relationship.oneToMany:
def = [def]
Expand Down
8 changes: 8 additions & 0 deletions src/utils/hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const hash = (str: string) => {
let ret = 0
for (let i = 0; i < str.length; i++) {
ret = ((ret << 5) - ret) + str.charCodeAt(i)
ret = ret & ret
}
return ret
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './hash'
export * from './clone'
export * from './valid'
export * from './option'
Expand Down
12 changes: 11 additions & 1 deletion test/specs/utils/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forEach, clone, getType, assert } from '../../index'
import { forEach, clone, getType, assert, hash } from '../../index'
import { describe, it } from 'tman'
import { expect } from 'chai'

Expand Down Expand Up @@ -397,4 +397,14 @@ export default describe('Utils Testcase: ', () => {

})

describe('Func: hash', () => {

it('should be able to convert string to hash', () => {
expect(hash('')).to.equal(0)
expect(hash(' ')).to.equal(32)
expect(hash(' ')).to.equal(1024)
})

})

})