21
loading...
This website collects cookies to deliver better user experience
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity('author')
export class Author {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
}
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity('genre')
export class Genre {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
}
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn} from "typeorm";
import { Author } from "./author";
import { Genre } from "./genre";
@Entity('book')
export class Book {
@PrimaryGeneratedColumn()
id: number = -1;
@Column({
name: 'name',
type: 'text',
nullable: false
})
name: string = '';
@ManyToOne(type => Author)
@JoinColumn({ name: 'authorId', referencedColumnName: 'id' })
author: Author = new Author();
@ManyToOne(type => Genre)
@JoinColumn({ name: 'genreId', referencedColumnName: 'id' })
genre: Genre = new Genre();
@Column({
name: 'last_update_date',
nullable: false,
type: 'timestamp with time zone'
})
lastUpdateDate: Date = new Date();
}
...
export class Book {
...
@Column({
name: 'authorId',
type: 'integer',
nullable: false
})
authorId: number = 0;
@ManyToOne(type => Author)
@JoinColumn({ name: 'authorId', referencedColumnName: 'id' })
author: Author = new Author();
@Column({
name: 'genreId',
type: 'integer',
nullable: false
})
genreId: number = 0;
@ManyToOne(type => Genre)
@JoinColumn({ name: 'genreId', referencedColumnName: 'id' })
genre: Genre = new Genre();
...
}
import "reflect-metadata";
import { singleton } from "tsyringe";
import { Connection, createConnection } from "typeorm";
// I must not connect two or more times.
@singleton()
export class DataContext {
private connection: Connection|null = null;
public async getConnection(): Promise<Connection> {
if(this.connection != null) {
return this.connection;
}
this.connection = await createConnection();
return this.connection;
}
}
import { autoInjectable } from "tsyringe";
import { Connection, QueryRunner } from "typeorm";
import { DataContext } from "../data/dataContext";
import { Author } from "../entities/author";
import { Book } from "../entities/book";
import { Genre } from "../entities/genre";
@autoInjectable()
export class BookService {
public constructor(private context: DataContext) {
}
public async createSeedData() {
const connection = await this.context.getConnection();
const queryRunner = connection.createQueryRunner();
await queryRunner.startTransaction();
try {
const authors = await this.createAuthors(connection, queryRunner);
const genres = await this.createGenres(connection, queryRunner);
const result = await this.createBooks(connection, queryRunner, authors, genres);
if(result === true) {
await queryRunner.commitTransaction();
}
} catch (err) {
console.error(err);
await queryRunner.rollbackTransaction();
}
}
private async createAuthors(connection: Connection, queryRunner: QueryRunner): Promise<readonly Author[]> {
const items = await connection.getRepository(Author)
.createQueryBuilder('author')
.getMany();
if(items.length > 0) {
return items;
}
const newItem = new Author();
newItem.name = 'David Flanagan';
await queryRunner.manager.save(newItem);
return [newItem];
}
private async createGenres(connection: Connection, queryRunner: QueryRunner): Promise<readonly Genre[]> {
const items = await connection.getRepository(Genre)
.createQueryBuilder('genre')
.getMany();
if(items.length > 0) {
return items;
}
const programming = new Genre();
programming.name = 'Programming';
await queryRunner.manager.save(programming);
const manga = new Genre();
manga.name = 'Manga';
await queryRunner.manager.save(manga);
const cooking = new Genre();
cooking.name = 'Cooking';
await queryRunner.manager.save(cooking);
return [programming, manga, cooking];
}
private async createBooks(connection: Connection, queryRunner: QueryRunner,
authors: readonly Author[], genres: readonly Genre[]): Promise<boolean> {
const items = await connection.getRepository(Book)
.createQueryBuilder('book')
.getMany();
if(items.length > 0) {
return false;
}
const author = authors[0];
const genre = genres.find(g => g.name === 'Programming');
const newItem = new Book();
newItem.name = 'Javascript: The Definitive Guide';
newItem.price = 6318;
newItem.author = author;
newItem.genre = genre ?? genres[0];
await queryRunner.manager.save(newItem);
return true;
}
}
var books = await context.Books
.Include(b => b.Genre)
.Include(b => b.Author)
.ToListAsync();
...
export class BookService {
...
public async getBooks(): Promise<readonly Book[]> {
const connection = await this.context.getConnection();
return await connection.getRepository(Book)
.createQueryBuilder('book')
.innerJoinAndSelect('book.genre', 'genre')
.innerJoinAndSelect('book.author', 'author')
.getMany();
}
...
}
import "reflect-metadata";
import express from 'express';
import { container } from 'tsyringe';
import { BookService } from "./books/bookService";
const port = 3000;
const app = express();
app.use(express.json());
app.use(express.raw());
app.use(express.static('clients/public'));
app.get('/books', async (req, res) => {
const books = container.resolve(BookService);
res.json(await books.getBooks());
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
export class Book {
...
@Column({
name: 'price',
type: 'money',
nullable: false
})
price: number = 0;
}