func (b *BridgeDB) Start(converter Converter) error {
	if err := b.mqttClient.Connect(); err != nil {
		log.Error(err)
		return err
	}
	defer b.Stop()

	var st time.Time
	var counterLimit int64 = 100000
	sem := make(chan int, b.setting.Concurrency)
	for {
		err := b.mqttClient.Subscribe(
			b.setting.Topic,
			mqtt.QOS_ZERO,
			func(msg mqtt.Message) error {
				atomic.AddInt64(&b.counter, 1)
				if b.counter == 1 {
					log.Infof(
						"Benchmark mqtt-subscriber pg-bridge start...",
					)
					st = time.Now()
				}
				log.Infof("counter=%v", b.counter)
				sem <- 1
				b.wg.Add(1)
				go func(topic string, msgData []byte) {
					log.Info(string(msgData))

					r := converter(topic)
					json.Unmarshal(msgData, r)
					err := b.dbm.Save(r)
					if err != nil {
						log.Error(err)
					}
					b.wg.Done()
					<-sem
				}(msg.Topic(), msg.Payload())
				return nil
			},
		)
		if err != nil {
			log.Error(err)
			break
		}
		if b.counter >= counterLimit {
			break
		}
		time.Sleep(time.Millisecond)
	}
	b.wg.Wait()
	log.Infof("counter=%v", b.counter)
	log.Infof(
		"Benchmark mqtt-subscriber pg-bridge end.[elapsedtime=%f sec]",
		time.Now().Sub(st).Seconds(),
	)
	return nil
}
func (db *gormDB) beginTransaction() (Transaction, error) {
	log.Debug("gorm#Begin")
	txn := &gormTxn{}
	txn.Dbm = db.Dbm.Begin()
	if err := txn.Dbm.Error; err != nil {
		log.Error("Failed to begin-transaction %v", err)
		return nil, err
	}
	return txn, nil
}
func (txn *sqlxTxn) Rollback() error {
	if txn.Tx == nil {
		return nil
	}
	log.Warn("sqlx#Rollback")
	if err := txn.Tx.Rollback(); err != nil {
		log.Error("Failed to rollback-transaction %v", err)
		return err
	}
	txn.Dbm = nil
	return nil
}
func (txn *sqlxTxn) Commit() error {
	if txn.Tx == nil {
		return nil
	}
	log.Debug("sqlx#Commit")
	if err := txn.Tx.Commit(); err != nil {
		log.Error("Failed to commit-transaction %v", err)
		return err
	}
	txn.Dbm = nil
	return nil
}
func (txn *gormTxn) Rollback() error {
	if txn.Dbm == nil {
		return nil
	}
	log.Warn("gorm#Rollback")
	if err := txn.Dbm.Rollback().Error; err != nil {
		log.Error("Failed to rollback-transaction %v", err)
		return err
	}
	txn.Dbm = nil
	return nil
}
/**************************
  gormTxn functions
**************************/
func (txn *gormTxn) Commit() error {
	if txn.Dbm == nil {
		return nil
	}
	log.Debug("gorm#Commit")
	if err := txn.Dbm.Commit().Error; err != nil {
		log.Error("Failed to commit-transaction %v", err)
		return err
	}
	txn.Dbm = nil
	return nil
}
func (db *sqlxDB) beginTransaction() (Transaction, error) {
	log.Debug("sqlx#Begin")
	var err error
	tx, err := db.Dbm.Beginx()
	if err != nil {
		log.Error("Failed to begin-transaction %v", err)
		return nil, err
	}
	txn := &sqlxTxn{}
	txn.Dbm = db.Dbm
	txn.Tx = tx
	return txn, nil
}