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 'reflect-metadata'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import cors from 'cors'
|
|
||||||
import { buildSchema } from 'type-graphql'
|
|
||||||
import { ApolloServer } from 'apollo-server-express'
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { RowDataPacket } from 'mysql2/promise'
|
|
||||||
|
|
||||||
import connection from './database/connection'
|
// config
|
||||||
import typeOrmConnection from './typeorm/connection'
|
|
||||||
import CONFIG from './config'
|
import CONFIG from './config'
|
||||||
|
|
||||||
// TODO move to extern
|
// database
|
||||||
import { UserResolver } from './graphql/resolvers/UserResolver'
|
import connection from './typeorm/connection'
|
||||||
import { BalanceResolver } from './graphql/resolvers/BalanceResolver'
|
import getDBVersion from './typeorm/getDBVersion'
|
||||||
import { GdtResolver } from './graphql/resolvers/GdtResolver'
|
|
||||||
import { TransactionResolver } from './graphql/resolvers/TransactionResolver'
|
|
||||||
import { KlicktippResolver } from './graphql/resolvers/KlicktippResolver'
|
|
||||||
|
|
||||||
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
|
// TODO implement
|
||||||
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
|
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
|
||||||
|
|
||||||
const DB_VERSION = '0001-init_db'
|
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() {
|
async function main() {
|
||||||
// check for correct database version
|
// open mysql connection
|
||||||
const con = await connection()
|
const con = await connection()
|
||||||
const [rows] = await con.query(`SELECT * FROM migrations ORDER BY version DESC LIMIT 1;`)
|
if (!con || !con.isConnected) {
|
||||||
if (
|
throw new Error(`Couldn't open connection to database`)
|
||||||
(<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}'`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const toCon = await typeOrmConnection()
|
// check for correct database version
|
||||||
if (!toCon.isConnected) {
|
const dbVersion = await getDBVersion()
|
||||||
throw new Error(`Couldn't open typeorm db connection`)
|
if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) {
|
||||||
}
|
throw new Error(
|
||||||
|
`Wrong database version - the backend requires '${DB_VERSION}' but found '${
|
||||||
const schema = await buildSchema({
|
dbVersion || 'None'
|
||||||
resolvers: [UserResolver, BalanceResolver, TransactionResolver, GdtResolver, KlicktippResolver],
|
}'`,
|
||||||
authChecker: isAuthorized,
|
)
|
||||||
})
|
|
||||||
|
|
||||||
// Graphiql interface
|
|
||||||
let playground = false
|
|
||||||
if (CONFIG.GRAPHIQL) {
|
|
||||||
playground = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Express Server
|
// Express Server
|
||||||
const server = express()
|
const server = express()
|
||||||
|
|
||||||
const corsOptions = {
|
// cors
|
||||||
origin: '*',
|
server.use(cors)
|
||||||
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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// Apollo Server
|
// 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 })
|
apollo.applyMiddleware({ app: server })
|
||||||
|
|
||||||
// Start 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 CONFIG from '../config'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
const connection = async (): Promise<Connection> => {
|
const connection = async (): Promise<Connection | null> => {
|
||||||
const con = await createConnection({
|
let con = null
|
||||||
name: 'default',
|
try {
|
||||||
type: 'mysql',
|
con = await createConnection({
|
||||||
host: CONFIG.DB_HOST,
|
name: 'default',
|
||||||
port: CONFIG.DB_PORT,
|
type: 'mysql',
|
||||||
username: CONFIG.DB_USER,
|
host: CONFIG.DB_HOST,
|
||||||
password: CONFIG.DB_PASSWORD,
|
port: CONFIG.DB_PORT,
|
||||||
database: CONFIG.DB_DATABASE,
|
username: CONFIG.DB_USER,
|
||||||
entities: [path.join(__dirname, 'entity', '*.ts')],
|
password: CONFIG.DB_PASSWORD,
|
||||||
synchronize: false,
|
database: CONFIG.DB_DATABASE,
|
||||||
})
|
entities: [path.join(__dirname, 'entity', '*.ts')],
|
||||||
|
synchronize: false,
|
||||||
|
})
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
return con
|
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