Skip to content

Commit

Permalink
include parent id
Browse files Browse the repository at this point in the history
  • Loading branch information
shashankbrgowda committed Feb 22, 2024
1 parent 955d683 commit 26d8a7d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class Feature {}
import { Types } from 'mongoose'

export interface FeatureObject {
_id: string
gffId: string
refSeq: Types.ObjectId
allIds: string[]
type: string
start: number
end: number
discontinuousLocations?: { start: number; end: number; phase?: 0 | 1 | 2 }[]
strand?: 1 | -1
score?: number
phase?: 0 | 1 | 2
attributes?: Record<string, string[]>
children?: Map<string, FeatureObject>
status: number
user: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ export class FeaturesController {
/**
* Get feature by featureId. When retrieving features by id, the features and any of its children are returned, but not any of its parent or sibling features.
* @param featureid - featureId
* @param parentId - If true, the parent feature id is also returned
* @returns Return 'HttpStatus.OK' and the feature(s) if search was successful
* or if search data was not found or in case of error throw exception
*/
@Validations(Role.ReadOnly)
@Get(':featureid')
getFeature(@Param('featureid') featureid: string) {
this.logger.debug(`Get feature by featureId: ${featureid}`)
return this.featuresService.findById(featureid)
getFeature(
@Param('featureid') featureid: string,
@Query('parentId') parentId: string,
) {
return this.featuresService.findById(featureid, parentId === 'true')
}

@Public()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ChecksService } from '../checks/checks.service'
import { FeatureRangeSearchDto } from '../entity/gff3Object.dto'
import { OperationsService } from '../operations/operations.service'
import { FeatureCountRequest } from './dto/feature.dto'
import { FeatureObject } from './entities/feature.entity'

@Injectable()
export class FeaturesService {
Expand Down Expand Up @@ -70,9 +71,10 @@ export class FeaturesService {
/**
* Get feature by featureId. When retrieving features by id, the features and any of its children are returned, but not any of its parent or sibling features.
* @param featureId - featureId
* @param parentId - If true, the parent feature id is also returned
* @returns Return the feature(s) if search was successful. Otherwise throw exception
*/
async findById(featureId: string) {
async findById(featureId: string, includeParentId: boolean) {
// Search correct feature
const topLevelFeature = await this.featureModel
.findOne({ allIds: featureId })
Expand All @@ -84,8 +86,16 @@ export class FeaturesService {
throw new NotFoundException(errMsg)
}

const topLevelFeatureObject: FeatureObject = JSON.parse(
JSON.stringify(topLevelFeature),
) as FeatureObject

// Now we need to find correct top level feature or sub-feature inside the feature
const foundFeature = this.getFeatureFromId(topLevelFeature, featureId)
const foundFeature = this.getFeatureFromId(
topLevelFeatureObject,
featureId,
includeParentId,
)
if (!foundFeature) {
const errMsg = 'ERROR when searching feature by featureId'
this.logger.error(errMsg)
Expand All @@ -97,14 +107,18 @@ export class FeaturesService {

/**
* Get single feature by featureId
* @param featureOrDocument -
* @param featureId -
* @returns
* @param feature - FeatureObject
* @param featureId - featureId
* @param includeParentId - If true, the parent feature id is also returned
* @returns FeatureObject | null
*/
getFeatureFromId(feature: Feature, featureId: string): Feature | null {
getFeatureFromId(
feature: FeatureObject,
featureId: string,
includeParentId: boolean,
): FeatureObject | null {
this.logger.verbose(`Entry=${JSON.stringify(feature)}`)

if (feature._id.equals(featureId)) {
if (feature._id.toString() === featureId.toString()) {
this.logger.debug(
`Top level featureId matches in object ${JSON.stringify(feature)}`,
)
Expand All @@ -115,9 +129,22 @@ export class FeaturesService {
this.logger.debug(
'FeatureId was not found on top level so lets make recursive call...',
)
for (const [, childFeature] of feature.children ?? new Map()) {
const subFeature = this.getFeatureFromId(childFeature, featureId)
for (const [, childFeature] of new Map(
Object.entries(feature.children ?? {}),
)) {
const subFeature = this.getFeatureFromId(
childFeature,
featureId,
includeParentId,
)
if (subFeature) {
if (
subFeature?.attributes &&
includeParentId &&
!subFeature.attributes.parent_id
) {
subFeature.attributes.parent_id = [feature._id.toString()]
}
return subFeature
}
}
Expand Down

0 comments on commit 26d8a7d

Please sign in to comment.