Skip to content

Commit

Permalink
fix: fix performance issues in large records
Browse files Browse the repository at this point in the history
  • Loading branch information
dziraf committed Oct 28, 2020
1 parent e8d541d commit 05ea7ee
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 67 deletions.
10 changes: 5 additions & 5 deletions src/backend/adapters/record/base-record.ts
Expand Up @@ -112,7 +112,6 @@ class BaseRecord {
*/
async update(params): Promise<BaseRecord> {
try {
this.storeParams(params)
const returnedParams = await this.resource.update(this.id(), params)
this.storeParams(returnedParams)
} catch (e) {
Expand Down Expand Up @@ -223,10 +222,11 @@ class BaseRecord {
* @return {RecordJSON}
*/
toJSON(currentAdmin?: CurrentAdmin): RecordJSON {
const populated = Object.keys(this.populated).reduce((m, key) => ({
...m,
[key]: this.populated[key].toJSON(currentAdmin),
}), {})
const populated = Object.keys(this.populated).reduce((m, key) => {
m[key] = this.populated[key].toJSON(currentAdmin)

return m
}, {})
return {
params: this.params,
populated,
Expand Down
3 changes: 2 additions & 1 deletion src/backend/controllers/api-controller.ts
Expand Up @@ -149,7 +149,8 @@ class ApiController {
}
[record] = await populator([record])

const jsonWithRecord = await actionContext.action.handler(request, response, { ...actionContext, record })
actionContext.record = record
const jsonWithRecord = await actionContext.action.handler(request, response, actionContext)

if (jsonWithRecord && jsonWithRecord.record && jsonWithRecord.record.recordActions) {
return jsonWithRecord
Expand Down
6 changes: 1 addition & 5 deletions src/backend/decorators/resource/resource-decorator.ts
Expand Up @@ -184,11 +184,7 @@ class ResourceDecorator {
const property = this.properties[propertyName]

const subProperties = flatSubProperties(property)
return {
...memo,
[propertyName]: property.toJSON(),
...subProperties,
}
return Object.assign(memo, { [propertyName]: property.toJSON() }, subProperties)
}, {})
}

Expand Down
34 changes: 19 additions & 15 deletions src/backend/decorators/resource/utils/decorate-properties.ts
Expand Up @@ -21,7 +21,10 @@ const decorateDatabaseProperties = (
options: options.properties && options.properties[property.name()],
resource: decorator,
})
return { ...memo, [property.name()]: decoratedProperty }

memo[property.name()] = decoratedProperty

return memo
}, {} as DecoratedProperties)
}

Expand All @@ -37,16 +40,16 @@ const decorateVirtualProperties = (
const existingProperty = getPropertyByKey(key, dbProperties)
if (!existingProperty) {
const property = new BaseProperty({ path: key, isSortable: false })
return {
...memo,
[key]: new PropertyDecorator({
property,
admin,
options: options.properties && options.properties[key],
resource: decorator,
isVirtual: true,
}),
}

memo[key] = new PropertyDecorator({
property,
admin,
options: options.properties && options.properties[key],
resource: decorator,
isVirtual: true,
})

return memo
}
return memo
}, {} as DecoratedProperties)
Expand Down Expand Up @@ -88,10 +91,11 @@ const organizeNestedProperties = (
return true
})

return rootPropertyKeys.reduce((memo, key) => ({
...memo,
[key]: properties[key],
}), {} as DecoratedProperties)
return rootPropertyKeys.reduce((memo, key) => {
memo[key] = properties[key]

return memo
}, {} as DecoratedProperties)
}

