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

Association query #19

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4090743
refactor(PredicateProvider): PredicateProvider now support multiple t…
Brooooooklyn Aug 7, 2017
c2afc44
feat(PredicateProvider): support deep nested association query
Brooooooklyn Aug 9, 2017
8dc5817
feat(Database): support association query without association fields
Brooooooklyn Aug 9, 2017
fa16011
test(PredicateProvider): add test for tableName missmatch in Predicat…
Brooooooklyn Aug 9, 2017
f193d6c
feat(Database): support nested predicate key
Brooooooklyn Aug 10, 2017
96261a7
fix(Database#remove): stop passing Clause to PredicateProvider, inste…
Brooooooklyn Aug 16, 2017
7f4ecd2
chore: display report coverage after run coverage
Brooooooklyn Aug 17, 2017
5ce4099
feat(Database): warn if delete/remove/update all table
Brooooooklyn Aug 17, 2017
4f0b237
feat(utils/keys): use keys as alias for Object.keys
Brooooooklyn Aug 17, 2017
1355358
fix: workaround for yarn bug: 4290
Brooooooklyn Aug 31, 2017
31fd983
fix(association-query): fix for reviews
Brooooooklyn Aug 19, 2017
62c6252
feat(Database#get): restrict Associated Field position in Fields
Brooooooklyn Aug 31, 2017
46b3fa0
refactor(Database): introduce merge-fields in utils, use merge fields…
Brooooooklyn Aug 31, 2017
4509849
test(TaskSchema): add tasklist schema, add more nested predicate case
Brooooooklyn Sep 1, 2017
b93e9d3
refactor(PredicateProvidor): use new parse-predicate helper to parse …
Brooooooklyn Sep 6, 2017
2ccf2ee
chore: yarn upgrade
Brooooooklyn Aug 17, 2017
a07455d
docs(QueryDescription): update docs, add fields description & update …
Brooooooklyn Sep 6, 2017
d78d3a1
chore: code cleanup
Brooooooklyn Sep 7, 2017
9e7db4a
chore: fix code-style
Sep 14, 2017
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
78 changes: 72 additions & 6 deletions docs/API-description/QueryDescription.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## QueryDescription
## Query

```ts
interface QueryDescription<T> extends ClauseDescription<T> {
fields?: FieldsValue[]
interface Query<T> extends Clause<T> {
fields?: Field[]
limit?: number
skip?: number
orderBy?: OrderDescription[]
}

interface ClauseDescription<T> {
interface Clause<T> {
where?: PredicateDescription<T>
}

Expand All @@ -26,7 +26,7 @@ interface OrderDescription {
</tr>
<tr>
<td>fields</td>
<td>查询哪些字段,数组,合法值为字符串或字面量对象</td>
<td>查询哪些字段,数组,合法值为字符串或字面量对象, 详细定义: <a href='#fields'>fields</a></td>
</tr>
<tr>
<td>limit</td>
Expand Down Expand Up @@ -80,6 +80,72 @@ interface OrderDescription {
}
```

<h2 id='fields'>Fields</h2>

### Description

fields 是一个数组,其中的值可为 string | Field 它的形状为:

```ts
type Field<T> = [...keyof T[], VirtualField<T>]

type Field<T> = {
[key in keyof T]: [...keyof (key in keyof T), Field<T[key]>]
}
```
> 注,源码里面并没有 VirtualField 这个类型,这里只是为了描述它的形状而用 `VirtualField` 来表达

其中,可以包含一个 `VirtualField` 类型的元素,用来查询`关联表`的数据,它必须位于数组的最后,不然会抛出一个类型错误。
`VirtualField` 的每一个字段的 key 都对应着查询的数据表上对应的 schema 上定义了 `virtual` 的字段,对应的值则是对应的 `Table` 的形状。

### example:

```ts
// query
database.get('Task', {
fields: ['_id', 'content', {
project: ['_id', 'name', {
organization: ['_id']
}]
}]
})

// schema definations
database.defineSchema('Task', {
_id: {
type: RDBType.string,
primaryKey: true
},
project: {
type: Relationship.oneToOne,
virtual: {
name: 'Project',
where: ref => {
return {
_projectId: ref._id
}
}
}
},
})

database.defineSchema('Project', {
_id: {
type: RDBType.string,
primaryKey: true
},
organization: {
type: Relationship.oneToOne,
virtual: {
name: 'Organization',
where: (organizationTable) => ({
_organizationId: organizationTable._id
})
}
}
})
```

<h2 id="OrderDescription">OrderDescription</h2>


Expand Down Expand Up @@ -167,7 +233,7 @@ interface PredicateMeta<T> {
}
}
```
默认表示 `lf.op.and(taskTable.dueDate.lte(...), taskTable.startDate.gte(...) )`
默认表示 `dueDate` 小于或等于七天后 ***并且*** `startDate` 大于或等于一天后

### *example:*
```ts
Expand Down
49 changes: 25 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
"clean_dist_cjs": "rm -rf ./dist/cjs",
"clean_dist_es": "rm -rf ./dist/es",
"check_circular_dependencies": "madge ./dist/cjs --circular",
"compile_cjs": " tsc dist/cjs/src/index.ts dist/cjs/src/proxy/index.ts -m commonjs --outDir dist/cjs --sourcemap --target ES5 -d --diagnostics --pretty --strict --noImplicitReturns --noUnusedLocals --noUnusedParameters --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --importHelpers --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom",
"compile_module_es": "tsc dist/es/src/index.ts dist/es/src/proxy/index.ts -m ES2015 --outDir dist/es --sourcemap --target ES5 -d --diagnostics --pretty --strict --noImplicitReturns --noUnusedLocals --noUnusedParameters --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --importHelpers --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom",
"compile_cjs": " tsc dist/cjs/src/index.ts dist/cjs/src/proxy/index.ts -m commonjs --outDir dist/cjs --sourcemap --target ES5 -d --diagnostics --pretty --strict --noImplicitReturns --noUnusedLocals --noUnusedParameters --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --importHelpers --downlevelIteration --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom",
"compile_module_es": "tsc dist/es/src/index.ts dist/es/src/proxy/index.ts -m ES2015 --outDir dist/es --sourcemap --target ES5 -d --diagnostics --pretty --strict --noImplicitReturns --noUnusedLocals --noUnusedParameters --suppressImplicitAnyIndexErrors --moduleResolution node --noEmitHelpers --importHelpers --downlevelIteration --lib es5,es2015.iterable,es2015.collection,es2015.promise,dom",
"copy_src_cjs": "shx mkdir -p ./dist/cjs/src && shx cp -r ./src/* ./dist/cjs/src",
"copy_src_es": "shx mkdir -p ./dist/es/src && shx cp -r ./src/* ./dist/es/src",
"cover": "rm -rf ./.nyc_output ./coverage && NODE_ENV=test nyc --reporter=html --reporter=lcov --exclude=node_modules --exclude=spec-js/test --exclude=spec-js/src/storage/lovefield.js --exclude=spec-js/src/shared/Logger.js --exclude=spec-js/src/utils/option.js --exclude=spec-js/src/utils/valid.js tman --mocha spec-js/test/run.js",
"cover": "rm -rf ./.nyc_output ./coverage && NODE_ENV=test nyc --reporter=html --reporter=lcov --exclude=node_modules --exclude=spec-js/test --exclude=spec-js/src/storage/lovefield.js --exclude=spec-js/src/shared/Logger.js --exclude=spec-js/src/utils/option.js --exclude=spec-js/src/utils/valid.js tman --mocha spec-js/test/run.js && nyc report",
"lint": "tslint -c tslint.json src/*.ts --project ./tsconfig.json --type-check src/**/*.ts ./test/**/*.ts -e ./test/e2e/*.ts",
"postinstall": "cd ./node_modules/.bin && shx ln -sf ../typescript/bin/tsc ./tsc",
"publish_all": "ts-node ./tools/publish.ts",
"start": "webpack-dev-server --inline --colors --progress --port 3000",
"start-demo": "webpack-dev-server --config ./example/webpack.config.js --inline --colors --progress --port 3001 --open",
Expand Down Expand Up @@ -59,42 +60,42 @@
},
"license": "MIT",
"devDependencies": {
"@types/chai": "^4.0.1",
"@types/node": "^8.0.14",
"@types/chai": "^4.0.4",
"@types/node": "^8.0.26",
"@types/shelljs": "^0.7.4",
"@types/sinon": "^2.3.3",
"@types/sinon-chai": "^2.7.28",
"awesome-typescript-loader": "^3.2.1",
"chai": "^4.1.0",
"@types/sinon-chai": "^2.7.29",
"awesome-typescript-loader": "^3.2.3",
"chai": "^4.1.2",
"coveralls": "^2.13.1",
"css-loader": "^0.28.4",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.0",
"happypack": "^3.0.3",
"html-webpack-plugin": "^2.29.0",
"madge": "^2.0.0",
"happypack": "^4.0.0-beta.5",
"html-webpack-plugin": "^2.30.1",
"madge": "^2.2.0",
"moment": "^2.18.1",
"node-watch": "^0.5.5",
"npm-run-all": "^4.0.2",
"nyc": "^11.0.3",
"npm-run-all": "^4.1.1",
"nyc": "^11.2.0",
"raw-loader": "^0.5.1",
"rxjs": "^5.4.2",
"rxjs": "^5.4.3",
"shelljs": "^0.7.8",
"shx": "^0.2.2",
"sinon": "^3.0.0",
"sinon-chai": "^2.11.0",
"sinon": "^3.2.1",
"sinon-chai": "^2.13.0",
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
"tman": "^1.7.1",
"ts-node": "^3.2.0",
"tslint": "^5.5.0",
"tman": "^1.7.2",
"ts-node": "^3.3.0",
"tslint": "^5.7.0",
"tslint-eslint-rules": "^4.1.1",
"tslint-loader": "^3.5.3",
"typescript": "^2.4.2",
"webpack": "^3.3.0",
"webpack-dev-server": "^2.5.1"
"typescript": "^2.5.2",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1"
},
"dependencies": {
"@types/lovefield": "^2.0.32",
"@types/lovefield": "^2.1.1",
"lovefield": "2.1.12",
"nesthydrationjs": "^1.0.2"
},
Expand Down
9 changes: 6 additions & 3 deletions src/exception/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ export const NonExistentTable =
export const UnmodifiableTable =
() => new ReactiveDBException(`Method: defineSchema cannot be invoked since schema is existed or database is connected`)

