Skip to content

Commit

Permalink
add KnexNode.getDescendants
Browse files Browse the repository at this point in the history
  • Loading branch information
a179346 committed Aug 16, 2021
1 parent bc22a9a commit 8098c48
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ yarn-error.log*
lerna-debug.log*
.vscode

src/test/test.ts

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ const data = await node.getPathUpTo(7);
// return the path from this node to the descendant(id = 7)
const data = await node.getPathDownTo(7);
```
##### `KnexNode.getDescendants(maxLevel?)` => `Promise<(Model & ITreeLv)[] | null>`
```js
// data is null if this.id doesn't exist
// return all descendants
let data = await node.getDescendants();

// return all descendants whose TreeLv <= 2
data = await node.getDescendants(2);
```

## 🙋‍♂️ Author

Expand Down
25 changes: 25 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export class KnexNode<IdType, Model> implements INode<IdType, Model> {
}

async hasChild (id: IdType): Promise<Model | null> {
if (id === this.id) return null;
const where: any = {};
where[this.options.idColumn] = id;
where[this.options.parentIdColumn] = this.id;
Expand All @@ -112,6 +113,7 @@ export class KnexNode<IdType, Model> implements INode<IdType, Model> {
}

async hasParent (id: IdType): Promise<Model | null> {
if (id === this.id) return null;
const where: any = {};
where[`n.${this.options.idColumn}`] = this.id;
where[`p.${this.options.idColumn}`] = id;
Expand Down Expand Up @@ -178,4 +180,27 @@ export class KnexNode<IdType, Model> implements INode<IdType, Model> {
});
return result.reverse();
}

async getDescendants (maxLevel?: number): Promise<(Model & ITreeLv)[] | null> {
const result = await this.options.db
.withRecursive('pt', (qb) => {
qb.select([ this.options.table + '.*', this.options.db.raw('0 as `TreeLv`') ])
.from(this.options.table)
.where(this.options.table + '.' + this.options.idColumn, this.id as unknown as string)
.union((qb) => {
qb.select([ 'p.*', this.options.db.raw('`TreeLv` + 1') ])
.from(this.options.db.raw('`' + this.options.table + '` as `p`, `pt` as `n`'))
.whereRaw('p.' + this.options.parentIdColumn + ' = n.' + this.options.idColumn)
.andWhereRaw('p.' + this.options.idColumn + ' != n.' + this.options.idColumn);
if (maxLevel)
qb.andWhere('n.TreeLv', '<', maxLevel);
});
})
.select('*').from('pt');

if (!result || result.length < 1)
return null;
result.shift();
return result;
}
}
2 changes: 2 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface INode<IdType, Model> {

getPathUpTo(id: IdType, maxLevel?: number): Promise<(Model & ITreeLv)[] | null>;
getPathDownTo(id: IdType, maxLevel?: number): Promise<(Model & ITreeLv)[] | null>;

getDescendants(maxLevel?: number): Promise<(Model & ITreeLv)[] | null>;
}

export interface ITree<IdType, Model> {
Expand Down

0 comments on commit 8098c48

Please sign in to comment.