import { inject , injectable } from 'inversify' ; import { FindConditions } from 'typeorm' ; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity' ; import * as apid from '../../../api' ; import * as mapid from '../../../node_modules/mirakurun/api' ; import Channel from '../../db/entities/Channel' ; import StrUtil from '../../util/StrUtil' ; import IConfiguration from '../IConfiguration' ; import ILogger from '../ILogger' ; import ILoggerModel from '../ILoggerModel' ; import IPromiseRetry from '../IPromiseRetry' ; import IChannelDB , { ChannelUpdateValues } from './IChannelDB' ; import IDBOperator from './IDBOperator' ; @ injectable ( ) export default class ChannelDB implements IChannelDB { private log : ILogger ; private configuration : IConfiguration ; private op : IDBOperator ; private promieRetry : IPromiseRetry ; constructor ( @ inject ( 'ILoggerModel' ) logger , @ inject ( 'IConfiguration' ) configuration , @ inject ( 'IDBOperator' ) op , @ inject ( 'IPromiseRetry' ) promieRetry ) { this . log = logger . getLogger ( ) ; this . configuration = configuration ; this . op = op ; this . promieRetry = promieRetry ; } param channels param needesDeleted return public async insert ( channels , needesDeleted = true ) { const values = [ ] ; for ( const channel of channels ) { if ( typeof channel . channel === 'undefined' ) { return ; } const name = StrUtil . toDBStr ( channel . name ) ; values . push ( { id : channel . id , serviceId : channel . serviceId , networkId : channel . networkId , name : name , halfWidthName : StrUtil . toHalf ( name ) , remoteControlKeyId : typeof channel . remoteControlKeyId === 'undefined' ? null : channel . remoteControlKeyId , hasLogoData : ! ! channel . hasLogoData , channelTypeId : this . getChannelTypeId ( channel . channel . type ) , channelType : channel . channel . type , channel : channel . channel . channel , type : typeof ( channel as any ) [ 'type' ] !== 'number' ? null : ( channel as any ) [ 'type' ] , } ) ; } const connection = await this . op . getConnection ( ) ; const queryRunner = connection . createQueryRunner ( ) ; await queryRunner . startTransaction ( ) ; let hasError = false ; try { if ( needesDeleted === true ) { await queryRunner . manager . delete ( Channel , { } ) ; } for ( const value of values ) { await queryRunner . manager . insert ( Channel , value ) . catch ( async ( err ) => { await queryRunner . manager . update ( Channel , value . id , value ) . catch ( serr => { this . log . system . error ( 'channel update error' ) ; this . log . system . error ( err ) ; this . log . system . error ( serr ) ; } ) ; } ) ; } await queryRunner . commitTransaction ( ) ; } catch ( err ) { console . error ( err ) ; hasError = true ; await queryRunner . rollbackTransaction ( ) ; } finally { await queryRunner . release ( ) ; } if ( hasError ) { throw new Error ( 'insert error' ) ; } } paramChannelTypeId private getChannelTypeId ( type ) { switch ( type ) { case 'GR' : return 0 ; case 'BS' : return 1 ; case 'CS' : return 2 ; case 'SKY' : return 3 ; default : return 4 ; } } param values return public async update ( values ) { const channels = [ ] ; Array . prototype . push . apply ( channels , values . insert ) ; Array . prototype . push . apply ( channels , values . update ) ; await this . insert ( channels , false ) ; } param channelId return public async findId ( channelId ) { const connection = await this . op . getConnection ( ) ; const repository = connection . getRepository ( Channel ) ; const result = await this . promieRetry . run ( ( ) => { return repository . findOne ( { where : [ { id : channelId } ] , } ) ; } ) ; return typeof result === 'undefined' ? null : result ; } param types param needSort return public async findChannleTypes ( types , needSort = false ) { const connection = await this . op . getConnection ( ) ; const queryOption = [ ] ; for ( const type of types ) { queryOption . push ( { channelType : type , } ) ; } const repository = connection . getRepository ( Channel ) . createQueryBuilder ( 'channel' ) . where ( queryOption ) . orderBy ( 'channel.channelTypeId, channel.remoteControlKeyId, channel.serviceId' , 'ASC' ) ; const result = await this . promieRetry . run ( ( ) => { return repository . getMany ( ) ; } ) ; return needSort === true ? this . sortChannels ( result ) : result ; } param needSort return public async findAll ( needSort = false ) { const connection = await this . op . getConnection ( ) ; const queryBuilder = connection . getRepository ( Channel ) . createQueryBuilder ( 'channel' ) . orderBy ( 'channel.channelTypeId, channel.remoteControlKeyId, channel.serviceId' , 'ASC' ) ; const result = await this . promieRetry . run ( ( ) => { return queryBuilder . getMany ( ) ; } ) ; return needSort === true ? this . sortChannels ( result ) : result ; } return private sortChannels ( channels ) { const config = this . configuration . getConfig ( ) ; let order = [ ] ; let key ; if ( typeof config . channelOrder !== 'undefined' ) { order = config . channelOrder ; key = 'id' ; } else if ( typeof config . sidOrder !== 'undefined' ) { order = config . sidOrder ; key = 'serviceId' ; } else { return channels ; } let cnt = 0 ; order . forEach ( id => { const i = channels . findIndex ( c => { return ( c as any ) [ key ] === id ; } ) ; if ( i === - 1 ) { return ; } const [ channel ] = channels . splice ( i , 1 ) ; channels . splice ( cnt , 0 , channel ) ; cnt += 1 ; } ) ; return channels ; } }