mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-01 04:12:10 +00:00
[CHORE] Remove Microsoft SQL Server Support
- Per https://codeberg.org/forgejo/discussions/issues/122
This commit is contained in:
parent
af47c583b4
commit
2d9afd0c21
70 changed files with 70 additions and 789 deletions
|
@ -41,20 +41,6 @@ func findAvailableCollationsMySQL(x *xorm.Engine) (ret container.Set[string], er
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func findAvailableCollationsMSSQL(x *xorm.Engine) (ret container.Set[string], err error) {
|
||||
var res []struct {
|
||||
Name string
|
||||
}
|
||||
if err = x.SQL("SELECT * FROM sys.fn_helpcollations() WHERE name LIKE '%[_]CS[_]AS%'").Find(&res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = make(container.Set[string], len(res))
|
||||
for _, r := range res {
|
||||
ret.Add(r.Name)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func CheckCollations(x *xorm.Engine) (*CheckCollationsResult, error) {
|
||||
dbTables, err := x.DBMetas()
|
||||
if err != nil {
|
||||
|
@ -84,18 +70,6 @@ func CheckCollations(x *xorm.Engine) (*CheckCollationsResult, error) {
|
|||
// At the moment, it's safe to ignore the database difference, just trim the prefix and compare. It could be fixed easily if there is any problem in the future.
|
||||
return a == b || strings.TrimPrefix(a, "utf8mb4_") == strings.TrimPrefix(b, "utf8mb4_")
|
||||
}
|
||||
} else if x.Dialect().URI().DBType == schemas.MSSQL {
|
||||
if _, err = x.SQL("SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation')").Get(&res.DatabaseCollation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.IsCollationCaseSensitive = func(s string) bool {
|
||||
return strings.HasSuffix(s, "_CS_AS")
|
||||
}
|
||||
candidateCollations = []string{"Latin1_General_CS_AS"}
|
||||
res.AvailableCollation, err = findAvailableCollationsMSSQL(x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -146,10 +120,6 @@ func alterDatabaseCollation(x *xorm.Engine, collation string) error {
|
|||
if x.Dialect().URI().DBType == schemas.MYSQL {
|
||||
_, err := x.Exec("ALTER DATABASE CHARACTER SET utf8mb4 COLLATE " + collation)
|
||||
return err
|
||||
} else if x.Dialect().URI().DBType == schemas.MSSQL {
|
||||
// TODO: MSSQL has many limitations on changing database collation, it could fail in many cases.
|
||||
_, err := x.Exec("ALTER DATABASE CURRENT COLLATE " + collation)
|
||||
return err
|
||||
}
|
||||
return errors.New("unsupported database type")
|
||||
}
|
||||
|
@ -165,12 +135,11 @@ func preprocessDatabaseCollation(x *xorm.Engine) {
|
|||
}
|
||||
|
||||
// try to alter database collation to expected if the database is empty, it might fail in some cases (and it isn't necessary to succeed)
|
||||
// at the moment, there is no "altering" solution for MSSQL, site admin should manually change the database collation
|
||||
// at the moment.
|
||||
if !r.CollationEquals(r.DatabaseCollation, r.ExpectedCollation) && r.ExistingTableNumber == 0 {
|
||||
if err = alterDatabaseCollation(x, r.ExpectedCollation); err != nil {
|
||||
log.Error("Failed to change database collation to %q: %v", r.ExpectedCollation, err)
|
||||
} else {
|
||||
_, _ = x.Exec("SELECT 1") // after "altering", MSSQL's session becomes invalid, so make a simple query to "refresh" the session
|
||||
if r, err = CheckCollations(x); err != nil {
|
||||
log.Error("Failed to check database collation again after altering: %v", err) // impossible case
|
||||
return
|
||||
|
|
|
@ -47,8 +47,6 @@ func BuilderDialect() string {
|
|||
return builder.SQLITE
|
||||
case setting.Database.Type.IsPostgreSQL():
|
||||
return builder.POSTGRES
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
return builder.MSSQL
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -47,33 +47,6 @@ func ConvertDatabaseTable() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ConvertVarcharToNVarchar converts database and tables from varchar to nvarchar if it's mssql
|
||||
func ConvertVarcharToNVarchar() error {
|
||||
if x.Dialect().URI().DBType != schemas.MSSQL {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
res, err := sess.QuerySliceString(`SELECT 'ALTER TABLE ' + OBJECT_NAME(SC.object_id) + ' MODIFY SC.name NVARCHAR(' + CONVERT(VARCHAR(5),SC.max_length) + ')'
|
||||
FROM SYS.columns SC
|
||||
JOIN SYS.types ST
|
||||
ON SC.system_type_id = ST.system_type_id
|
||||
AND SC.user_type_id = ST.user_type_id
|
||||
WHERE ST.name ='varchar'`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, row := range res {
|
||||
if len(row) == 1 {
|
||||
if _, err = sess.Exec(row[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Cell2Int64 converts a xorm.Cell type to int64,
|
||||
// and handles possible irregular cases.
|
||||
func Cell2Int64(val xorm.Cell) int64 {
|
||||
|
|
|
@ -22,9 +22,8 @@ import (
|
|||
"xorm.io/xorm/names"
|
||||
"xorm.io/xorm/schemas"
|
||||
|
||||
_ "github.com/denisenkom/go-mssqldb" // Needed for the MSSQL driver
|
||||
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
||||
_ "github.com/lib/pq" // Needed for the Postgresql driver
|
||||
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
||||
_ "github.com/lib/pq" // Needed for the Postgresql driver
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -114,10 +113,8 @@ func newXORMEngine() (*xorm.Engine, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if setting.Database.Type == "mysql" {
|
||||
if setting.Database.Type.IsMySQL() {
|
||||
engine.Dialect().SetParams(map[string]string{"rowFormat": "DYNAMIC"})
|
||||
} else if setting.Database.Type == "mssql" {
|
||||
engine.Dialect().SetParams(map[string]string{"DEFAULT_VARCHAR": "nvarchar"})
|
||||
}
|
||||
engine.SetSchema(setting.Database.Schema)
|
||||
return engine, nil
|
||||
|
|
|
@ -89,33 +89,6 @@ func mysqlGetNextResourceIndex(ctx context.Context, tableName string, groupID in
|
|||
return idx, nil
|
||||
}
|
||||
|
||||
func mssqlGetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
if _, err := GetEngine(ctx).Exec(fmt.Sprintf(`
|
||||
MERGE INTO %s WITH (HOLDLOCK) AS target
|
||||
USING (SELECT %d AS group_id) AS source
|
||||
(group_id)
|
||||
ON target.group_id = source.group_id
|
||||
WHEN MATCHED
|
||||
THEN UPDATE
|
||||
SET max_index = max_index + 1
|
||||
WHEN NOT MATCHED
|
||||
THEN INSERT (group_id, max_index)
|
||||
VALUES (%d, 1);
|
||||
`, tableName, groupID, groupID)); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var idx int64
|
||||
_, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&idx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if idx == 0 {
|
||||
return 0, errors.New("cannot get the correct index")
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
|
||||
// GetNextResourceIndex generates a resource index, it must run in the same transaction where the resource is created
|
||||
func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64) (int64, error) {
|
||||
switch {
|
||||
|
@ -123,8 +96,6 @@ func GetNextResourceIndex(ctx context.Context, tableName string, groupID int64)
|
|||
return postgresGetNextResourceIndex(ctx, tableName, groupID)
|
||||
case setting.Database.Type.IsMySQL():
|
||||
return mysqlGetNextResourceIndex(ctx, tableName, groupID)
|
||||
case setting.Database.Type.IsMSSQL():
|
||||
return mssqlGetNextResourceIndex(ctx, tableName, groupID)
|
||||
}
|
||||
|
||||
e := GetEngine(ctx)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue