feat: refactor entity classes to use mixins, add rateable mixin to book and copy
This commit is contained in:
parent
8bfaba185b
commit
2006815b2b
|
@ -1,7 +1,7 @@
|
|||
import { Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
export abstract class Base {
|
||||
export class BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
public id: number;
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import { Entity, ManyToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Book } from './book';
|
||||
|
||||
@Entity()
|
||||
export class Author extends MultiNamed {
|
||||
export class Author extends MultiNamed(BaseEntity) {
|
||||
@ManyToMany(() => Book, {
|
||||
nullable: false,
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { Column, Entity } from 'typeorm';
|
||||
import { Base } from '../../base';
|
||||
|
||||
@Entity()
|
||||
export abstract class MultiNamed extends Base {
|
||||
export function MultiNamed<T extends Constructor>(BaseClass: T) {
|
||||
@Entity()
|
||||
class MixinClass extends BaseClass {
|
||||
@Column()
|
||||
public nameCanonical: string;
|
||||
|
||||
@Column('simple-array')
|
||||
public names: string[];
|
||||
}
|
||||
|
||||
return MixinClass;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import { Column, Entity } from 'typeorm';
|
||||
|
||||
export function Rateable<T extends Constructor>(BaseClass: T) {
|
||||
@Entity()
|
||||
class MixinClass extends BaseClass {
|
||||
@Column({ nullable: true })
|
||||
public rating: number;
|
||||
}
|
||||
|
||||
return MixinClass;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": ["../../../../../tslint.json"],
|
||||
"rules": {
|
||||
"typedef": false
|
||||
}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
import { Entity, JoinTable, ManyToMany, OneToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { Author } from './author';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Rateable } from './base/rateable';
|
||||
import { Character } from './character';
|
||||
import { Copy } from './copy';
|
||||
import { Fiction } from './fiction';
|
||||
import { Tag } from './tag';
|
||||
|
||||
@Entity()
|
||||
export class Book extends MultiNamed {
|
||||
export class Book extends Rateable(MultiNamed(BaseEntity)) {
|
||||
@OneToMany(
|
||||
() => Copy,
|
||||
(copy: Copy) => copy.original,
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Entity, ManyToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Book } from './book';
|
||||
import { Fiction } from './fiction';
|
||||
|
||||
@Entity()
|
||||
export class Character extends MultiNamed {
|
||||
export class Character extends MultiNamed(BaseEntity) {
|
||||
@ManyToMany(() => Book, {
|
||||
nullable: false,
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Column, Entity, ManyToOne } from 'typeorm';
|
||||
import { Base } from '../base';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { Copy } from './copy';
|
||||
|
||||
const enum CopyTypes {
|
||||
|
@ -10,7 +10,7 @@ const enum CopyTypes {
|
|||
}
|
||||
|
||||
@Entity()
|
||||
export class CopyType extends Base {
|
||||
export class CopyType extends BaseEntity {
|
||||
@ManyToOne(
|
||||
() => Copy,
|
||||
(copy: Copy) => copy.types,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Column, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany } from 'typeorm';
|
||||
import { Base } from '../base';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { Rateable } from './base/rateable';
|
||||
import { Book } from './book';
|
||||
import { CopyType } from './copy-type';
|
||||
import { Language } from './language';
|
||||
|
@ -7,7 +8,7 @@ import { Source } from './source';
|
|||
import { Translator } from './translator';
|
||||
|
||||
@Entity()
|
||||
export class Copy extends Base {
|
||||
export class Copy extends Rateable(BaseEntity) {
|
||||
@ManyToOne(
|
||||
() => Book,
|
||||
(book: Book) => book.copies,
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Entity, ManyToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Book } from './book';
|
||||
import { Character } from './character';
|
||||
|
||||
@Entity()
|
||||
export class Fiction extends MultiNamed {
|
||||
export class Fiction extends MultiNamed(BaseEntity) {
|
||||
@ManyToMany(() => Book, {
|
||||
nullable: false,
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Column, Entity, ManyToMany } from 'typeorm';
|
||||
import { Base } from '../base';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { Copy } from './copy';
|
||||
|
||||
@Entity()
|
||||
export class Language extends Base {
|
||||
export class Language extends BaseEntity {
|
||||
@Column({
|
||||
nullable: false,
|
||||
unique: true,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Entity, OneToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Source } from './source';
|
||||
|
||||
@Entity()
|
||||
export class Site extends MultiNamed {
|
||||
export class Site extends MultiNamed(BaseEntity) {
|
||||
@OneToMany(
|
||||
() => Source,
|
||||
(source: Source) => source.site,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Column, Entity, ManyToMany, ManyToOne } from 'typeorm';
|
||||
import { Base } from '../base';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { Copy } from './copy';
|
||||
import { Site } from './site';
|
||||
|
||||
@Entity()
|
||||
export class Source extends Base {
|
||||
export class Source extends BaseEntity {
|
||||
@Column({
|
||||
nullable: false,
|
||||
unique: true,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Entity, ManyToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Book } from './book';
|
||||
|
||||
@Entity()
|
||||
export class Tag extends MultiNamed {
|
||||
export class Tag extends MultiNamed(BaseEntity) {
|
||||
@ManyToMany(() => Book, {
|
||||
nullable: false,
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Entity, ManyToMany } from 'typeorm';
|
||||
import { BaseEntity } from '../base-entity';
|
||||
import { MultiNamed } from './base/multi-named';
|
||||
import { Copy } from './copy';
|
||||
|
||||
@Entity()
|
||||
export class Translator extends MultiNamed {
|
||||
export class Translator extends MultiNamed(BaseEntity) {
|
||||
@ManyToMany(() => Copy, {
|
||||
nullable: false,
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class addRating1574452206367 implements MigrationInterface {
|
||||
name = 'addRating1574452206367';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_copy" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "favorited" boolean NOT NULL DEFAULT (0), "isDigital" boolean NOT NULL, "originalId" integer NOT NULL, "rating" integer, CONSTRAINT "FK_e8ce0011cf0a8b9fdc8ad908a44" FOREIGN KEY ("originalId") REFERENCES "book" ("id") ON DELETE CASCADE ON UPDATE CASCADE)`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_copy"("id", "favorited", "isDigital", "originalId") SELECT "id", "favorited", "isDigital", "originalId" FROM "copy"`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "copy"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "temporary_copy" RENAME TO "copy"`, undefined);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_book" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "nameCanonical" varchar NOT NULL, "names" text NOT NULL, "rating" integer)`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_book"("id", "nameCanonical", "names") SELECT "id", "nameCanonical", "names" FROM "book"`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "book"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "temporary_book" RENAME TO "book"`, undefined);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "book" RENAME TO "temporary_book"`, undefined);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "book" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "nameCanonical" varchar NOT NULL, "names" text NOT NULL)`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "book"("id", "nameCanonical", "names") SELECT "id", "nameCanonical", "names" FROM "temporary_book"`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_book"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "copy" RENAME TO "temporary_copy"`, undefined);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "copy" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "favorited" boolean NOT NULL DEFAULT (0), "isDigital" boolean NOT NULL, "originalId" integer NOT NULL, CONSTRAINT "FK_e8ce0011cf0a8b9fdc8ad908a44" FOREIGN KEY ("originalId") REFERENCES "book" ("id") ON DELETE CASCADE ON UPDATE CASCADE)`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "copy"("id", "favorited", "isDigital", "originalId") SELECT "id", "favorited", "isDigital", "originalId" FROM "temporary_copy"`,
|
||||
undefined
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_copy"`, undefined);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": ["../../../../tslint.json"],
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"member-access": false,
|
||||
"typedef": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
type Constructor<T = {}> = new (...args: any[]) => T;
|
Loading…
Reference in New Issue