Merge pull request #894 from gradido/db_check_with_typeorm

Db check with typeorm
This commit is contained in:
Ulf Gebhardt 2021-09-24 16:18:51 +02:00 committed by GitHub
commit 31c2bb3990
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 145 additions and 100 deletions

View File

@ -1,18 +0,0 @@
import { createConnection, Connection } from 'mysql2/promise'
import CONFIG from '../config'
const connection = async (): Promise<Connection> => {
const con = await createConnection({
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
user: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
})
await con.connect()
return con
}
export default connection

View File

@ -0,0 +1,19 @@
import { UserResolver } from './UserResolver'
import { BalanceResolver } from './BalanceResolver'
import { GdtResolver } from './GdtResolver'
import { TransactionResolver } from './TransactionResolver'
import { KlicktippResolver } from './KlicktippResolver'
import { NonEmptyArray } from 'type-graphql'
export { UserResolver, BalanceResolver, GdtResolver, TransactionResolver, KlicktippResolver }
// eslint-disable-next-line @typescript-eslint/ban-types
const resolvers = (): NonEmptyArray<Function> => [
UserResolver,
BalanceResolver,
GdtResolver,
TransactionResolver,
KlicktippResolver,
]
export default resolvers

View File

@ -0,0 +1,14 @@
import { GraphQLSchema } from 'graphql'
import { buildSchema } from 'type-graphql'
import resolvers from './resolvers'
import { isAuthorized } from '../auth/auth'
const schema = async (): Promise<GraphQLSchema> => {
return buildSchema({
resolvers: resolvers(),
authChecker: isAuthorized,
})
}
export default schema

View File

@ -2,98 +2,58 @@
import 'reflect-metadata'
import express from 'express'
import cors from 'cors'
import { buildSchema } from 'type-graphql'
import { ApolloServer } from 'apollo-server-express'
import { RowDataPacket } from 'mysql2/promise'
import connection from './database/connection'
import typeOrmConnection from './typeorm/connection'
// config
import CONFIG from './config'
// TODO move to extern
import { UserResolver } from './graphql/resolvers/UserResolver'
import { BalanceResolver } from './graphql/resolvers/BalanceResolver'
import { GdtResolver } from './graphql/resolvers/GdtResolver'
import { TransactionResolver } from './graphql/resolvers/TransactionResolver'
import { KlicktippResolver } from './graphql/resolvers/KlicktippResolver'
// database
import connection from './typeorm/connection'
import getDBVersion from './typeorm/getDBVersion'
import { isAuthorized } from './auth/auth'
// server
import cors from './server/cors'
import context from './server/context'
import plugins from './server/plugins'
// graphql
import schema from './graphql/schema'
// TODO implement
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
const DB_VERSION = '0001-init_db'
const context = (args: any) => {
const authorization = args.req.headers.authorization
let token = null
if (authorization) {
token = authorization.replace(/^Bearer /, '')
}
const context = {
token,
setHeaders: [],
}
return context
}
async function main() {
// check for correct database version
// open mysql connection
const con = await connection()
const [rows] = await con.query(`SELECT * FROM migrations ORDER BY version DESC LIMIT 1;`)
if (
(<RowDataPacket>rows).length === 0 ||
!(<RowDataPacket>rows)[0].fileName ||
(<RowDataPacket>rows)[0].fileName.indexOf(DB_VERSION) === -1
) {
throw new Error(`Wrong database version - the backend requires '${DB_VERSION}'`)
if (!con || !con.isConnected) {
throw new Error(`Couldn't open connection to database`)
}
const toCon = await typeOrmConnection()
if (!toCon.isConnected) {
throw new Error(`Couldn't open typeorm db connection`)
}
const schema = await buildSchema({
resolvers: [UserResolver, BalanceResolver, TransactionResolver, GdtResolver, KlicktippResolver],
authChecker: isAuthorized,
})
// Graphiql interface
let playground = false
if (CONFIG.GRAPHIQL) {
playground = true
// check for correct database version
const dbVersion = await getDBVersion()
if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) {
throw new Error(
`Wrong database version - the backend requires '${DB_VERSION}' but found '${
dbVersion || 'None'
}'`,
)
}
// Express Server
const server = express()
const corsOptions = {
origin: '*',
exposedHeaders: ['token'],
}
server.use(cors(corsOptions))
const plugins = [
{
requestDidStart() {
return {
willSendResponse(requestContext: any) {
const { setHeaders = [] } = requestContext.context
setHeaders.forEach(({ key, value }: { [key: string]: string }) => {
requestContext.response.http.headers.append(key, value)
})
return requestContext
},
}
},
},
]
// cors
server.use(cors)
// Apollo Server
const apollo = new ApolloServer({ schema, playground, context, plugins })
const apollo = new ApolloServer({
schema: await schema(),
playground: CONFIG.GRAPHIQL,
context,
plugins,
})
apollo.applyMiddleware({ app: server })
// Start Server

View File

@ -0,0 +1,14 @@
const context = (args: any) => {
const authorization = args.req.headers.authorization
let token = null
if (authorization) {
token = authorization.replace(/^Bearer /, '')
}
const context = {
token,
setHeaders: [],
}
return context
}
export default context

View File

@ -0,0 +1,8 @@
import cors from 'cors'
const corsOptions = {
origin: '*',
exposedHeaders: ['token'],
}
export default cors(corsOptions)

View File

@ -0,0 +1,17 @@
const plugins = [
{
requestDidStart() {
return {
willSendResponse(requestContext: any) {
const { setHeaders = [] } = requestContext.context
setHeaders.forEach(({ key, value }: { [key: string]: string }) => {
requestContext.response.http.headers.append(key, value)
})
return requestContext
},
}
},
},
]
export default plugins

View File

@ -2,18 +2,21 @@ import { createConnection, Connection } from 'typeorm'
import CONFIG from '../config'
import path from 'path'
const connection = async (): Promise<Connection> => {
const con = await createConnection({
name: 'default',
type: 'mysql',
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
username: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
entities: [path.join(__dirname, 'entity', '*.ts')],
synchronize: false,
})
const connection = async (): Promise<Connection | null> => {
let con = null
try {
con = await createConnection({
name: 'default',
type: 'mysql',
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
username: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
entities: [path.join(__dirname, 'entity', '*.ts')],
synchronize: false,
})
} catch (error) {}
return con
}

View File

@ -0,0 +1,13 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
@Entity('migrations')
export class Migration extends BaseEntity {
@PrimaryGeneratedColumn() // This is actually not a primary column
version: number
@Column({ length: 256, nullable: true, default: null })
fileName: string
@Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
date: Date
}

View File

@ -0,0 +1,15 @@
import { getConnection } from 'typeorm'
import { Migration } from './entity/Migration'
const getDBVersion = async (): Promise<string | null> => {
const connection = getConnection()
const migrations = connection.getRepository(Migration)
try {
const dbVersion = await migrations.findOne({ order: { version: 'DESC' } })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
return null
}
}
export default getDBVersion