Skip to content

Commit

Permalink
feat(db-ql): add ejson support; add ObjectId & Binary support;
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Oct 15, 2021
1 parent be9eb27 commit 4471e6f
Show file tree
Hide file tree
Showing 19 changed files with 260 additions and 386 deletions.
14 changes: 7 additions & 7 deletions packages/database-ql/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/database-ql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"module": "dist/esm/index.js",
"scripts": {
"watch": "tsc -w",
"test": "mocha tests/*test.js",
"test": "mocha tests/units/*.test.js",
"build": "tsc -p tsconfig.json && tsc -p tsconfig.esm.json",
"eslint": "eslint \"./**/*.ts\"",
"fix": "eslint --fix \"./**/*.ts\"",
Expand Down Expand Up @@ -34,7 +34,7 @@
"typescript-eslint-parser": "^22.0.0"
},
"dependencies": {
"bson": "^4.0.2",
"bson": "^4.5.3",
"lodash.clonedeep": "4.5.0",
"lodash.set": "4.3.2",
"lodash.unset": "4.5.2"
Expand Down
6 changes: 3 additions & 3 deletions packages/database-ql/src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export class CollectionReference extends Query {
*
* @param docID - 文档ID
*/
doc(docID?: string | number): DocumentReference {
if (typeof docID !== 'string' && typeof docID !== 'number') {
throw new Error('docId 必须为字符串或数字')
doc(docID: string | number): DocumentReference {
if (!docID) {
throw new Error('docID cannot be empty')
}
return new DocumentReference(this._db, this._coll, docID)
}
Expand Down
4 changes: 3 additions & 1 deletion packages/database-ql/src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ const FieldType = {
Timestamp: 'Date',
Command: 'Command',
ServerDate: 'ServerDate',
BsonDate: 'BsonDate'
BsonDate: 'BsonDate',
ObjectId: 'ObjectId',
Binary: 'Binary'
}

/**
Expand Down
8 changes: 5 additions & 3 deletions packages/database-ql/src/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { UpdateCommand } from './commands/update'
import { QueryType } from './constant'
import { AddRes, GetOneRes, RemoveRes, UpdateRes } from './result-types'
import { RequestInterface } from './interface'
import { EJSON, ObjectId } from 'bson'
import { isObjectId } from './utils/type'
// import { Util } from './util'


Expand All @@ -17,7 +19,7 @@ export class DocumentReference {
/**
* 文档ID
*/
readonly id: string | number
readonly id: string | number | ObjectId

/**
*
Expand Down Expand Up @@ -58,10 +60,10 @@ export class DocumentReference {
* @param coll - 集合名称
* @param docID - 文档ID
*/
constructor(db: Db, coll: string, docID: string | number, projection = {}) {
constructor(db: Db, coll: string, docID: string | number | ObjectId, projection = {}) {
this._db = db
this._coll = coll
this.id = docID
this.id = isObjectId(docID) ? EJSON.serialize(docID) as ObjectId : docID
/* eslint-disable new-cap*/
this.request = this._db.request
this.projection = projection
Expand Down
9 changes: 9 additions & 0 deletions packages/database-ql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,13 @@ export class Db {
const id = new ObjectId()
return id.toHexString()
}

/**
* Wrapper for ObjectId() of mongodb
* @param params
* @returns
*/
ObjectId(id?: string | number | ObjectId) {
return new ObjectId(id)
}
}
10 changes: 6 additions & 4 deletions packages/database-ql/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UpdateSerializer } from './serializer/update'
import { ErrorCode } from './constant'
import { GetOneRes, GetRes, CountRes, UpdateRes, RemoveRes } from './result-types'
import { RequestInterface } from './interface'
import { Util } from './util'



Expand Down Expand Up @@ -172,7 +173,7 @@ export class Query {
* @param query
*/
public where(query: object) {
// query校验 1. 必填对象类型 2. value 不可均为undefiend
// query校验 1. 必填对象类型 2. value 不可均为 undefiend
if (Object.prototype.toString.call(query).slice(8, -1) !== 'Object') {
throw Error(ErrorCode.QueryParamTypeError)
}
Expand All @@ -187,10 +188,11 @@ export class Query {
throw Error(ErrorCode.QueryParamValueError)
}

const _query = QuerySerializer.encode(query)
return new Query(
this._db,
this._coll,
QuerySerializer.encode(query),
_query,
this._fieldOrders,
this._queryOptions,
this._joins,
Expand Down Expand Up @@ -459,9 +461,9 @@ export class Query {
}
}

// const documents = Util.formatResDocumentData(res.data.list)
const documents = Util.formatResDocumentData(res.data.list)
const result: any = {
data: res.data.list,
data: documents,
requestId: res.requestId,
ok: true
}
Expand Down
10 changes: 8 additions & 2 deletions packages/database-ql/src/serializer/common.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getType, isObject, isArray, isDate, isRegExp, isInternalObject } from '../utils/type'
import { getType, isObject, isArray, isDate, isRegExp, isInternalObject, isObjectId } from '../utils/type'
import { serialize as serializeInternalDataType, deserialize as deserializeInternalDataType } from './datatype'
import { LogicCommand } from '../commands/logic'

Expand Down Expand Up @@ -98,8 +98,14 @@ export function mergeConditionAfterEncode(query: Record<string, any>, condition:
}
}

/**
* Check `val` if `InternalObject` | `Date` | `RegExp` | `ObjectId`
* InternalObject can be: `LogicCommand` | `QueryCommand` | `UpdateCommand`
* @param val
* @returns
*/
export function isConversionRequired(val: any): boolean {
return isInternalObject(val) || isDate(val) || isRegExp(val)
return isInternalObject(val) || isDate(val) || isRegExp(val) || isObjectId(val)
}

export function encodeInternalDataType(val: any): IQueryCondition {
Expand Down
14 changes: 4 additions & 10 deletions packages/database-ql/src/serializer/datatype.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// transpile internal data type
import { SYMBOL_GEO_POINT, SYMBOL_SERVER_DATE, SYMBOL_REGEXP } from '../helper/symbol'
import { getType, isObject, isArray, isDate, isNumber, isInternalObject, isRegExp } from '../utils/type'
import { getType, isObject, isArray, isDate, isNumber, isInternalObject, isRegExp, isObjectId, isBinary } from '../utils/type'
import { Point } from '../geo/index'
import { ServerDate } from '../serverDate/index'
import { RegExp } from '../regexp/index'
import { LogicCommand } from '../commands/logic'
import { EJSON } from 'bson'

export type IQueryCondition = Record<string, any> | LogicCommand

Expand Down Expand Up @@ -35,15 +36,8 @@ function serializeHelper(
return val.toJSON ? val.toJSON() : val
}
}
} else if (isDate(val)) {
return {
$date: +val,
}
} else if (isRegExp(val)) {
return {
$regex: val.source,
$options: val.flags,
}
} else if (isDate(val) || isRegExp(val) || isObjectId(val) || isBinary(val)) {
return EJSON.serialize(val)
} else if (isArray(val)) {
return val.map(item => {
if (visited.indexOf(item) > -1) {
Expand Down
2 changes: 1 addition & 1 deletion packages/database-ql/src/serializer/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
export type IQueryCondition = Record<string, any> | LogicCommand

export class QuerySerializer {
constructor() {}
constructor() { }

static encode(
query: IQueryCondition | QueryCommand | LogicCommand
Expand Down
2 changes: 1 addition & 1 deletion packages/database-ql/src/serializer/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface IPushModifiers {
}

export class UpdateSerializer {
private constructor() {}
private constructor() { }

static encode(query: IQueryCondition | UpdateCommand): IUpdateCondition {
const stringifier = new UpdateSerializer()
Expand Down
16 changes: 15 additions & 1 deletion packages/database-ql/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Binary, EJSON, ObjectId } from 'bson'
import { FieldType } from './constant'
import { Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon } from './geo/index'
import { ServerDate } from './serverDate/index'
Expand Down Expand Up @@ -87,7 +88,12 @@ export class Util {
case FieldType.ServerDate:
realValue = new Date(item.$date)
break

case FieldType.ObjectId:
realValue = EJSON.deserialize(item)
break
case FieldType.Binary:
realValue = EJSON.deserialize(item)
break
default:
realValue = item
}
Expand Down Expand Up @@ -124,6 +130,10 @@ export class Util {
obj instanceof ServerDate
) {
return FieldType.ServerDate
} else if (obj instanceof ObjectId) {
return FieldType.ObjectId
} else if (obj instanceof Binary) {
return FieldType.Binary
}

if (obj.$timestamp) {
Expand All @@ -142,6 +152,10 @@ export class Util {
type = FieldType.GeoMultiLineString
} else if (MultiPolygon.validate(obj)) {
type = FieldType.GeoMultiPolygon
} else if (obj.$oid) {
type = FieldType.ObjectId
} else if (obj.$binary) {
type = FieldType.Binary
}
}
return type
Expand Down
14 changes: 14 additions & 0 deletions packages/database-ql/src/utils/type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Binary, ObjectId } from 'bson'
import { InternalSymbol } from './symbol'

export const getType = (x: any): string => Object.prototype.toString.call(x).slice(8, -1).toLowerCase()
Expand All @@ -19,6 +20,11 @@ export const isDate = (x: any): x is Date => getType(x) === 'date'

export const isRegExp = (x: any): x is RegExp => getType(x) === 'regexp'

/**
* Internal Object can be: `LogicCommand` | `QueryCommand` | `UpdateCommand`
* @param x
* @returns
*/
export const isInternalObject = (x: any): boolean => x && (x._internalType instanceof InternalSymbol)

export const isPlainObject = (obj: any): obj is object => {
Expand All @@ -31,3 +37,11 @@ export const isPlainObject = (obj: any): obj is object => {

return Object.getPrototypeOf(obj) === proto
}

export const isObjectId = (x: any): x is ObjectId => {
return x?._bsontype === 'ObjectID'
}

export const isBinary = (x: any): x is Binary => {
return x?._bsontype === 'Binary'
}
53 changes: 0 additions & 53 deletions packages/database-ql/tests/geo_test.js

This file was deleted.

Loading

0 comments on commit 4471e6f

Please sign in to comment.