2014-02-12 17:49:46 +00:00
|
|
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
2018-06-20 05:06:01 +00:00
|
|
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
2022-11-27 18:20:29 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2014-02-12 17:49:46 +00:00
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
package db
|
2014-02-13 15:23:23 +00:00
|
|
|
|
2014-02-18 22:48:02 +00:00
|
|
|
import (
|
2019-12-15 09:51:28 +00:00
|
|
|
"context"
|
2014-10-19 05:35:24 +00:00
|
|
|
"database/sql"
|
2014-02-18 22:48:02 +00:00
|
|
|
"fmt"
|
2020-09-06 21:52:01 +00:00
|
|
|
"reflect"
|
|
|
|
"strings"
|
2017-10-27 06:10:54 +00:00
|
|
|
|
2019-10-17 09:26:49 +00:00
|
|
|
"xorm.io/xorm"
|
2020-03-22 15:12:55 +00:00
|
|
|
"xorm.io/xorm/schemas"
|
2016-11-26 00:20:18 +00:00
|
|
|
|
2024-04-11 01:12:40 +00:00
|
|
|
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
|
|
|
_ "github.com/lib/pq" // Needed for the Postgresql driver
|
|
|
|
_ "github.com/microsoft/go-mssqldb" // Needed for the MSSQL driver
|
2014-02-18 22:48:02 +00:00
|
|
|
)
|
2014-02-13 15:23:23 +00:00
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
var (
|
2024-12-20 16:11:38 +00:00
|
|
|
xormEngine *xorm.Engine
|
|
|
|
registeredModels []any
|
|
|
|
registeredInitFuncs []func() error
|
2021-09-19 11:49:59 +00:00
|
|
|
)
|
|
|
|
|
2014-10-19 05:35:24 +00:00
|
|
|
// Engine represents a xorm engine or session.
|
|
|
|
type Engine interface {
|
2023-07-04 18:36:08 +00:00
|
|
|
Table(tableNameOrBean any) *xorm.Session
|
|
|
|
Count(...any) (int64, error)
|
|
|
|
Decr(column string, arg ...any) *xorm.Session
|
|
|
|
Delete(...any) (int64, error)
|
|
|
|
Truncate(...any) (int64, error)
|
|
|
|
Exec(...any) (sql.Result, error)
|
|
|
|
Find(any, ...any) error
|
|
|
|
Get(beans ...any) (bool, error)
|
|
|
|
ID(any) *xorm.Session
|
|
|
|
In(string, ...any) *xorm.Session
|
|
|
|
Incr(column string, arg ...any) *xorm.Session
|
|
|
|
Insert(...any) (int64, error)
|
|
|
|
Iterate(any, xorm.IterFunc) error
|
|
|
|
Join(joinOperator string, tablename, condition any, args ...any) *xorm.Session
|
|
|
|
SQL(any, ...any) *xorm.Session
|
|
|
|
Where(any, ...any) *xorm.Session
|
2019-06-12 19:41:28 +00:00
|
|
|
Asc(colNames ...string) *xorm.Session
|
2020-08-17 03:07:38 +00:00
|
|
|
Desc(colNames ...string) *xorm.Session
|
2020-01-24 19:00:29 +00:00
|
|
|
Limit(limit int, start ...int) *xorm.Session
|
2021-11-21 15:41:00 +00:00
|
|
|
NoAutoTime() *xorm.Session
|
2023-07-04 18:36:08 +00:00
|
|
|
SumInt(bean any, columnName string) (res int64, err error)
|
2023-08-13 19:17:21 +00:00
|
|
|
Sync(...any) error
|
2021-09-19 11:49:59 +00:00
|
|
|
Select(string) *xorm.Session
|
2024-05-08 13:44:57 +00:00
|
|
|
SetExpr(string, any) *xorm.Session
|
2023-07-04 18:36:08 +00:00
|
|
|
NotIn(string, ...any) *xorm.Session
|
|
|
|
OrderBy(any, ...any) *xorm.Session
|
|
|
|
Exist(...any) (bool, error)
|
2021-09-19 11:49:59 +00:00
|
|
|
Distinct(...string) *xorm.Session
|
2023-07-04 18:36:08 +00:00
|
|
|
Query(...any) ([]map[string][]byte, error)
|
2021-09-19 11:49:59 +00:00
|
|
|
Cols(...string) *xorm.Session
|
2022-01-19 23:26:57 +00:00
|
|
|
Context(ctx context.Context) *xorm.Session
|
2022-01-27 08:30:51 +00:00
|
|
|
Ping() error
|
2014-10-19 05:35:24 +00:00
|
|
|
}
|
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
// TableInfo returns table's information via an object
|
2023-07-04 18:36:08 +00:00
|
|
|
func TableInfo(v any) (*schemas.Table, error) {
|
2024-12-20 16:11:38 +00:00
|
|
|
return xormEngine.TableInfo(v)
|
2021-09-19 11:49:59 +00:00
|
|
|
}
|
2016-11-26 00:20:18 +00:00
|
|
|
|
2024-12-20 16:11:38 +00:00
|
|
|
// RegisterModel registers model, if initFuncs provided, it will be invoked after data model sync
|
2023-07-04 18:36:08 +00:00
|
|
|
func RegisterModel(bean any, initFunc ...func() error) {
|
2024-12-20 16:11:38 +00:00
|
|
|
registeredModels = append(registeredModels, bean)
|
|
|
|
if len(registeredInitFuncs) > 0 && initFunc[0] != nil {
|
|
|
|
registeredInitFuncs = append(registeredInitFuncs, initFunc[0])
|
2020-01-20 15:45:14 +00:00
|
|
|
}
|
2014-09-04 15:19:26 +00:00
|
|
|
}
|
|
|
|
|
2022-01-20 17:46:10 +00:00
|
|
|
// SyncAllTables sync the schemas of all tables, is required by unit test code
|
2021-11-12 14:36:47 +00:00
|
|
|
func SyncAllTables() error {
|
2024-12-20 16:11:38 +00:00
|
|
|
_, err := xormEngine.StoreEngine("InnoDB").SyncWithOptions(xorm.SyncOptions{
|
2023-06-24 08:20:08 +00:00
|
|
|
WarnIfDatabaseColumnMissed: true,
|
2024-12-20 16:11:38 +00:00
|
|
|
}, registeredModels...)
|
2023-06-24 08:20:08 +00:00
|
|
|
return err
|
2021-06-14 02:22:55 +00:00
|
|
|
}
|
|
|
|
|
2020-09-06 21:52:01 +00:00
|
|
|
// NamesToBean return a list of beans or an error
|
2023-07-04 18:36:08 +00:00
|
|
|
func NamesToBean(names ...string) ([]any, error) {
|
|
|
|
beans := []any{}
|
2020-09-06 21:52:01 +00:00
|
|
|
if len(names) == 0 {
|
2024-12-20 16:11:38 +00:00
|
|
|
beans = append(beans, registeredModels...)
|
2020-09-06 21:52:01 +00:00
|
|
|
return beans, nil
|
|
|
|
}
|
|
|
|
// Need to map provided names to beans...
|
2023-07-04 18:36:08 +00:00
|
|
|
beanMap := make(map[string]any)
|
2024-12-20 16:11:38 +00:00
|
|
|
for _, bean := range registeredModels {
|
2020-09-06 21:52:01 +00:00
|
|
|
beanMap[strings.ToLower(reflect.Indirect(reflect.ValueOf(bean)).Type().Name())] = bean
|
2024-12-20 16:11:38 +00:00
|
|
|
beanMap[strings.ToLower(xormEngine.TableName(bean))] = bean
|
|
|
|
beanMap[strings.ToLower(xormEngine.TableName(bean, true))] = bean
|
2020-09-06 21:52:01 +00:00
|
|
|
}
|
|
|
|
|
2023-07-04 18:36:08 +00:00
|
|
|
gotBean := make(map[any]bool)
|
2020-09-06 21:52:01 +00:00
|
|
|
for _, name := range names {
|
|
|
|
bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))]
|
|
|
|
if !ok {
|
2022-10-18 05:50:37 +00:00
|
|
|
return nil, fmt.Errorf("no table found that matches: %s", name)
|
2020-09-06 21:52:01 +00:00
|
|
|
}
|
|
|
|
if !gotBean[bean] {
|
|
|
|
beans = append(beans, bean)
|
|
|
|
gotBean[bean] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return beans, nil
|
|
|
|
}
|
|
|
|
|
2019-07-06 19:24:50 +00:00
|
|
|
// MaxBatchInsertSize returns the table's max batch insert size
|
2023-07-04 18:36:08 +00:00
|
|
|
func MaxBatchInsertSize(bean any) int {
|
2024-12-20 16:11:38 +00:00
|
|
|
t, err := xormEngine.TableInfo(bean)
|
2020-03-22 15:12:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return 50
|
|
|
|
}
|
2019-07-06 19:24:50 +00:00
|
|
|
return 999 / len(t.ColumnsSeq())
|
|
|
|
}
|
2019-09-06 02:20:09 +00:00
|
|
|
|
2019-12-08 19:15:35 +00:00
|
|
|
// IsTableNotEmpty returns true if table has at least one record
|
2024-04-14 17:22:14 +00:00
|
|
|
func IsTableNotEmpty(beanOrTableName any) (bool, error) {
|
2024-12-20 16:11:38 +00:00
|
|
|
return xormEngine.Table(beanOrTableName).Exist()
|
2019-12-08 19:15:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteAllRecords will delete all the records of this table
|
|
|
|
func DeleteAllRecords(tableName string) error {
|
2024-12-20 16:11:38 +00:00
|
|
|
_, err := xormEngine.Exec(fmt.Sprintf("DELETE FROM %s", tableName))
|
2019-12-08 19:15:35 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetMaxID will return max id of the table
|
2023-07-04 18:36:08 +00:00
|
|
|
func GetMaxID(beanOrTableName any) (maxID int64, err error) {
|
2024-12-20 16:11:38 +00:00
|
|
|
_, err = xormEngine.Select("MAX(id)").Table(beanOrTableName).Get(&maxID)
|
2022-06-20 10:02:49 +00:00
|
|
|
return maxID, err
|
2019-12-08 19:15:35 +00:00
|
|
|
}
|
2022-06-24 10:49:47 +00:00
|
|
|
|
|
|
|
func SetLogSQL(ctx context.Context, on bool) {
|
|
|
|
e := GetEngine(ctx)
|
|
|
|
if x, ok := e.(*xorm.Engine); ok {
|
|
|
|
x.ShowSQL(on)
|
|
|
|
} else if sess, ok := e.(*xorm.Session); ok {
|
|
|
|
sess.Engine().ShowSQL(on)
|
|
|
|
}
|
|
|
|
}
|