/**
Expand Down
12 changes: 7 additions & 5 deletions src/backend/decorators/resource/utils/flat-sub-properties.ts
Expand Up @@ -16,9 +16,11 @@ import { PropertyJSON } from '../../../../frontend/interfaces'
export const flatSubProperties = (
rootProperty: PropertyDecorator,
): Record<string, PropertyJSON> => (
rootProperty.subProperties().reduce((subMemo, subProperty) => ({
...subMemo,
[subProperty.path]: subProperty.toJSON(),
...flatSubProperties(subProperty),
}), {})
rootProperty.subProperties().reduce((subMemo, subProperty) => {
return Object.assign(
subMemo,
{ [subProperty.path]: subProperty.toJSON() },
flatSubProperties(subProperty),
)
}, {})
)
11 changes: 6 additions & 5 deletions src/backend/utils/filter/filter.ts
Expand Up @@ -59,14 +59,15 @@ export class Filter {
constructor(filters = {}, resource) {
this.resource = resource
const normalized = Filter.normalizeKeys(filters)
this.filters = Object.keys(normalized).reduce((memo, path) => ({
[path]: {
this.filters = Object.keys(normalized).reduce((memo, path) => {
memo[path] = {
path,
property: this.resource.property(path),
value: normalized[path],
},
...memo,
}), {})
};

return memo;
}, {})
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/backend/utils/populator/populate-property.ts
Expand Up @@ -53,10 +53,10 @@ export const populateProperty = async (
if (!isValueSearchable(foreignKeyValue)) {
return memo
}
return {
...memo,
[foreignKeyValue]: foreignKeyValue,
}

memo[foreignKeyValue] = foreignKeyValue

return memo
}, {})

const uniqueExternalIds = Object.values<string | number>(externalIdsMap)
Expand Down
30 changes: 21 additions & 9 deletions src/backend/utils/request-parser/request-parser.ts
Expand Up @@ -32,25 +32,37 @@ export const requestParser = (

if (property) {
if (property.type() === 'boolean') {
if (value === 'true') { return { ...memo, [path]: true } }
if (value === 'false') { return { ...memo, [path]: false } }
if (value === '') { return { ...memo, [path]: false } }
if (value === 'true') {
memo[path] = true
return memo
}
if (value === 'false') {
memo[path] = false
return memo
}
if (value === '') {
memo[path] = false
return memo
}
}
if (['date', 'datetime'].includes(property.type())) {
if (value === '' || value === null) { return { ...memo, [path]: null } }
if (value === '' || value === null) {
memo[path] = null
return memo
}
}
if (property.type() === 'string') {
const availableValues = property.availableValues()
if (availableValues && !availableValues.includes(value) && value === '') {
return { ...memo, [path]: null }
memo[path] = null
return memo
}
}
}

return {
...memo,
[path]: value,
}
memo[path] = value

return memo
}, {})

return {
Expand Down
9 changes: 5 additions & 4 deletions src/utils/flat/filter-out-params.ts
Expand Up @@ -16,10 +16,11 @@ const filterOutParams = (params: FlattenParams, property: string): FlattenParams
// filter all keys which starts with property
return Object.keys(params)
.filter(key => !key.match(regex))
.reduce((memo, key) => ({
...memo,
[key]: (params[key] as string),
}), {} as FlattenParams)
.reduce((memo, key) => {
memo[key] = (params[key] as string)

return memo
}, {} as FlattenParams)
}

export { filterOutParams }
9 changes: 5 additions & 4 deletions src/utils/flat/get.ts
Expand Up @@ -29,10 +29,11 @@ const get = (params: FlattenParams = {}, propertyPath?: string): any => {
const regex = propertyKeyRegex(propertyPath)
const selectedParams = selectParams(params, propertyPath)

const nestedProperties = Object.keys(selectedParams).reduce((memo, key) => ({
...memo,
[key.replace(regex, `${TEMP_HOLDING_KEY}${DELIMITER}`)]: selectedParams[key],
}), {} as FlattenParams)
const nestedProperties = Object.keys(selectedParams).reduce((memo, key) => {
memo[key.replace(regex, `${TEMP_HOLDING_KEY}${DELIMITER}`)] = selectedParams[key]

return memo
}, {} as FlattenParams)

if (Object.keys(nestedProperties).length) {
return (unflatten(nestedProperties) as {})[TEMP_HOLDING_KEY]
Expand Down
6 changes: 2 additions & 4 deletions src/utils/flat/merge.ts
Expand Up @@ -10,13 +10,11 @@ import { set } from './set'
* @memberof flat
*/
export const merge = (params: any = {}, ...mergeParams: Array<any>): FlattenParams => {
const flattenParams = flatten(params)
const flattenParams = flatten(params) as any

// reverse because we merge from right
return mergeParams.reverse().reduce((globalMemo, mergeParam) => (
Object.keys(mergeParam)
.reduce((memo, key) => (
set(memo, key, mergeParam[key])
), globalMemo)
.reduce((memo, key) => (set(memo, key, mergeParam[key])), globalMemo)
), flattenParams as Record<string, any>)
}
9 changes: 5 additions & 4 deletions src/utils/flat/select-params.ts
Expand Up @@ -16,10 +16,11 @@ const selectParams = (params: FlattenParams, ...properties: Array<string>): Flat
const filtered = Object.keys(params)
// filter all keys which starts with property
.filter(key => key.match(regex))
.reduce((memo, key) => ({
...memo,
[key]: (params[key] as string),
}), {} as FlattenParams)
.reduce((memo, key) => {
memo[key] = (params[key] as string)

return memo
}, {} as FlattenParams)
return {
...globalMemo,
...filtered,
Expand Down
12 changes: 10 additions & 2 deletions src/utils/flat/set.ts
Expand Up @@ -26,7 +26,11 @@ const set = (params: FlattenParams = {}, propertyPath: string, value?: any): Fla
// remove all existing keys
const paramsCopy = Object.keys(params)
.filter(key => !key.match(regex))
.reduce((memo, key) => ({ ...memo, [key]: params[key] }), {} as FlattenParams)
.reduce((memo, key) => {
memo[key] = params[key]

return memo
}, {} as FlattenParams)

if (typeof value !== 'undefined') {
if (isObject(value)) {
Expand All @@ -51,7 +55,11 @@ const set = (params: FlattenParams = {}, propertyPath: string, value?: any): Fla
if (parts.length) {
return Object.keys(paramsCopy)
.filter(key => !parts.includes(key))
.reduce((memo, key) => ({ ...memo, [key]: paramsCopy[key] }), {} as FlattenParams)
.reduce((memo, key) => {
memo[key] = paramsCopy[key]

return memo
}, {} as FlattenParams)
}
}
return paramsCopy
Expand Down

0 comments on commit 05ea7ee

Please sign in to comment.