123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- package operations
- import (
- "database/sql"
- "git.sxidc.com/service-supports/fslog"
- "gorm.io/gorm"
- "strings"
- "time"
- )
- type Operations struct {
- initDB *gorm.DB
- processDB *gorm.DB
- stopPingChan chan any
- }
- func NewOperations(dbConfig *DBConfig) (*Operations, error) {
- gormDB, err := newGormDB(dbConfig)
- if err != nil {
- return nil, err
- }
- sqlDB, err := gormDB.DB()
- if err != nil {
- return nil, err
- }
- if dbConfig.MaxConnections == 0 {
- dbConfig.MaxConnections = 50
- }
- if dbConfig.MaxIdleConnections == 0 {
- dbConfig.MaxIdleConnections = 10
- }
- sqlDB.SetMaxOpenConns(dbConfig.MaxConnections)
- sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConnections)
- op := &Operations{
- initDB: gormDB,
- processDB: gormDB,
- stopPingChan: make(chan any),
- }
- op.startBeatHeart(sqlDB)
- return op, nil
- }
- func DestroyOperation(op *Operations) error {
- if op == nil {
- return nil
- }
- if op.initDB == nil {
- return nil
- }
- op.stopBeatHeart()
- return destroyGormDB(op.initDB)
- }
- func (op *Operations) startBeatHeart(sqlDB *sql.DB) {
- go func() {
- pingTicker := time.NewTicker(time.Minute * 1)
- defer pingTicker.Stop()
- for {
- select {
- case <-op.stopPingChan:
- return
- case <-pingTicker.C:
- err := sqlDB.Ping()
- if err != nil {
- fslog.Error(err)
- }
- }
- }
- }()
- }
- func (op *Operations) stopBeatHeart() {
- if op.stopPingChan != nil {
- close(op.stopPingChan)
- op.stopPingChan = nil
- }
- }
- func (op *Operations) BeginTransaction() TransactionDBOperations {
- tx := op.initDB.Begin()
- return &TransactionOperations{
- Operations{
- initDB: tx,
- processDB: tx,
- },
- }
- }
- func (op *Operations) NewSession() DBOperations {
- return &Operations{
- initDB: op.initDB,
- processDB: op.initDB,
- }
- }
- func (op *Operations) AutoMigrate(tables ...Table) error {
- tx := op.processDB.Begin()
- for _, table := range tables {
- dbModel, err := table.ToDBModel()
- if err != nil {
- tx.Rollback()
- return err
- }
- err = tx.Table(table.TableName).AutoMigrate(dbModel)
- if err != nil {
- tx.Rollback()
- return err
- }
- }
- tx.Commit()
- return nil
- }
- func (op *Operations) Table(name string, args ...any) DBOperations {
- return &Operations{
- initDB: op.initDB,
- processDB: op.initDB.Table(name, args...),
- }
- }
- func (op *Operations) Raw(sql string, values ...any) DBOperations {
- op.processDB = op.processDB.Raw(sql, values...)
- return op
- }
- func (op *Operations) Select(query string, args ...any) DBOperations {
- op.processDB = op.processDB.Select(query, args...)
- return op
- }
- func (op *Operations) Joins(query string, args ...any) DBOperations {
- op.processDB = op.processDB.Joins(query, args...)
- return op
- }
- func (op *Operations) Where(conditions *Conditions) DBOperations {
- op.processDB = conditions.where(op.processDB)
- return op
- }
- func (op *Operations) Or(conditions *Conditions) DBOperations {
- op.processDB = conditions.or(op.processDB)
- return op
- }
- func (op *Operations) Having(conditions *Conditions) DBOperations {
- op.processDB = conditions.having(op.processDB)
- return op
- }
- func (op *Operations) GroupBy(groupBy string) DBOperations {
- op.processDB = op.processDB.Group(groupBy)
- return op
- }
- func (op *Operations) OrderBy(orderBy string) DBOperations {
- op.processDB = op.processDB.Order(orderBy)
- return op
- }
- func (op *Operations) Paging(pageNo int, pageSize int) DBOperations {
- if pageNo != 0 && pageSize != 0 {
- offset := -1
- if pageNo == -1 || pageSize == -1 {
- offset = -1
- pageSize = -1
- } else {
- offset = (pageNo - 1) * pageSize
- }
- op.processDB = op.processDB.Offset(offset).Limit(pageSize)
- }
- return op
- }
- func (op *Operations) Create(tableRow *TableRow) error {
- err := op.processDB.Create(tableRow.ToMap()).Error
- if err != nil {
- if strings.Contains(err.Error(), "SQLSTATE 23505") {
- return ErrDBRecordHasExist
- }
- return err
- }
- return nil
- }
- func (op *Operations) CreateBatch(tableRows []TableRow) error {
- tableRowMaps := make([]map[string]any, 0)
- for _, tableRow := range tableRows {
- tableRowMaps = append(tableRowMaps, tableRow.ToMap())
- }
- err := op.processDB.Create(tableRowMaps).Error
- if err != nil {
- if strings.Contains(err.Error(), "SQLSTATE 23505") {
- return ErrDBRecordHasExist
- }
- return err
- }
- return nil
- }
- func (op *Operations) Delete() error {
- return op.processDB.Delete(make(map[string]any)).Error
- }
- func (op *Operations) Updates(newTableRow *TableRow) error {
- err := op.processDB.Updates(newTableRow.ToMap()).Error
- if err != nil {
- if strings.Contains(err.Error(), "SQLSTATE 23505") {
- return ErrDBRecordHasExist
- }
- return err
- }
- return nil
- }
- func (op *Operations) UpdatesWithRowsAffected(newTableRow *TableRow) (int64, error) {
- op.processDB = op.processDB.Updates(newTableRow.ToMap())
- if op.processDB.Error != nil {
- return 0, op.processDB.Error
- }
- return op.processDB.RowsAffected, nil
- }
- func (op *Operations) Rows(pageNo int, pageSize int) ([]TableRow, error) {
- if pageNo != 0 && pageSize != 0 {
- offset := (pageNo - 1) * pageSize
- op.processDB = op.processDB.Offset(offset).Limit(pageSize)
- }
- defer func() {
- op.processDB = op.processDB.Offset(-1).Limit(-1)
- }()
- tableRowMaps := make([]map[string]any, 0)
- err := op.processDB.Scan(&tableRowMaps).Error
- if err != nil {
- return nil, err
- }
- tableRows := make([]TableRow, 0)
- for _, tableRowMap := range tableRowMaps {
- tableRows = append(tableRows, *NewTableRowFromMap(tableRowMap))
- }
- return tableRows, nil
- }
- func (op *Operations) Row() (*TableRow, error) {
- valueMap := make(map[string]any)
- err := op.processDB.Scan(&valueMap).Error
- if err != nil {
- return nil, err
- }
- if valueMap == nil || len(valueMap) == 0 {
- return nil, ErrDBRecordNotExist
- }
- return NewTableRowFromMap(valueMap), nil
- }
- func (op *Operations) Count(count *int64) error {
- return op.processDB.Count(count).Error
- }
- func (op *Operations) CheckExist() (bool, error) {
- var count int64
- err := op.processDB.Count(&count).Error
- if err != nil {
- return false, err
- }
- return count > 0, nil
- }
- func (op *Operations) CheckHasOnlyOne() (bool, error) {
- var count int64
- err := op.processDB.Count(&count).Error
- if err != nil {
- return false, err
- }
- return count == 1, nil
- }
|