mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge pull request #894 from gradido/db_check_with_typeorm
Db check with typeorm
This commit is contained in:
commit
31c2bb3990
@ -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
|
||||
19
backend/src/graphql/resolvers/index.ts
Normal file
19
backend/src/graphql/resolvers/index.ts
Normal 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
|
||||
14
backend/src/graphql/schema.ts
Normal file
14
backend/src/graphql/schema.ts
Normal 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
|
||||
@ -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
|
||||
|
||||
14
backend/src/server/context.ts
Normal file
14
backend/src/server/context.ts
Normal 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
|
||||
8
backend/src/server/cors.ts
Normal file
8
backend/src/server/cors.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import cors from 'cors'
|
||||
|
||||
const corsOptions = {
|
||||
origin: '*',
|
||||
exposedHeaders: ['token'],
|
||||
}
|
||||
|
||||
export default cors(corsOptions)
|
||||
17
backend/src/server/plugins.ts
Normal file
17
backend/src/server/plugins.ts
Normal 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
|
||||
@ -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
|
||||
}
|
||||
|
||||
13
backend/src/typeorm/entity/Migration.ts
Normal file
13
backend/src/typeorm/entity/Migration.ts
Normal 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
|
||||
}
|
||||
15
backend/src/typeorm/getDBVersion.ts
Normal file
15
backend/src/typeorm/getDBVersion.ts
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user