Skip to content

Commit

Permalink
Refactor logger implementation in MySQL database module
Browse files Browse the repository at this point in the history
  • Loading branch information
MXPOL committed Jan 28, 2024
1 parent 301a3aa commit 92521fb
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 16 deletions.
6 changes: 3 additions & 3 deletions libs/external-db-mysql/src/connection_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import DataProvider from './mysql_data_provider'
import FilterParser from './sql_filter_transformer'
import DatabaseOperations from './mysql_operations'
import { MySqlConfig } from './types'
import { Logger } from '@wix-velo/external-db-logger'
import { ILogger } from '@wix-velo/external-db-logger'


export default (cfg: MySqlConfig, _poolOptions: Record<string, unknown>, logger?: Logger) => {
export default (cfg: MySqlConfig, _poolOptions: Record<string, unknown>, logger?: ILogger) => {
const config: mysql.PoolConfig = {
host: cfg.host,
user: cfg.user,
Expand All @@ -31,7 +31,7 @@ export default (cfg: MySqlConfig, _poolOptions: Record<string, unknown>, logger?

const filterParser = new FilterParser()
const dataProvider = new DataProvider(pool, filterParser, logger)
const schemaProvider = new SchemaProvider(pool)
const schemaProvider = new SchemaProvider(pool, logger)

return { dataProvider, schemaProvider, databaseOperations, connection: pool, cleanup: async() => await pool.end() }
}
23 changes: 19 additions & 4 deletions libs/external-db-mysql/src/mysql_data_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { wildCardWith } from './mysql_utils'
import { IDataProvider, AdapterFilter as Filter, AdapterAggregation as Aggregation, Item, Sort } from '@wix-velo/velo-external-db-types'
import { IMySqlFilterParser } from './sql_filter_transformer'
import { MySqlQuery } from './types'
import { Logger } from '@wix-velo/external-db-logger'
import { ILogger } from '@wix-velo/external-db-logger'

export default class DataProvider implements IDataProvider {
filterParser: IMySqlFilterParser
pool: MySqlPool
query: MySqlQuery
logger?: Logger
constructor(pool: any, filterParser: any, logger?: Logger) {
logger?: ILogger
constructor(pool: any, filterParser: any, logger?: ILogger) {
this.filterParser = filterParser
this.pool = pool
this.logger = logger
Expand All @@ -28,7 +28,7 @@ export default class DataProvider implements IDataProvider {
const projectionExpr = this.filterParser.selectFieldsFor(projection)
const sql = `SELECT ${projectionExpr} FROM ${escapeTable(collectionName)} ${filterExpr} ${sortExpr} LIMIT ?, ?`

this.logger?.info('find', { collectionName, filter, sort, skip, limit, projection, sql, parameters })
this.logger?.info('find', { sql, parameters })

const resultset = await this.query(sql, [...parameters, skip, limit])
.catch( err => translateErrorCodes(err, collectionName) )
Expand All @@ -38,6 +38,8 @@ export default class DataProvider implements IDataProvider {
async count(collectionName: string, filter: Filter): Promise<number> {
const { filterExpr, parameters } = this.filterParser.transform(filter)
const sql = `SELECT COUNT(*) AS num FROM ${escapeTable(collectionName)} ${filterExpr}`

this.logger?.info('count', { sql, parameters })
const resultset = await this.query(sql, parameters)
.catch( err => translateErrorCodes(err, collectionName) )
return resultset[0]['num']
Expand All @@ -49,6 +51,9 @@ export default class DataProvider implements IDataProvider {
const sql = `${op} INTO ${escapeTable(collectionName)} (${escapedFieldsNames}) VALUES ?`

const data = items.map((item: Item) => asParamArrays( patchItem(item) ) )

this.logger?.info('insert', { sql, parameters: data })

const resultset = await this.query(sql, [data])
.catch( err => translateErrorCodes(err, collectionName) )
return resultset.affectedRows
Expand All @@ -60,6 +65,8 @@ export default class DataProvider implements IDataProvider {
.join(';')
const updatables: Item[] = items.map((i: Item) => [...updateFields, '_id'].reduce((obj, key) => ({ ...obj, [key]: i[key] }), {}) )
.map((u: Item) => asParamArrays( patchItem(u) ))

this.logger?.info('update', { sql: queries, parameters: updatables })

// @ts-ignore
const resultset = await this.query(queries, [].concat(...updatables))
Expand All @@ -70,12 +77,17 @@ export default class DataProvider implements IDataProvider {

async delete(collectionName: string, itemIds: string[]): Promise<number> {
const sql = `DELETE FROM ${escapeTable(collectionName)} WHERE _id IN (${wildCardWith(itemIds.length, '?')})`

this.logger?.info('delete', { sql, parameters: itemIds })

const rs = await this.query(sql, itemIds)
.catch( err => translateErrorCodes(err, collectionName) )
return rs.affectedRows
}

async truncate(collectionName: string): Promise<void> {
const sql = `TRUNCATE ${escapeTable(collectionName)}`
this.logger?.info('truncate', { sql })
await this.query(`TRUNCATE ${escapeTable(collectionName)}`).catch( err => translateErrorCodes(err, collectionName) )
}

Expand All @@ -85,6 +97,9 @@ export default class DataProvider implements IDataProvider {
const { sortExpr } = this.filterParser.orderBy(sort)

const sql = `SELECT ${fieldsStatement} FROM ${escapeTable(collectionName)} ${whereFilterExpr} GROUP BY ${groupByColumns.map( escapeId ).join(', ')} ${havingFilter} ${sortExpr} LIMIT ?, ?`

this.logger?.info('aggregate', { sql, parameters: [...whereParameters, ...parameters, skip, limit] })

const resultset = await this.query(sql, [...whereParameters, ...parameters, skip, limit])
.catch( err => translateErrorCodes(err, collectionName) )
return resultset
Expand Down
34 changes: 27 additions & 7 deletions libs/external-db-mysql/src/mysql_schema_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import SchemaColumnTranslator from './sql_schema_translator'
import { escapeId, escapeTable } from './mysql_utils'
import { MySqlQuery } from './types'
import { CollectionOperations, FieldTypes, ReadOnlyOperations, ReadWriteOperations, ColumnsCapabilities } from './mysql_capabilities'
import { ILogger } from '@wix-velo/external-db-logger'

export default class SchemaProvider implements ISchemaProvider {
pool: MySqlPool
sqlSchemaTranslator: SchemaColumnTranslator
query: MySqlQuery
constructor(pool: any) {
logger?: ILogger
constructor(pool: any, logger?: ILogger) {
this.pool = pool
this.logger = logger

this.sqlSchemaTranslator = new SchemaColumnTranslator()

Expand All @@ -22,7 +25,11 @@ export default class SchemaProvider implements ISchemaProvider {

async list(): Promise<Table[]> {
const currentDb = this.pool.config.connectionConfig.database
const data = await this.query('SELECT TABLE_NAME as table_name, COLUMN_NAME as field, DATA_TYPE as type FROM information_schema.columns WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME, ORDINAL_POSITION', currentDb)
const sql = 'SELECT TABLE_NAME as table_name, COLUMN_NAME as field, DATA_TYPE as type FROM information_schema.columns WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME, ORDINAL_POSITION'

this.logger?.info('list', { sql, parameters: currentDb })

const data = await this.query(sql, currentDb)
const tables: {[x:string]: { field: string, type: string}[]} = parseTableData( data )

return Object.entries(tables)
Expand All @@ -35,7 +42,10 @@ export default class SchemaProvider implements ISchemaProvider {

async listHeaders(): Promise<string[]> {
const currentDb = this.pool.config.connectionConfig.database
const data = await this.query('SELECT TABLE_NAME as table_name FROM information_schema.tables WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME', currentDb)
const sql = 'SELECT TABLE_NAME as table_name FROM information_schema.tables WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME'

this.logger?.info('listHeaders', { sql, parameters: currentDb })
const data = await this.query(sql, currentDb)
return data.map( (rs: { table_name: any }) => rs.table_name )
}

Expand All @@ -46,26 +56,35 @@ export default class SchemaProvider implements ISchemaProvider {
async create(collectionName: string, columns: InputField[]): Promise<void> {
const dbColumnsSql = columns.map( c => this.sqlSchemaTranslator.columnToDbColumnSql(c) ).join(', ')
const primaryKeySql = columns.filter(f => f.isPrimary).map(f => escapeId(f.name)).join(', ')
const sql = `CREATE TABLE IF NOT EXISTS ${escapeTable(collectionName)} (${dbColumnsSql}, PRIMARY KEY (${primaryKeySql}))`
const parameters = columns.map( c => c.name )

await this.query(`CREATE TABLE IF NOT EXISTS ${escapeTable(collectionName)} (${dbColumnsSql}, PRIMARY KEY (${primaryKeySql}))`,
columns.map((c: { name: any }) => c.name))
this.logger?.info('create table', { sql, parameters })
await this.query(sql, parameters)
.catch( err => translateErrorCodes(err, collectionName) )
}

async drop(collectionName: string): Promise<void> {
const sql = `DROP TABLE IF EXISTS ${escapeTable(collectionName)}`

this.logger?.info('drop table', { sql })
await this.query(`DROP TABLE IF EXISTS ${escapeTable(collectionName)}`)
.catch( err => translateErrorCodes(err, collectionName) )
}

async addColumn(collectionName: string, column: InputField): Promise<void> {
await validateSystemFields(column.name)
const sql = `ALTER TABLE ${escapeTable(collectionName)} ADD ${escapeId(column.name)} ${this.sqlSchemaTranslator.dbTypeFor(column)}`
this.logger?.info('add column', { sql })
await this.query(`ALTER TABLE ${escapeTable(collectionName)} ADD ${escapeId(column.name)} ${this.sqlSchemaTranslator.dbTypeFor(column)}`)
.catch( err => translateErrorCodes(err, collectionName) )
}

async changeColumnType(collectionName: string, column: InputField): Promise<void> {
await validateSystemFields(column.name)
await this.query(`ALTER TABLE ${escapeTable(collectionName)} MODIFY ${escapeId(column.name)} ${this.sqlSchemaTranslator.dbTypeFor(column)}`)
const sql = `ALTER TABLE ${escapeTable(collectionName)} MODIFY ${escapeId(column.name)} ${this.sqlSchemaTranslator.dbTypeFor(column)}`
this.logger?.info('change column type', { sql })
await this.query(sql)
.catch( err => translateErrorCodes(err, collectionName) )
}

Expand All @@ -80,7 +99,8 @@ export default class SchemaProvider implements ISchemaProvider {
Field: string,
Type: string,
}

const sql = `DESCRIBE ${escapeTable(collectionName)}`
this.logger?.info('describe table', { sql })
const res: describeTableResponse[] = await this.query(`DESCRIBE ${escapeTable(collectionName)}`)
.catch( err => translateErrorCodes(err, collectionName) )
const fields = res.map(r => ({ field: r.Field, type: r.Type })).map(this.appendAdditionalRowDetails.bind(this))
Expand Down
7 changes: 5 additions & 2 deletions libs/external-db-mysql/src/sql_schema_translator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { InputField } from '@wix-velo/velo-external-db-types'
import { ILogger } from '@wix-velo/external-db-logger'
import { escapeId } from './mysql_utils'

export default class SchemaColumnTranslato {
constructor() {
logger?: ILogger
constructor(logger?: ILogger) {
this.logger = logger
}

translateType(dbType: string) {
Expand Down Expand Up @@ -47,7 +50,7 @@ export default class SchemaColumnTranslato {
return 'object'

default:
console.log('Unknown type', type)
this.logger ? this.logger.warn(`Unknown type ${type} returning default type - text`) : console.log(`Unknown type ${type} returning default type - text`)
return 'text'
}
}
Expand Down

0 comments on commit 92521fb

Please sign in to comment.