Chore: use any rather than interface{} (#74066)
This commit is contained in:
@@ -27,9 +27,9 @@ func normalizeBulkSettings(s BulkOpSettings) BulkOpSettings {
|
||||
return s
|
||||
}
|
||||
|
||||
func (sess *DBSession) BulkInsert(table interface{}, recordsSlice interface{}, opts BulkOpSettings) (int64, error) {
|
||||
func (sess *DBSession) BulkInsert(table any, recordsSlice any, opts BulkOpSettings) (int64, error) {
|
||||
var inserted int64
|
||||
err := InBatches(recordsSlice, opts, func(batch interface{}) error {
|
||||
err := InBatches(recordsSlice, opts, func(batch any) error {
|
||||
a, err := sess.Table(table).InsertMulti(batch)
|
||||
inserted += a
|
||||
return err
|
||||
@@ -37,7 +37,7 @@ func (sess *DBSession) BulkInsert(table interface{}, recordsSlice interface{}, o
|
||||
return inserted, err
|
||||
}
|
||||
|
||||
func InBatches(items interface{}, opts BulkOpSettings, fn func(batch interface{}) error) error {
|
||||
func InBatches(items any, opts BulkOpSettings, fn func(batch any) error) error {
|
||||
opts = normalizeBulkSettings(opts)
|
||||
slice := reflect.Indirect(reflect.ValueOf(items))
|
||||
if slice.Kind() != reflect.Slice {
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestBatching(t *testing.T) {
|
||||
t.Run("InBatches", func(t *testing.T) {
|
||||
t.Run("calls fn 0 times if items is empty", func(t *testing.T) {
|
||||
var calls int
|
||||
fn := func(batch interface{}) error { calls += 1; return nil }
|
||||
fn := func(batch any) error { calls += 1; return nil }
|
||||
opts := BulkOpSettings{BatchSize: DefaultBatchSize}
|
||||
|
||||
err := InBatches([]int{}, opts, fn)
|
||||
@@ -27,7 +27,7 @@ func TestBatching(t *testing.T) {
|
||||
|
||||
t.Run("succeeds if batch size is nonpositive", func(t *testing.T) {
|
||||
var calls int
|
||||
fn := func(batch interface{}) error { calls += 1; return nil }
|
||||
fn := func(batch any) error { calls += 1; return nil }
|
||||
opts := BulkOpSettings{BatchSize: DefaultBatchSize}
|
||||
|
||||
err := InBatches([]int{1, 2, 3}, opts, fn)
|
||||
@@ -38,7 +38,7 @@ func TestBatching(t *testing.T) {
|
||||
|
||||
t.Run("rejects if items is not a slice", func(t *testing.T) {
|
||||
var calls int
|
||||
fn := func(batch interface{}) error { calls += 1; return nil }
|
||||
fn := func(batch any) error { calls += 1; return nil }
|
||||
opts := BulkOpSettings{BatchSize: DefaultBatchSize}
|
||||
|
||||
err := InBatches("lol", opts, fn)
|
||||
@@ -48,7 +48,7 @@ func TestBatching(t *testing.T) {
|
||||
|
||||
t.Run("calls expected number of times when batch size does not evenly divide length", func(t *testing.T) {
|
||||
var calls int
|
||||
fn := func(batch interface{}) error { calls += 1; return nil }
|
||||
fn := func(batch any) error { calls += 1; return nil }
|
||||
opts := BulkOpSettings{BatchSize: 5}
|
||||
vals := make([]int, 93)
|
||||
|
||||
@@ -86,7 +86,7 @@ func TestIntegrationBulkOps(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func assertTableCount(t *testing.T, db *SQLStore, table interface{}, expCount int64) {
|
||||
func assertTableCount(t *testing.T, db *SQLStore, table any, expCount int64) {
|
||||
t.Helper()
|
||||
err := db.WithDbSession(context.Background(), func(sess *DBSession) error {
|
||||
total, err := sess.Table(bulkTestItem{}).Count()
|
||||
|
||||
@@ -68,12 +68,12 @@ type databaseQueryWrapper struct {
|
||||
type databaseQueryWrapperKey struct{}
|
||||
|
||||
// Before hook will print the query with its args and return the context with the timestamp
|
||||
func (h *databaseQueryWrapper) Before(ctx context.Context, query string, args ...interface{}) (context.Context, error) {
|
||||
func (h *databaseQueryWrapper) Before(ctx context.Context, query string, args ...any) (context.Context, error) {
|
||||
return context.WithValue(ctx, databaseQueryWrapperKey{}, time.Now()), nil
|
||||
}
|
||||
|
||||
// After hook will get the timestamp registered on the Before hook and print the elapsed time
|
||||
func (h *databaseQueryWrapper) After(ctx context.Context, query string, args ...interface{}) (context.Context, error) {
|
||||
func (h *databaseQueryWrapper) After(ctx context.Context, query string, args ...any) (context.Context, error) {
|
||||
h.instrument(ctx, "success", query, nil)
|
||||
|
||||
return ctx, nil
|
||||
@@ -111,7 +111,7 @@ func (h *databaseQueryWrapper) instrument(ctx context.Context, status string, qu
|
||||
}
|
||||
|
||||
// OnError will be called if any error happens
|
||||
func (h *databaseQueryWrapper) OnError(ctx context.Context, err error, query string, args ...interface{}) error {
|
||||
func (h *databaseQueryWrapper) OnError(ctx context.Context, err error, query string, args ...any) error {
|
||||
// Not a user error: driver is telling sql package that an
|
||||
// optional interface method is not implemented. There is
|
||||
// nothing to instrument here.
|
||||
|
||||
@@ -23,56 +23,56 @@ func NewXormLogger(level glog.Lvl, grafanaLog glog.Logger) *XormLogger {
|
||||
}
|
||||
|
||||
// Error implement core.ILogger
|
||||
func (s *XormLogger) Error(v ...interface{}) {
|
||||
func (s *XormLogger) Error(v ...any) {
|
||||
if s.level <= glog.LvlError {
|
||||
s.grafanaLog.Error(fmt.Sprint(v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf implement core.ILogger
|
||||
func (s *XormLogger) Errorf(format string, v ...interface{}) {
|
||||
func (s *XormLogger) Errorf(format string, v ...any) {
|
||||
if s.level <= glog.LvlError {
|
||||
s.grafanaLog.Error(fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Debug implement core.ILogger
|
||||
func (s *XormLogger) Debug(v ...interface{}) {
|
||||
func (s *XormLogger) Debug(v ...any) {
|
||||
if s.level <= glog.LvlDebug {
|
||||
s.grafanaLog.Debug(fmt.Sprint(v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Debugf implement core.ILogger
|
||||
func (s *XormLogger) Debugf(format string, v ...interface{}) {
|
||||
func (s *XormLogger) Debugf(format string, v ...any) {
|
||||
if s.level <= glog.LvlDebug {
|
||||
s.grafanaLog.Debug(fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Info implement core.ILogger
|
||||
func (s *XormLogger) Info(v ...interface{}) {
|
||||
func (s *XormLogger) Info(v ...any) {
|
||||
if s.level <= glog.LvlInfo {
|
||||
s.grafanaLog.Info(fmt.Sprint(v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Infof implement core.ILogger
|
||||
func (s *XormLogger) Infof(format string, v ...interface{}) {
|
||||
func (s *XormLogger) Infof(format string, v ...any) {
|
||||
if s.level <= glog.LvlInfo {
|
||||
s.grafanaLog.Info(fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Warn implement core.ILogger
|
||||
func (s *XormLogger) Warn(v ...interface{}) {
|
||||
func (s *XormLogger) Warn(v ...any) {
|
||||
if s.level <= glog.LvlWarn {
|
||||
s.grafanaLog.Warn(fmt.Sprint(v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Warnf implement core.ILogger
|
||||
func (s *XormLogger) Warnf(format string, v ...interface{}) {
|
||||
func (s *XormLogger) Warnf(format string, v ...any) {
|
||||
if s.level <= glog.LvlWarn {
|
||||
s.grafanaLog.Warn(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ func (m *actionNameMigrator) migrateActionNames() error {
|
||||
"alert.rules:update": accesscontrol.ActionAlertingRuleUpdate,
|
||||
}
|
||||
|
||||
oldActionNames := make([]interface{}, 0, len(actionNameMapping))
|
||||
newActionNames := make([]interface{}, 0, len(actionNameMapping))
|
||||
oldActionNames := make([]any, 0, len(actionNameMapping))
|
||||
newActionNames := make([]any, 0, len(actionNameMapping))
|
||||
for oldName, newName := range actionNameMapping {
|
||||
oldActionNames = append(oldActionNames, oldName)
|
||||
newActionNames = append(newActionNames, newName)
|
||||
|
||||
@@ -87,7 +87,7 @@ func (m *adminOnlyMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) erro
|
||||
|
||||
// Remove managed permission for editors and viewers if there was any
|
||||
removeSQL := `DELETE FROM permission WHERE scope = ? AND role_id IN(?` + strings.Repeat(", ?", len(roleIDS)-1) + `) `
|
||||
params := []interface{}{removeSQL, scope}
|
||||
params := []any{removeSQL, scope}
|
||||
for _, id := range roleIDS {
|
||||
params = append(params, id)
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func (m *managedFolderAlertActionsMigrator) SQL(dialect migrator.Dialect) string
|
||||
}
|
||||
|
||||
func (m *managedFolderAlertActionsMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
|
||||
var ids []interface{}
|
||||
var ids []any
|
||||
if err := sess.SQL("SELECT id FROM role WHERE name LIKE 'managed:%'").Find(&ids); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func (m *managedFolderAlertActionsRepeatMigrator) SQL(dialect migrator.Dialect)
|
||||
}
|
||||
|
||||
func (m *managedFolderAlertActionsRepeatMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
|
||||
var ids []interface{}
|
||||
var ids []any
|
||||
if err := sess.SQL("SELECT id FROM role WHERE name LIKE 'managed:%'").Find(&ids); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (m *DisabledMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) error
|
||||
return fmt.Errorf("failed to remove managed rbac roles: %w", err)
|
||||
}
|
||||
|
||||
params := []interface{}{"DELETE FROM migration_log WHERE migration_id IN (?, ?, ?, ?, ?, ?, ?, ?)"}
|
||||
params := []any{"DELETE FROM migration_log WHERE migration_id IN (?, ?, ?, ?, ?, ?, ?, ?)"}
|
||||
for _, m := range migrations {
|
||||
params = append(params, m)
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ func (m *permissionMigrator) createRoles(roles []*accesscontrol.Role) ([]*access
|
||||
ts := time.Now()
|
||||
createdRoles := make([]*accesscontrol.Role, 0, len(roles))
|
||||
valueStrings := make([]string, len(roles))
|
||||
args := make([]interface{}, 0, len(roles)*5)
|
||||
args := make([]any, 0, len(roles)*5)
|
||||
|
||||
for i, r := range roles {
|
||||
uid, err := GenerateManagedRoleUID(r.OrgID, r.Name)
|
||||
@@ -160,7 +160,7 @@ func (m *permissionMigrator) createRolesMySQL(roles []*accesscontrol.Role) ([]*a
|
||||
createdRoles := make([]*accesscontrol.Role, 0, len(roles))
|
||||
|
||||
where := make([]string, len(roles))
|
||||
args := make([]interface{}, 0, len(roles)*2)
|
||||
args := make([]any, 0, len(roles)*2)
|
||||
|
||||
for i := range roles {
|
||||
uid, err := GenerateManagedRoleUID(roles[i].OrgID, roles[i].Name)
|
||||
|
||||
@@ -64,7 +64,7 @@ func (e externalAlertmanagerToDatasources) Exec(sess *xorm.Session, mg *migrator
|
||||
Updated: time.Unix(result.UpdatedAt, 0),
|
||||
UID: uid,
|
||||
Version: 1,
|
||||
JsonData: simplejson.NewFromAny(map[string]interface{}{
|
||||
JsonData: simplejson.NewFromAny(map[string]any{
|
||||
"handleGrafanaManagedAlerts": true,
|
||||
"implementation": "prometheus",
|
||||
}),
|
||||
|
||||
@@ -309,7 +309,7 @@ func (d duration) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (d *duration) UnmarshalJSON(b []byte) error {
|
||||
var v interface{}
|
||||
var v any
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -22,22 +22,22 @@ func TestMigrateAlertRuleQueries(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "when a query has a sub query - it is extracted",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{"targetFull": "thisisafullquery", "target": "ahalfquery"}),
|
||||
input: simplejson.NewFromAny(map[string]any{"targetFull": "thisisafullquery", "target": "ahalfquery"}),
|
||||
expected: `{"target":"thisisafullquery"}`,
|
||||
},
|
||||
{
|
||||
name: "when a query does not have a sub query - it no-ops",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{"target": "ahalfquery"}),
|
||||
input: simplejson.NewFromAny(map[string]any{"target": "ahalfquery"}),
|
||||
expected: `{"target":"ahalfquery"}`,
|
||||
},
|
||||
{
|
||||
name: "when query was hidden, it removes the flag",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{"hide": true}),
|
||||
input: simplejson.NewFromAny(map[string]any{"hide": true}),
|
||||
expected: `{}`,
|
||||
},
|
||||
{
|
||||
name: "when prometheus both type query, convert to range",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{
|
||||
input: simplejson.NewFromAny(map[string]any{
|
||||
"datasource": map[string]string{
|
||||
"type": "prometheus",
|
||||
},
|
||||
@@ -48,7 +48,7 @@ func TestMigrateAlertRuleQueries(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "when prometheus instant type query, do nothing",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{
|
||||
input: simplejson.NewFromAny(map[string]any{
|
||||
"datasource": map[string]string{
|
||||
"type": "prometheus",
|
||||
},
|
||||
@@ -58,7 +58,7 @@ func TestMigrateAlertRuleQueries(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "when non-prometheus with instant and range, do nothing",
|
||||
input: simplejson.NewFromAny(map[string]interface{}{
|
||||
input: simplejson.NewFromAny(map[string]any{
|
||||
"datasource": map[string]string{
|
||||
"type": "something",
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ type channelsPerOrg map[int64][]*notificationChannel
|
||||
type defaultChannelsPerOrg map[int64][]*notificationChannel
|
||||
|
||||
// uidOrID for both uid and ID, primarily used for mapping legacy channel to migrated receiver.
|
||||
type uidOrID interface{}
|
||||
type uidOrID any
|
||||
|
||||
// channelReceiver is a convenience struct that contains a notificationChannel and its corresponding migrated PostableApiReceiver.
|
||||
type channelReceiver struct {
|
||||
@@ -130,7 +130,7 @@ func (m *migration) setupAlertmanagerConfigs(rulesPerOrg map[int64]map[*alertRul
|
||||
}
|
||||
|
||||
// contactListToString creates a sorted string representation of a given map (set) of receiver names. Each name will be comma-separated and double-quoted. Names should not contain double quotes.
|
||||
func contactListToString(m map[string]interface{}) string {
|
||||
func contactListToString(m map[string]any) string {
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, quote(k))
|
||||
@@ -338,14 +338,14 @@ func createRoute(cr channelReceiver) (*Route, error) {
|
||||
}
|
||||
|
||||
// Filter receivers to select those that were associated to the given rule as channels.
|
||||
func (m *migration) filterReceiversForAlert(name string, channelIDs []uidOrID, receivers map[uidOrID]*PostableApiReceiver, defaultReceivers map[string]struct{}) map[string]interface{} {
|
||||
func (m *migration) filterReceiversForAlert(name string, channelIDs []uidOrID, receivers map[uidOrID]*PostableApiReceiver, defaultReceivers map[string]struct{}) map[string]any {
|
||||
if len(channelIDs) == 0 {
|
||||
// If there are no channels associated, we use the default route.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Filter receiver names.
|
||||
filteredReceiverNames := make(map[string]interface{})
|
||||
filteredReceiverNames := make(map[string]any)
|
||||
for _, uidOrId := range channelIDs {
|
||||
recv, ok := receivers[uidOrId]
|
||||
if ok {
|
||||
@@ -355,7 +355,7 @@ func (m *migration) filterReceiversForAlert(name string, channelIDs []uidOrID, r
|
||||
}
|
||||
}
|
||||
|
||||
coveredByDefault := func(names map[string]interface{}) bool {
|
||||
coveredByDefault := func(names map[string]any) bool {
|
||||
// Check if all receivers are also default ones and if so, just use the default route.
|
||||
for n := range names {
|
||||
if _, ok := defaultReceivers[n]; !ok {
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestFilterReceiversForAlert(t *testing.T) {
|
||||
channelIds []uidOrID
|
||||
receivers map[uidOrID]*PostableApiReceiver
|
||||
defaultReceivers map[string]struct{}
|
||||
expected map[string]interface{}
|
||||
expected map[string]any
|
||||
}{
|
||||
{
|
||||
name: "when an alert has multiple channels, each should filter for the correct receiver",
|
||||
@@ -40,7 +40,7 @@ func TestFilterReceiversForAlert(t *testing.T) {
|
||||
},
|
||||
},
|
||||
defaultReceivers: map[string]struct{}{},
|
||||
expected: map[string]interface{}{
|
||||
expected: map[string]any{
|
||||
"recv1": struct{}{},
|
||||
"recv2": struct{}{},
|
||||
},
|
||||
@@ -65,7 +65,7 @@ func TestFilterReceiversForAlert(t *testing.T) {
|
||||
defaultReceivers: map[string]struct{}{
|
||||
"recv2": {},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
expected: map[string]any{
|
||||
"recv1": struct{}{}, // From alert
|
||||
"recv2": struct{}{}, // From default
|
||||
},
|
||||
@@ -80,7 +80,7 @@ func TestFilterReceiversForAlert(t *testing.T) {
|
||||
},
|
||||
},
|
||||
defaultReceivers: map[string]struct{}{},
|
||||
expected: map[string]interface{}{
|
||||
expected: map[string]any{
|
||||
"recv1": struct{}{},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -110,7 +110,7 @@ func transConditions(set dashAlertSettings, orgID int64, dsUIDMap dsUIDLookup) (
|
||||
continue
|
||||
}
|
||||
|
||||
var queryObj map[string]interface{} // copy the model
|
||||
var queryObj map[string]any // copy the model
|
||||
err := json.Unmarshal(set.Conditions[condIdx].Query.Model, &queryObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -308,7 +308,7 @@ type classicConditionJSON struct {
|
||||
} `json:"query"`
|
||||
|
||||
Reducer struct {
|
||||
// Params []interface{} `json:"params"` (Unused)
|
||||
// Params []any `json:"params"` (Unused)
|
||||
Type string `json:"type"`
|
||||
} `json:"reducer"`
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ type dashAlertSettings struct {
|
||||
NoDataState string `json:"noDataState"`
|
||||
ExecutionErrorState string `json:"executionErrorState"`
|
||||
Conditions []dashAlertCondition `json:"conditions"`
|
||||
AlertRuleTags interface{} `json:"alertRuleTags"`
|
||||
AlertRuleTags any `json:"alertRuleTags"`
|
||||
Notifications []dashAlertNot `json:"notifications"`
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ type dashAlertCondition struct {
|
||||
} `json:"query"`
|
||||
|
||||
Reducer struct {
|
||||
// Params []interface{} `json:"params"` (Unused)
|
||||
// Params []any `json:"params"` (Unused)
|
||||
Type string `json:"type"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func (m *folderHelper) createFolder(orgID int64, title string) (*dashboard, erro
|
||||
OrgId: orgID,
|
||||
FolderId: 0,
|
||||
IsFolder: true,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
Dashboard: simplejson.NewFromAny(map[string]any{
|
||||
"title": title,
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -682,7 +682,7 @@ func (u *upgradeNgAlerting) updateAlertConfigurations(sess *xorm.Session, migrat
|
||||
// Otherwise, it deletes those files.
|
||||
// pre-8.2 version put all configuration files into the root of alerting directory. Since 8.2 configuration files are put in organization specific directory
|
||||
func (u *upgradeNgAlerting) updateAlertmanagerFiles(orgId int64, migrator *migrator.Migrator) {
|
||||
knownFiles := map[string]interface{}{"__default__.tmpl": nil, "silences": nil, "notifications": nil}
|
||||
knownFiles := map[string]any{"__default__.tmpl": nil, "silences": nil, "notifications": nil}
|
||||
alertingDir := filepath.Join(migrator.Cfg.DataPath, "alerting")
|
||||
|
||||
// do not fail if something goes wrong because these files are not used anymore. the worst that can happen is that we leave some leftovers behind
|
||||
@@ -858,7 +858,7 @@ func (c updateRulesOrderInGroup) Exec(sess *xorm.Session, migrator *migrator.Mig
|
||||
}
|
||||
|
||||
updated := time.Now()
|
||||
versions := make([]interface{}, 0, len(toUpdate))
|
||||
versions := make([]any, 0, len(toUpdate))
|
||||
|
||||
for _, rule := range toUpdate {
|
||||
rule.Updated = updated
|
||||
|
||||
@@ -47,8 +47,8 @@ type Dialect interface {
|
||||
|
||||
UpdateTableSQL(tableName string, columns []*Column) string
|
||||
|
||||
IndexCheckSQL(tableName, indexName string) (string, []interface{})
|
||||
ColumnCheckSQL(tableName, columnName string) (string, []interface{})
|
||||
IndexCheckSQL(tableName, indexName string) (string, []any)
|
||||
ColumnCheckSQL(tableName, columnName string) (string, []any)
|
||||
// UpsertSQL returns the upsert sql statement for a dialect
|
||||
UpsertSQL(tableName string, keyCols, updateCols []string) string
|
||||
UpsertMultipleSQL(tableName string, keyCols, updateCols []string, count int) (string, error)
|
||||
@@ -235,7 +235,7 @@ func (b *BaseDialect) RenameColumn(table Table, column *Column, newName string)
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BaseDialect) ColumnCheckSQL(tableName, columnName string) (string, []interface{}) {
|
||||
func (b *BaseDialect) ColumnCheckSQL(tableName, columnName string) (string, []any) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
|
||||
@@ -111,14 +111,14 @@ func (db *MySQLDialect) UpdateTableSQL(tableName string, columns []*Column) stri
|
||||
return "ALTER TABLE " + db.Quote(tableName) + " " + strings.Join(statements, ", ") + ";"
|
||||
}
|
||||
|
||||
func (db *MySQLDialect) IndexCheckSQL(tableName, indexName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, indexName}
|
||||
func (db *MySQLDialect) IndexCheckSQL(tableName, indexName string) (string, []any) {
|
||||
args := []any{tableName, indexName}
|
||||
sql := "SELECT 1 FROM " + db.Quote("INFORMATION_SCHEMA") + "." + db.Quote("STATISTICS") + " WHERE " + db.Quote("TABLE_SCHEMA") + " = DATABASE() AND " + db.Quote("TABLE_NAME") + "=? AND " + db.Quote("INDEX_NAME") + "=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
func (db *MySQLDialect) ColumnCheckSQL(tableName, columnName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, columnName}
|
||||
func (db *MySQLDialect) ColumnCheckSQL(tableName, columnName string) (string, []any) {
|
||||
args := []any{tableName, columnName}
|
||||
sql := "SELECT 1 FROM " + db.Quote("INFORMATION_SCHEMA") + "." + db.Quote("COLUMNS") + " WHERE " + db.Quote("TABLE_SCHEMA") + " = DATABASE() AND " + db.Quote("TABLE_NAME") + "=? AND " + db.Quote("COLUMN_NAME") + "=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ func (db *PostgresDialect) SQLType(c *Column) string {
|
||||
return res
|
||||
}
|
||||
|
||||
func (db *PostgresDialect) IndexCheckSQL(tableName, indexName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, indexName}
|
||||
func (db *PostgresDialect) IndexCheckSQL(tableName, indexName string) (string, []any) {
|
||||
args := []any{tableName, indexName}
|
||||
sql := "SELECT 1 FROM " + db.Quote("pg_indexes") + " WHERE" + db.Quote("tablename") + "=? AND " + db.Quote("indexname") + "=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ func (db *SQLite3) SQLType(c *Column) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (db *SQLite3) IndexCheckSQL(tableName, indexName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, indexName}
|
||||
func (db *SQLite3) IndexCheckSQL(tableName, indexName string) (string, []any) {
|
||||
args := []any{tableName, indexName}
|
||||
sql := "SELECT 1 FROM " + db.Quote("sqlite_master") + " WHERE " + db.Quote("type") + "='index' AND " + db.Quote("tbl_name") + "=? AND " + db.Quote("name") + "=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ const maximumRecursiveQueries = 2
|
||||
|
||||
type clause struct {
|
||||
string
|
||||
params []interface{}
|
||||
params []any
|
||||
}
|
||||
|
||||
type accessControlDashboardPermissionFilter struct {
|
||||
@@ -36,11 +36,11 @@ type accessControlDashboardPermissionFilter struct {
|
||||
|
||||
type PermissionsFilter interface {
|
||||
LeftJoin() string
|
||||
With() (string, []interface{})
|
||||
Where() (string, []interface{})
|
||||
With() (string, []any)
|
||||
Where() (string, []any)
|
||||
|
||||
buildClauses()
|
||||
nestedFoldersSelectors(permSelector string, permSelectorArgs []interface{}, leftTableCol string, rightTableCol string) (string, []interface{})
|
||||
nestedFoldersSelectors(permSelector string, permSelectorArgs []any, leftTableCol string, rightTableCol string) (string, []any)
|
||||
}
|
||||
|
||||
// NewAccessControlDashboardPermissionFilter creates a new AccessControlDashboardPermissionFilter that is configured with specific actions calculated based on the dashboards.PermissionType and query type
|
||||
@@ -106,7 +106,7 @@ func (f *accessControlDashboardPermissionFilter) LeftJoin() string {
|
||||
// Where returns:
|
||||
// - a where clause for filtering dashboards with expected permissions
|
||||
// - an array with the query parameters
|
||||
func (f *accessControlDashboardPermissionFilter) Where() (string, []interface{}) {
|
||||
func (f *accessControlDashboardPermissionFilter) Where() (string, []any) {
|
||||
return f.where.string, f.where.params
|
||||
}
|
||||
|
||||
@@ -120,12 +120,12 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.OrgID, f.user.UserID, f.user.Teams, accesscontrol.GetOrgRoles(f.user))
|
||||
rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") "
|
||||
var args []interface{}
|
||||
var args []any
|
||||
builder := strings.Builder{}
|
||||
builder.WriteRune('(')
|
||||
|
||||
permSelector := strings.Builder{}
|
||||
var permSelectorArgs []interface{}
|
||||
var permSelectorArgs []any
|
||||
|
||||
// useSelfContainedPermissions is true if the user's permissions are stored and set from the JWT token
|
||||
// currently it's used for the extended JWT module (when the user is authenticated via a JWT token generated by Grafana)
|
||||
@@ -305,9 +305,9 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
|
||||
// With returns:
|
||||
// - a with clause for fetching folders with inherited permissions if nested folders are enabled or an empty string
|
||||
func (f *accessControlDashboardPermissionFilter) With() (string, []interface{}) {
|
||||
func (f *accessControlDashboardPermissionFilter) With() (string, []any) {
|
||||
var sb bytes.Buffer
|
||||
var params []interface{}
|
||||
var params []any
|
||||
if len(f.recQueries) > 0 {
|
||||
sb.WriteString("WITH RECURSIVE ")
|
||||
sb.WriteString(f.recQueries[0].string)
|
||||
@@ -321,11 +321,11 @@ func (f *accessControlDashboardPermissionFilter) With() (string, []interface{})
|
||||
return sb.String(), params
|
||||
}
|
||||
|
||||
func (f *accessControlDashboardPermissionFilter) addRecQry(queryName string, whereUIDSelect string, whereParams []interface{}) {
|
||||
func (f *accessControlDashboardPermissionFilter) addRecQry(queryName string, whereUIDSelect string, whereParams []any) {
|
||||
if f.recQueries == nil {
|
||||
f.recQueries = make([]clause, 0, maximumRecursiveQueries)
|
||||
}
|
||||
c := make([]interface{}, len(whereParams))
|
||||
c := make([]any, len(whereParams))
|
||||
copy(c, whereParams)
|
||||
f.recQueries = append(f.recQueries, clause{
|
||||
string: fmt.Sprintf(`%s AS (
|
||||
@@ -336,8 +336,8 @@ func (f *accessControlDashboardPermissionFilter) addRecQry(queryName string, whe
|
||||
})
|
||||
}
|
||||
|
||||
func actionsToCheck(actions []string, permissions map[string][]string, wildcards ...accesscontrol.Wildcards) []interface{} {
|
||||
toCheck := make([]interface{}, 0, len(actions))
|
||||
func actionsToCheck(actions []string, permissions map[string][]string, wildcards ...accesscontrol.Wildcards) []any {
|
||||
toCheck := make([]any, 0, len(actions))
|
||||
|
||||
for _, a := range actions {
|
||||
var hasWildcard bool
|
||||
@@ -359,9 +359,9 @@ func actionsToCheck(actions []string, permissions map[string][]string, wildcards
|
||||
return toCheck
|
||||
}
|
||||
|
||||
func (f *accessControlDashboardPermissionFilter) nestedFoldersSelectors(permSelector string, permSelectorArgs []interface{}, leftTableCol string, rightTableCol string) (string, []interface{}) {
|
||||
func (f *accessControlDashboardPermissionFilter) nestedFoldersSelectors(permSelector string, permSelectorArgs []any, leftTableCol string, rightTableCol string) (string, []any) {
|
||||
wheres := make([]string, 0, folder.MaxNestedFolderDepth+1)
|
||||
args := make([]interface{}, 0, len(permSelectorArgs)*(folder.MaxNestedFolderDepth+1))
|
||||
args := make([]any, 0, len(permSelectorArgs)*(folder.MaxNestedFolderDepth+1))
|
||||
|
||||
joins := make([]string, 0, folder.MaxNestedFolderDepth+2)
|
||||
|
||||
@@ -384,7 +384,7 @@ func (f *accessControlDashboardPermissionFilter) nestedFoldersSelectors(permSele
|
||||
return strings.Join(wheres, ") OR "), args
|
||||
}
|
||||
|
||||
func parseStringSliceFromInterfaceSlice(slice []interface{}) []string {
|
||||
func parseStringSliceFromInterfaceSlice(slice []any) []string {
|
||||
result := make([]string, 0, len(slice))
|
||||
for _, s := range slice {
|
||||
result = append(result, s.(string))
|
||||
@@ -392,7 +392,7 @@ func parseStringSliceFromInterfaceSlice(slice []interface{}) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func getAllowedUIDs(actions []string, user *user.SignedInUser, scopePrefix string) []interface{} {
|
||||
func getAllowedUIDs(actions []string, user *user.SignedInUser, scopePrefix string) []any {
|
||||
uidToActions := make(map[string]map[string]struct{})
|
||||
for _, action := range actions {
|
||||
for _, uidScope := range user.Permissions[user.OrgID][action] {
|
||||
@@ -408,7 +408,7 @@ func getAllowedUIDs(actions []string, user *user.SignedInUser, scopePrefix strin
|
||||
}
|
||||
|
||||
// args max capacity is the length of the different uids
|
||||
args := make([]interface{}, 0, len(uidToActions))
|
||||
args := make([]any, 0, len(uidToActions))
|
||||
for uid, assignedActions := range uidToActions {
|
||||
if len(assignedActions) == len(actions) {
|
||||
args = append(args, uid)
|
||||
|
||||
@@ -34,12 +34,12 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
||||
|
||||
filter, params := accesscontrol.UserRolesFilter(f.user.OrgID, f.user.UserID, f.user.Teams, accesscontrol.GetOrgRoles(f.user))
|
||||
rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") "
|
||||
var args []interface{}
|
||||
var args []any
|
||||
builder := strings.Builder{}
|
||||
builder.WriteRune('(')
|
||||
|
||||
permSelector := strings.Builder{}
|
||||
var permSelectorArgs []interface{}
|
||||
var permSelectorArgs []any
|
||||
|
||||
// useSelfContainedPermissions is true if the user's permissions are stored and set from the JWT token
|
||||
// currently it's used for the extended JWT module (when the user is authenticated via a JWT token generated by Grafana)
|
||||
@@ -217,9 +217,9 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
||||
f.where = clause{string: builder.String(), params: args}
|
||||
}
|
||||
|
||||
func (f *accessControlDashboardPermissionFilterNoFolderSubquery) nestedFoldersSelectors(permSelector string, permSelectorArgs []interface{}, leftTableCol string, _ string) (string, []interface{}) {
|
||||
func (f *accessControlDashboardPermissionFilterNoFolderSubquery) nestedFoldersSelectors(permSelector string, permSelectorArgs []any, leftTableCol string, _ string) (string, []any) {
|
||||
wheres := make([]string, 0, folder.MaxNestedFolderDepth+1)
|
||||
args := make([]interface{}, 0, len(permSelectorArgs)*(folder.MaxNestedFolderDepth+1))
|
||||
args := make([]any, 0, len(permSelectorArgs)*(folder.MaxNestedFolderDepth+1))
|
||||
|
||||
joins := make([]string, 0, folder.MaxNestedFolderDepth+2)
|
||||
|
||||
|
||||
@@ -380,14 +380,14 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permission dashboards.PermissionType
|
||||
permissions []accesscontrol.Permission
|
||||
expectedResult []string
|
||||
features []interface{}
|
||||
features []any
|
||||
}{
|
||||
{
|
||||
desc: "Should not be able to view dashboards under inherited folders with no permissions if nested folders are enabled",
|
||||
queryType: searchstore.TypeDashboard,
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
permissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
@@ -395,14 +395,14 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
queryType: searchstore.TypeFolder,
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
permissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
desc: "Should not be able to view inherited dashboards and folders with no permissions if nested folders are enabled",
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
permissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
@@ -412,7 +412,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: dashboards.ScopeFoldersAll},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -422,7 +422,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -432,7 +432,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"dashboard under parent folder"},
|
||||
},
|
||||
{
|
||||
@@ -442,7 +442,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"parent", "subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -452,7 +452,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
permissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"parent"},
|
||||
},
|
||||
{
|
||||
@@ -462,7 +462,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"parent", "subfolder", "dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -472,7 +472,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"parent", "dashboard under parent folder"},
|
||||
},
|
||||
}
|
||||
@@ -533,14 +533,14 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
permission dashboards.PermissionType
|
||||
signedInUserPermissions []accesscontrol.Permission
|
||||
expectedResult []string
|
||||
features []interface{}
|
||||
features []any
|
||||
}{
|
||||
{
|
||||
desc: "Should not be able to view dashboards under inherited folders with no permissions if nested folders are enabled",
|
||||
queryType: searchstore.TypeDashboard,
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
signedInUserPermissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
@@ -548,14 +548,14 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
queryType: searchstore.TypeFolder,
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
signedInUserPermissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
desc: "Should not be able to view inherited dashboards and folders with no permissions if nested folders are enabled",
|
||||
permission: dashboards.PERMISSION_VIEW,
|
||||
signedInUserPermissions: nil,
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
@@ -565,7 +565,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
signedInUserPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: dashboards.ScopeFoldersAll},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -575,7 +575,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
signedInUserPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -585,7 +585,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
signedInUserPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"dashboard under parent folder"},
|
||||
},
|
||||
{
|
||||
@@ -595,7 +595,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
signedInUserPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"parent", "subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -605,7 +605,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
signedInUserPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"parent"},
|
||||
},
|
||||
{
|
||||
@@ -615,7 +615,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"parent", "subfolder", "dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
{
|
||||
@@ -625,7 +625,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
features: []any{},
|
||||
expectedResult: []string{"parent", "dashboard under parent folder"},
|
||||
},
|
||||
{
|
||||
@@ -639,7 +639,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "folders:uid:parent"},
|
||||
{Action: dashboards.ActionDashboardsWrite, Scope: "folders:uid:parent"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedResult: []string{"subfolder", "dashboard under parent folder", "dashboard under subfolder"},
|
||||
},
|
||||
}
|
||||
@@ -817,7 +817,7 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
|
||||
_, err = dashStore.SaveDashboard(context.Background(), dashboards.SaveDashboardCommand{
|
||||
OrgID: orgID,
|
||||
FolderID: parent.ID,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
Dashboard: simplejson.NewFromAny(map[string]any{
|
||||
"title": "dashboard under parent folder",
|
||||
}),
|
||||
})
|
||||
@@ -827,7 +827,7 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
|
||||
_, err = dashStore.SaveDashboard(context.Background(), dashboards.SaveDashboardCommand{
|
||||
OrgID: orgID,
|
||||
FolderID: subfolder.ID,
|
||||
Dashboard: simplejson.NewFromAny(map[string]interface{}{
|
||||
Dashboard: simplejson.NewFromAny(map[string]any{
|
||||
"title": "dashboard under subfolder",
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -13,16 +13,16 @@ import (
|
||||
type Builder struct {
|
||||
// List of FilterWhere/FilterGroupBy/FilterOrderBy/FilterLeftJoin
|
||||
// to modify the query.
|
||||
Filters []interface{}
|
||||
Filters []any
|
||||
Dialect migrator.Dialect
|
||||
|
||||
params []interface{}
|
||||
params []any
|
||||
sql bytes.Buffer
|
||||
}
|
||||
|
||||
// ToSQL builds the SQL query and returns it as a string, together with the SQL parameters.
|
||||
func (b *Builder) ToSQL(limit, page int64) (string, []interface{}) {
|
||||
b.params = make([]interface{}, 0)
|
||||
func (b *Builder) ToSQL(limit, page int64) (string, []any) {
|
||||
b.params = make([]any, 0)
|
||||
b.sql = bytes.Buffer{}
|
||||
|
||||
b.buildSelect()
|
||||
@@ -45,7 +45,7 @@ func (b *Builder) ToSQL(limit, page int64) (string, []interface{}) {
|
||||
|
||||
func (b *Builder) buildSelect() {
|
||||
var recQuery string
|
||||
var recQueryParams []interface{}
|
||||
var recQueryParams []any
|
||||
|
||||
b.sql.WriteString(
|
||||
`SELECT
|
||||
@@ -90,10 +90,10 @@ func (b *Builder) applyFilters() (ordering string) {
|
||||
orderJoins := []string{}
|
||||
|
||||
wheres := []string{}
|
||||
whereParams := []interface{}{}
|
||||
whereParams := []any{}
|
||||
|
||||
groups := []string{}
|
||||
groupParams := []interface{}{}
|
||||
groupParams := []any{}
|
||||
|
||||
orders := []string{}
|
||||
|
||||
|
||||
@@ -12,20 +12,20 @@ import (
|
||||
// which the filter is applicable. Results where the first value is
|
||||
// an empty string are discarded.
|
||||
type FilterWhere interface {
|
||||
Where() (string, []interface{})
|
||||
Where() (string, []any)
|
||||
}
|
||||
|
||||
// FilterWith returns any recursive CTE queries (if supported)
|
||||
// and their parameters
|
||||
type FilterWith interface {
|
||||
With() (string, []interface{})
|
||||
With() (string, []any)
|
||||
}
|
||||
|
||||
// FilterGroupBy should be used after performing an outer join on the
|
||||
// search result to ensure there is only one of each ID in the results.
|
||||
// The id column must be present in the result.
|
||||
type FilterGroupBy interface {
|
||||
GroupBy() (string, []interface{})
|
||||
GroupBy() (string, []any)
|
||||
}
|
||||
|
||||
// FilterOrderBy provides an ordering for the search result.
|
||||
@@ -55,7 +55,7 @@ type TypeFilter struct {
|
||||
Type string
|
||||
}
|
||||
|
||||
func (f TypeFilter) Where() (string, []interface{}) {
|
||||
func (f TypeFilter) Where() (string, []any) {
|
||||
if f.Type == TypeFolder || f.Type == TypeAlertFolder {
|
||||
return "dashboard.is_folder = " + f.Dialect.BooleanStr(true), nil
|
||||
}
|
||||
@@ -71,8 +71,8 @@ type OrgFilter struct {
|
||||
OrgId int64
|
||||
}
|
||||
|
||||
func (f OrgFilter) Where() (string, []interface{}) {
|
||||
return "dashboard.org_id=?", []interface{}{f.OrgId}
|
||||
func (f OrgFilter) Where() (string, []any) {
|
||||
return "dashboard.org_id=?", []any{f.OrgId}
|
||||
}
|
||||
|
||||
type TitleFilter struct {
|
||||
@@ -80,15 +80,15 @@ type TitleFilter struct {
|
||||
Title string
|
||||
}
|
||||
|
||||
func (f TitleFilter) Where() (string, []interface{}) {
|
||||
return fmt.Sprintf("dashboard.title %s ?", f.Dialect.LikeStr()), []interface{}{"%" + f.Title + "%"}
|
||||
func (f TitleFilter) Where() (string, []any) {
|
||||
return fmt.Sprintf("dashboard.title %s ?", f.Dialect.LikeStr()), []any{"%" + f.Title + "%"}
|
||||
}
|
||||
|
||||
type FolderFilter struct {
|
||||
IDs []int64
|
||||
}
|
||||
|
||||
func (f FolderFilter) Where() (string, []interface{}) {
|
||||
func (f FolderFilter) Where() (string, []any) {
|
||||
return sqlIDin("dashboard.folder_id", f.IDs)
|
||||
}
|
||||
|
||||
@@ -98,12 +98,12 @@ type FolderUIDFilter struct {
|
||||
UIDs []string
|
||||
}
|
||||
|
||||
func (f FolderUIDFilter) Where() (string, []interface{}) {
|
||||
func (f FolderUIDFilter) Where() (string, []any) {
|
||||
if len(f.UIDs) < 1 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
params := []interface{}{}
|
||||
params := []any{}
|
||||
includeGeneral := false
|
||||
for _, uid := range f.UIDs {
|
||||
if uid == folder.GeneralFolderUID {
|
||||
@@ -119,11 +119,11 @@ func (f FolderUIDFilter) Where() (string, []interface{}) {
|
||||
// do nothing
|
||||
case len(params) == 1:
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid = ?)"
|
||||
params = append([]interface{}{f.OrgID}, params...)
|
||||
params = append([]any{f.OrgID}, params...)
|
||||
default:
|
||||
sqlArray := "(?" + strings.Repeat(",?", len(params)-1) + ")"
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN " + sqlArray + ")"
|
||||
params = append([]interface{}{f.OrgID}, params...)
|
||||
params = append([]any{f.OrgID}, params...)
|
||||
}
|
||||
|
||||
if includeGeneral {
|
||||
@@ -142,7 +142,7 @@ type DashboardIDFilter struct {
|
||||
IDs []int64
|
||||
}
|
||||
|
||||
func (f DashboardIDFilter) Where() (string, []interface{}) {
|
||||
func (f DashboardIDFilter) Where() (string, []any) {
|
||||
return sqlIDin("dashboard.id", f.IDs)
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ type DashboardFilter struct {
|
||||
UIDs []string
|
||||
}
|
||||
|
||||
func (f DashboardFilter) Where() (string, []interface{}) {
|
||||
func (f DashboardFilter) Where() (string, []any) {
|
||||
return sqlUIDin("dashboard.uid", f.UIDs)
|
||||
}
|
||||
|
||||
@@ -162,12 +162,12 @@ func (f TagsFilter) LeftJoin() string {
|
||||
return `dashboard_tag ON dashboard_tag.dashboard_id = dashboard.id`
|
||||
}
|
||||
|
||||
func (f TagsFilter) GroupBy() (string, []interface{}) {
|
||||
return `dashboard.id HAVING COUNT(dashboard.id) >= ?`, []interface{}{len(f.Tags)}
|
||||
func (f TagsFilter) GroupBy() (string, []any) {
|
||||
return `dashboard.id HAVING COUNT(dashboard.id) >= ?`, []any{len(f.Tags)}
|
||||
}
|
||||
|
||||
func (f TagsFilter) Where() (string, []interface{}) {
|
||||
params := make([]interface{}, len(f.Tags))
|
||||
func (f TagsFilter) Where() (string, []any) {
|
||||
params := make([]any, len(f.Tags))
|
||||
for i, tag := range f.Tags {
|
||||
params[i] = tag
|
||||
}
|
||||
@@ -186,7 +186,7 @@ func (s TitleSorter) OrderBy() string {
|
||||
return "dashboard.title ASC"
|
||||
}
|
||||
|
||||
func sqlIDin(column string, ids []int64) (string, []interface{}) {
|
||||
func sqlIDin(column string, ids []int64) (string, []any) {
|
||||
length := len(ids)
|
||||
if length < 1 {
|
||||
return "", nil
|
||||
@@ -194,14 +194,14 @@ func sqlIDin(column string, ids []int64) (string, []interface{}) {
|
||||
|
||||
sqlArray := "(?" + strings.Repeat(",?", length-1) + ")"
|
||||
|
||||
params := []interface{}{}
|
||||
params := []any{}
|
||||
for _, id := range ids {
|
||||
params = append(params, id)
|
||||
}
|
||||
return fmt.Sprintf("%s IN %s", column, sqlArray), params
|
||||
}
|
||||
|
||||
func sqlUIDin(column string, uids []string) (string, []interface{}) {
|
||||
func sqlUIDin(column string, uids []string) (string, []any) {
|
||||
length := len(uids)
|
||||
if length < 1 {
|
||||
return "", nil
|
||||
@@ -209,7 +209,7 @@ func sqlUIDin(column string, uids []string) (string, []interface{}) {
|
||||
|
||||
sqlArray := "(?" + strings.Repeat(",?", length-1) + ")"
|
||||
|
||||
params := []interface{}{}
|
||||
params := []any{}
|
||||
for _, id := range uids {
|
||||
params = append(params, id)
|
||||
}
|
||||
@@ -222,6 +222,6 @@ type FolderWithAlertsFilter struct {
|
||||
|
||||
var _ FilterWhere = &FolderWithAlertsFilter{}
|
||||
|
||||
func (f FolderWithAlertsFilter) Where() (string, []interface{}) {
|
||||
func (f FolderWithAlertsFilter) Where() (string, []any) {
|
||||
return "EXISTS (SELECT 1 FROM alert_rule WHERE alert_rule.namespace_uid = dashboard.uid)", nil
|
||||
}
|
||||
|
||||
@@ -12,31 +12,31 @@ func TestFolderUIDFilter(t *testing.T) {
|
||||
description string
|
||||
uids []string
|
||||
expectedSql string
|
||||
expectedParams []interface{}
|
||||
expectedParams []any
|
||||
}{
|
||||
{
|
||||
description: "searching general folder",
|
||||
uids: []string{"general"},
|
||||
expectedSql: "dashboard.folder_id = ? ",
|
||||
expectedParams: []interface{}{0},
|
||||
expectedParams: []any{0},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folder",
|
||||
uids: []string{"abc-123"},
|
||||
expectedSql: "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid = ?)",
|
||||
expectedParams: []interface{}{int64(1), "abc-123"},
|
||||
expectedParams: []any{int64(1), "abc-123"},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folders",
|
||||
uids: []string{"abc-123", "def-456"},
|
||||
expectedSql: "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN (?,?))",
|
||||
expectedParams: []interface{}{int64(1), "abc-123", "def-456"},
|
||||
expectedParams: []any{int64(1), "abc-123", "def-456"},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folders or general",
|
||||
uids: []string{"general", "abc-123", "def-456"},
|
||||
expectedSql: "(dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN (?,?)) OR dashboard.folder_id = ?)",
|
||||
expectedParams: []interface{}{int64(1), "abc-123", "def-456", 0},
|
||||
expectedParams: []any{int64(1), "abc-123", "def-456", 0},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestBuilder_EqualResults_Basic(t *testing.T) {
|
||||
createDashboards(t, store, 1, 2, 2)
|
||||
|
||||
builder := &searchstore.Builder{
|
||||
Filters: []interface{}{
|
||||
Filters: []any{
|
||||
searchstore.OrgFilter{OrgId: user.OrgID},
|
||||
searchstore.TitleSorter{},
|
||||
},
|
||||
@@ -79,7 +79,7 @@ func TestBuilder_Pagination(t *testing.T) {
|
||||
createDashboards(t, store, 0, 25, user.OrgID)
|
||||
|
||||
builder := &searchstore.Builder{
|
||||
Filters: []interface{}{
|
||||
Filters: []any{
|
||||
searchstore.OrgFilter{OrgId: user.OrgID},
|
||||
searchstore.TitleSorter{},
|
||||
},
|
||||
@@ -118,13 +118,13 @@ func TestBuilder_RBAC(t *testing.T) {
|
||||
testsCases := []struct {
|
||||
desc string
|
||||
userPermissions []accesscontrol.Permission
|
||||
features []interface{}
|
||||
expectedParams []interface{}
|
||||
features []any
|
||||
expectedParams []any
|
||||
}{
|
||||
{
|
||||
desc: "no user permissions",
|
||||
features: []interface{}{},
|
||||
expectedParams: []interface{}{
|
||||
features: []any{},
|
||||
expectedParams: []any{
|
||||
int64(1),
|
||||
},
|
||||
},
|
||||
@@ -133,8 +133,8 @@ func TestBuilder_RBAC(t *testing.T) {
|
||||
userPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:1"},
|
||||
},
|
||||
features: []interface{}{},
|
||||
expectedParams: []interface{}{
|
||||
features: []any{},
|
||||
expectedParams: []any{
|
||||
int64(1),
|
||||
int64(1),
|
||||
int64(1),
|
||||
@@ -170,8 +170,8 @@ func TestBuilder_RBAC(t *testing.T) {
|
||||
userPermissions: []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:1"},
|
||||
},
|
||||
features: []interface{}{featuremgmt.FlagNestedFolders},
|
||||
expectedParams: []interface{}{
|
||||
features: []any{featuremgmt.FlagNestedFolders},
|
||||
expectedParams: []any{
|
||||
int64(1),
|
||||
int64(1),
|
||||
0,
|
||||
@@ -232,7 +232,7 @@ func TestBuilder_RBAC(t *testing.T) {
|
||||
level := dashboards.PERMISSION_EDIT
|
||||
|
||||
builder := &searchstore.Builder{
|
||||
Filters: []interface{}{
|
||||
Filters: []any{
|
||||
searchstore.OrgFilter{OrgId: user.OrgID},
|
||||
searchstore.TitleSorter{},
|
||||
permissions.NewAccessControlDashboardPermissionFilter(
|
||||
|
||||
@@ -24,16 +24,16 @@ var ErrMaximumRetriesReached = errutil.Internal("sqlstore.max-retries-reached")
|
||||
type DBSession struct {
|
||||
*xorm.Session
|
||||
transactionOpen bool
|
||||
events []interface{}
|
||||
events []any
|
||||
}
|
||||
|
||||
type DBTransactionFunc func(sess *DBSession) error
|
||||
|
||||
func (sess *DBSession) publishAfterCommit(msg interface{}) {
|
||||
func (sess *DBSession) publishAfterCommit(msg any) {
|
||||
sess.events = append(sess.events, msg)
|
||||
}
|
||||
|
||||
func (sess *DBSession) PublishAfterCommit(msg interface{}) {
|
||||
func (sess *DBSession) PublishAfterCommit(msg any) {
|
||||
sess.events = append(sess.events, msg)
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ func (ss *SQLStore) withDbSession(ctx context.Context, engine *xorm.Engine, call
|
||||
return retryer.Retry(ss.retryOnLocks(ctx, callback, sess, retry), ss.dbCfg.QueryRetries, time.Millisecond*time.Duration(10), time.Second)
|
||||
}
|
||||
|
||||
func (sess *DBSession) InsertId(bean interface{}, dialect migrator.Dialect) error {
|
||||
func (sess *DBSession) InsertId(bean any, dialect migrator.Dialect) error {
|
||||
table := sess.DB().Mapper.Obj2Table(getTypeName(bean))
|
||||
|
||||
if err := dialect.PreInsertId(table, sess.Session); err != nil {
|
||||
@@ -143,7 +143,7 @@ func (sess *DBSession) InsertId(bean interface{}, dialect migrator.Dialect) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sess *DBSession) WithReturningID(driverName string, query string, args []interface{}) (int64, error) {
|
||||
func (sess *DBSession) WithReturningID(driverName string, query string, args []any) (int64, error) {
|
||||
supported := driverName != migrator.Postgres
|
||||
var id int64
|
||||
if !supported {
|
||||
@@ -152,7 +152,7 @@ func (sess *DBSession) WithReturningID(driverName string, query string, args []i
|
||||
return id, err
|
||||
}
|
||||
} else {
|
||||
sqlOrArgs := append([]interface{}{query}, args...)
|
||||
sqlOrArgs := append([]any{query}, args...)
|
||||
res, err := sess.Exec(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return id, err
|
||||
@@ -165,7 +165,7 @@ func (sess *DBSession) WithReturningID(driverName string, query string, args []i
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func getTypeName(bean interface{}) (res string) {
|
||||
func getTypeName(bean any) (res string) {
|
||||
t := reflect.TypeOf(bean)
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
)
|
||||
|
||||
type Session interface {
|
||||
Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error
|
||||
Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
|
||||
NamedExec(ctx context.Context, query string, arg interface{}) (sql.Result, error)
|
||||
Get(ctx context.Context, dest any, query string, args ...any) error
|
||||
Exec(ctx context.Context, query string, args ...any) (sql.Result, error)
|
||||
NamedExec(ctx context.Context, query string, arg any) (sql.Result, error)
|
||||
}
|
||||
|
||||
type SessionDB struct {
|
||||
@@ -22,23 +22,23 @@ func GetSession(sqlxdb *sqlx.DB) *SessionDB {
|
||||
return &SessionDB{sqlxdb: sqlxdb}
|
||||
}
|
||||
|
||||
func (gs *SessionDB) Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
func (gs *SessionDB) Get(ctx context.Context, dest any, query string, args ...any) error {
|
||||
return gs.sqlxdb.GetContext(ctx, dest, gs.sqlxdb.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gs *SessionDB) Select(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
func (gs *SessionDB) Select(ctx context.Context, dest any, query string, args ...any) error {
|
||||
return gs.sqlxdb.SelectContext(ctx, dest, gs.sqlxdb.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gs *SessionDB) Query(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
func (gs *SessionDB) Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return gs.sqlxdb.QueryContext(ctx, gs.sqlxdb.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gs *SessionDB) Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
func (gs *SessionDB) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
return gs.sqlxdb.ExecContext(ctx, gs.sqlxdb.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gs *SessionDB) NamedExec(ctx context.Context, query string, arg interface{}) (sql.Result, error) {
|
||||
func (gs *SessionDB) NamedExec(ctx context.Context, query string, arg any) (sql.Result, error) {
|
||||
return gs.sqlxdb.NamedExecContext(ctx, gs.sqlxdb.Rebind(query), arg)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func (gs *SessionDB) WithTransaction(ctx context.Context, callback func(*Session
|
||||
return tx.sqlxtx.Commit()
|
||||
}
|
||||
|
||||
func (gs *SessionDB) ExecWithReturningId(ctx context.Context, query string, args ...interface{}) (int64, error) {
|
||||
func (gs *SessionDB) ExecWithReturningId(ctx context.Context, query string, args ...any) (int64, error) {
|
||||
return execWithReturningId(ctx, gs.driverName(), query, gs, args...)
|
||||
}
|
||||
|
||||
@@ -76,19 +76,19 @@ type SessionTx struct {
|
||||
sqlxtx *sqlx.Tx
|
||||
}
|
||||
|
||||
func (gtx *SessionTx) NamedExec(ctx context.Context, query string, arg interface{}) (sql.Result, error) {
|
||||
func (gtx *SessionTx) NamedExec(ctx context.Context, query string, arg any) (sql.Result, error) {
|
||||
return gtx.sqlxtx.NamedExecContext(ctx, gtx.sqlxtx.Rebind(query), arg)
|
||||
}
|
||||
|
||||
func (gtx *SessionTx) Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
func (gtx *SessionTx) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
return gtx.sqlxtx.ExecContext(ctx, gtx.sqlxtx.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gtx *SessionTx) Query(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
func (gtx *SessionTx) Query(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return gtx.sqlxtx.QueryContext(ctx, gtx.sqlxtx.Rebind(query), args...)
|
||||
}
|
||||
|
||||
func (gtx *SessionTx) Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
func (gtx *SessionTx) Get(ctx context.Context, dest any, query string, args ...any) error {
|
||||
return gtx.sqlxtx.GetContext(ctx, dest, gtx.sqlxtx.Rebind(query), args...)
|
||||
}
|
||||
|
||||
@@ -96,11 +96,11 @@ func (gtx *SessionTx) driverName() string {
|
||||
return gtx.sqlxtx.DriverName()
|
||||
}
|
||||
|
||||
func (gtx *SessionTx) ExecWithReturningId(ctx context.Context, query string, args ...interface{}) (int64, error) {
|
||||
func (gtx *SessionTx) ExecWithReturningId(ctx context.Context, query string, args ...any) (int64, error) {
|
||||
return execWithReturningId(ctx, gtx.driverName(), query, gtx, args...)
|
||||
}
|
||||
|
||||
func execWithReturningId(ctx context.Context, driverName string, query string, sess Session, args ...interface{}) (int64, error) {
|
||||
func execWithReturningId(ctx context.Context, driverName string, query string, sess Session, args ...any) (int64, error) {
|
||||
supported := false
|
||||
var id int64
|
||||
if driverName == "postgres" {
|
||||
|
||||
@@ -559,9 +559,9 @@ func (ss *SQLStore) RecursiveQueriesAreSupported() (bool, error) {
|
||||
// ITestDB is an interface of arguments for testing db
|
||||
type ITestDB interface {
|
||||
Helper()
|
||||
Fatalf(format string, args ...interface{})
|
||||
Logf(format string, args ...interface{})
|
||||
Log(args ...interface{})
|
||||
Fatalf(format string, args ...any)
|
||||
Logf(format string, args ...any)
|
||||
Log(args ...any)
|
||||
}
|
||||
|
||||
var testSQLStore *SQLStore
|
||||
|
||||
Reference in New Issue
Block a user