export const InvalidQuery =
() => new ReactiveDBException('Only navigation properties were included in query.')

export const AliasConflict =
(column: string, tableName: string) => new ReactiveDBException(`Definition conflict, Column: \`${column}\` on table: ${tableName}.`)

Expand Down Expand Up @@ -41,3 +38,9 @@ export const DatabaseIsNotEmpty =

export const NotConnected =
() => new ReactiveDBException('Method: dispose cannnot be invoked before database is connected.')

export const FieldMustBeArray =
(field: any) => new ReactiveDBException(`Field must be Array, but got: ${ JSON.stringify(field) }`)

export const AssociatedFieldsPostionError =
() => new ReactiveDBException(`Associated fields description must be the last item in Fields`)
12 changes: 8 additions & 4 deletions src/interface/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,7 @@ export type SchemaDisposeFunction<T> =

export interface ShapeMatcher {
mainTable: lf.schema.Table
pk: {
name: string,
queried: boolean
}
pk: string
definition: Object
}

Expand Down Expand Up @@ -174,3 +171,10 @@ export type Predicate<T> = {
}

export { StatementType, JoinMode, LeafType, Relationship, DataStoreType, RDBType }

export interface TablesStruct {
[index: string]: {
table: lf.schema.Table
contextName?: string
}
}
4 changes: 2 additions & 2 deletions src/shared/Traversable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forEach, getType } from '../utils'
import { forEach, getType, keys } from '../utils'
import { TraverseContext } from '../interface'

export class Traversable<T> {
Expand Down Expand Up @@ -29,7 +29,7 @@ export class Traversable<T> {
} else if (target && typeof target.keys === 'function') {
return Array.from(target.keys())
} else {
return (typeof target === 'object' && target !== null) || Array.isArray(target) ? Object.keys(target) : []
return (typeof target === 'object' && target !== null) || Array.isArray(target) ? keys(target) : []
}
}
}
Expand Down
Loading