github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/meta/internal/sqlkv/connection.go (about)

     1  // Copyright 2022 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package sqlkv
    15  
    16  import (
    17  	"database/sql"
    18  	"strconv"
    19  	"sync"
    20  
    21  	"github.com/pingcap/tiflow/engine/pkg/dbutil"
    22  	"github.com/pingcap/tiflow/engine/pkg/meta/model"
    23  	"github.com/pingcap/tiflow/pkg/errors"
    24  )
    25  
    26  // NewClientConnImpl return a new clientConnImpl
    27  func NewClientConnImpl(storeConf *model.StoreConfig) (*clientConnImpl, error) {
    28  	if storeConf == nil {
    29  		return nil, errors.ErrMetaParamsInvalid.GenWithStackByArgs("store config is nil")
    30  	}
    31  
    32  	if storeConf.StoreType != model.StoreTypeMySQL {
    33  		return nil, errors.ErrMetaParamsInvalid.GenWithStack("sql conn but get type:%s",
    34  			storeConf.StoreType)
    35  	}
    36  
    37  	db, err := NewSQLDB(storeConf)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	return &clientConnImpl{
    43  		db: db,
    44  	}, nil
    45  }
    46  
    47  type clientConnImpl struct {
    48  	rwLock sync.RWMutex
    49  	db     *sql.DB
    50  }
    51  
    52  // GetConn implements GetConn of ClientConn
    53  // Return *sql.DB if no error
    54  func (cc *clientConnImpl) GetConn() (interface{}, error) {
    55  	cc.rwLock.RLock()
    56  	defer cc.rwLock.RUnlock()
    57  
    58  	if cc.db == nil {
    59  		return nil, errors.ErrMetaOpFail.GenWithStackByArgs("connection is uninitialized")
    60  	}
    61  
    62  	return cc.db, nil
    63  }
    64  
    65  // Close implements Close of ClientConn
    66  func (cc *clientConnImpl) Close() error {
    67  	cc.rwLock.Lock()
    68  	defer cc.rwLock.Unlock()
    69  
    70  	if cc.db != nil {
    71  		cc.db.Close()
    72  		cc.db = nil
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // StoreType implements StoreType of ClientConn
    79  func (cc *clientConnImpl) StoreType() model.StoreType {
    80  	return model.StoreTypeMySQL
    81  }
    82  
    83  // NewSQLDB news a sql.DB.
    84  func NewSQLDB(storeConf *model.StoreConfig) (*sql.DB, error) {
    85  	pairs := map[string]string{
    86  		"sql_mode": strconv.Quote(dbutil.GetSQLStrictMode()),
    87  	}
    88  	dsn, err := model.GenerateDSNByParams(storeConf, pairs)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	return dbutil.NewSQLDB("mysql", dsn, storeConf.DBConf)
    93  }