code.gitea.io/gitea@v1.22.3/models/db/convert.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package db
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  
    10  	"code.gitea.io/gitea/modules/log"
    11  	"code.gitea.io/gitea/modules/setting"
    12  
    13  	"xorm.io/xorm"
    14  	"xorm.io/xorm/schemas"
    15  )
    16  
    17  // ConvertDatabaseTable converts database and tables from utf8 to utf8mb4 if it's mysql and set ROW_FORMAT=dynamic
    18  func ConvertDatabaseTable() error {
    19  	if x.Dialect().URI().DBType != schemas.MYSQL {
    20  		return nil
    21  	}
    22  
    23  	r, err := CheckCollations(x)
    24  	if err != nil {
    25  		return err
    26  	}
    27  
    28  	_, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", setting.Database.Name, r.ExpectedCollation))
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	tables, err := x.DBMetas()
    34  	if err != nil {
    35  		return err
    36  	}
    37  	for _, table := range tables {
    38  		if _, err := x.Exec(fmt.Sprintf("ALTER TABLE `%s` ROW_FORMAT=dynamic", table.Name)); err != nil {
    39  			return err
    40  		}
    41  
    42  		if _, err := x.Exec(fmt.Sprintf("ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8mb4 COLLATE %s", table.Name, r.ExpectedCollation)); err != nil {
    43  			return err
    44  		}
    45  	}
    46  
    47  	return nil
    48  }
    49  
    50  // ConvertVarcharToNVarchar converts database and tables from varchar to nvarchar if it's mssql
    51  func ConvertVarcharToNVarchar() error {
    52  	if x.Dialect().URI().DBType != schemas.MSSQL {
    53  		return nil
    54  	}
    55  
    56  	sess := x.NewSession()
    57  	defer sess.Close()
    58  	res, err := sess.QuerySliceString(`SELECT 'ALTER TABLE ' + OBJECT_NAME(SC.object_id) + ' MODIFY SC.name NVARCHAR(' + CONVERT(VARCHAR(5),SC.max_length) + ')'
    59  FROM SYS.columns SC
    60  JOIN SYS.types ST
    61  ON SC.system_type_id = ST.system_type_id
    62  AND SC.user_type_id = ST.user_type_id
    63  WHERE ST.name ='varchar'`)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	for _, row := range res {
    68  		if len(row) == 1 {
    69  			if _, err = sess.Exec(row[0]); err != nil {
    70  				return err
    71  			}
    72  		}
    73  	}
    74  	return err
    75  }
    76  
    77  // Cell2Int64 converts a xorm.Cell type to int64,
    78  // and handles possible irregular cases.
    79  func Cell2Int64(val xorm.Cell) int64 {
    80  	switch (*val).(type) {
    81  	case []uint8:
    82  		log.Trace("Cell2Int64 ([]uint8): %v", *val)
    83  
    84  		v, _ := strconv.ParseInt(string((*val).([]uint8)), 10, 64)
    85  		return v
    86  	}
    87  	return (*val).(int64)
    88  }