mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
feat: entity schema support trees (#11606)
This commit is contained in:
parent
4f05718237
commit
925dee002b
@ -14,6 +14,7 @@ import { EntitySchemaExclusionOptions } from "./EntitySchemaExclusionOptions"
|
||||
import { EntitySchemaInheritanceOptions } from "./EntitySchemaInheritanceOptions"
|
||||
import { EntitySchemaRelationIdOptions } from "./EntitySchemaRelationIdOptions"
|
||||
import { EntitySchemaForeignKeyOptions } from "./EntitySchemaForeignKeyOptions"
|
||||
import { TreeMetadataArgs } from "../metadata-args/TreeMetadataArgs"
|
||||
|
||||
/**
|
||||
* Interface for entity metadata mappings stored inside "schemas" instead of models decorated by decorators.
|
||||
@ -135,4 +136,6 @@ export class EntitySchemaOptions<T> {
|
||||
* Custom discriminator value for Single Table Inheritance.
|
||||
*/
|
||||
discriminatorValue?: string
|
||||
|
||||
trees?: Omit<TreeMetadataArgs, "target">[]
|
||||
}
|
||||
|
||||
@ -396,5 +396,15 @@ export class EntitySchemaTransformer {
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (options.trees) {
|
||||
options.trees.forEach((tree) => {
|
||||
metadataArgsStorage.trees.push({
|
||||
target: options.target || options.name,
|
||||
type: tree.type,
|
||||
options: tree.options,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
import { EntitySchema } from "../../../../../../src"
|
||||
|
||||
export const Category = new EntitySchema<{
|
||||
id: number
|
||||
name: string
|
||||
parentCategory: any
|
||||
childCategories: any[]
|
||||
}>({
|
||||
name: "Category",
|
||||
columns: {
|
||||
id: {
|
||||
primary: true,
|
||||
type: Number,
|
||||
generated: "increment",
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
relations: {
|
||||
parentCategory: {
|
||||
type: "many-to-one",
|
||||
treeParent: true,
|
||||
target: "Category",
|
||||
},
|
||||
childCategories: {
|
||||
type: "one-to-many",
|
||||
treeChildren: true,
|
||||
target: "Category",
|
||||
cascade: true,
|
||||
},
|
||||
},
|
||||
trees: [{ type: "nested-set" }],
|
||||
})
|
||||
69
test/functional/entity-schema/trees/nested-set/nested-set.ts
Normal file
69
test/functional/entity-schema/trees/nested-set/nested-set.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import "reflect-metadata"
|
||||
import { Category } from "./entity/Category"
|
||||
|
||||
import { DataSource } from "../../../../../src"
|
||||
import {
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
closeTestingConnections,
|
||||
} from "../../../../utils/test-utils"
|
||||
|
||||
describe("entity-schema > tree tables > nested-set", () => {
|
||||
let connections: DataSource[]
|
||||
before(
|
||||
async () =>
|
||||
(connections = await createTestingConnections({
|
||||
entities: [Category],
|
||||
enabledDrivers: ["better-sqlite3"],
|
||||
})),
|
||||
)
|
||||
beforeEach(() => reloadTestingDatabases(connections))
|
||||
after(() => closeTestingConnections(connections))
|
||||
|
||||
it("attach should work properly", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
const categoryRepository =
|
||||
connection.getTreeRepository(Category)
|
||||
|
||||
const a1 = await categoryRepository.save({ name: "a1" })
|
||||
|
||||
const a11 = await categoryRepository.save({
|
||||
name: "a11",
|
||||
parentCategory: a1,
|
||||
})
|
||||
|
||||
await categoryRepository.save({
|
||||
name: "a111",
|
||||
parentCategory: a11,
|
||||
})
|
||||
|
||||
await categoryRepository.save({
|
||||
name: "a12",
|
||||
parentCategory: a1,
|
||||
})
|
||||
|
||||
const rootCategories = await categoryRepository.findRoots()
|
||||
rootCategories.should.be.eql([
|
||||
{
|
||||
id: 1,
|
||||
name: "a1",
|
||||
},
|
||||
])
|
||||
|
||||
const a11Parent = await categoryRepository.findAncestors(a11)
|
||||
const a11ParentNames = a11Parent.map((i) => i.name)
|
||||
a11ParentNames.length.should.be.equal(2)
|
||||
a11ParentNames.should.deep.include("a1")
|
||||
a11ParentNames.should.deep.include("a11")
|
||||
|
||||
const a1Children = await categoryRepository.findDescendants(a1)
|
||||
const a1ChildrenNames = a1Children.map((i) => i.name)
|
||||
a1ChildrenNames.length.should.be.equal(4)
|
||||
a1ChildrenNames.should.deep.include("a1")
|
||||
a1ChildrenNames.should.deep.include("a11")
|
||||
a1ChildrenNames.should.deep.include("a111")
|
||||
a1ChildrenNames.should.deep.include("a12")
|
||||
}),
|
||||
))
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user