ソースを参照

Handle default datasource management

Torkel Ödegaard 11 年 前
コミット
68cc3f86dd

+ 1 - 1
grafana

@@ -1 +1 @@
-Subproject commit 1b9b8ba2bff651a38592805c9210bd1864dc1e79
+Subproject commit 1d769fe41cf348d88636938fcb06afcf3425d45b

+ 1 - 2
pkg/api/datasources.go

@@ -29,6 +29,7 @@ func GetDataSources(c *middleware.Context) {
 			Database:  ds.Database,
 			User:      ds.User,
 			BasicAuth: ds.BasicAuth,
+			IsDefault: ds.IsDefault,
 		}
 	}
 
@@ -69,8 +70,6 @@ func AddDataSource(c *middleware.Context) {
 		return
 	}
 
-	//bus.Publish(&m.DataSourceCreatedEvent{Account: c.GetAccountId(), })
-
 	c.JsonOK("Datasource added")
 }
 

+ 1 - 0
pkg/api/dtos/models.go

@@ -30,6 +30,7 @@ type DataSource struct {
 	User      string          `json:"user"`
 	Database  string          `json:"database"`
 	BasicAuth bool            `json:"basicAuth"`
+	IsDefault bool            `json:"isDefault"`
 }
 
 type MetricQueryResultDto struct {

+ 3 - 2
pkg/api/frontendsettings.go

@@ -33,8 +33,9 @@ func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error)
 		}
 
 		var dsMap = map[string]interface{}{
-			"type": ds.Type,
-			"url":  url,
+			"type":    ds.Type,
+			"url":     url,
+			"default": ds.IsDefault,
 		}
 
 		if ds.Type == m.DS_INFLUXDB {

+ 43 - 1
pkg/bus/bus.go

@@ -10,11 +10,14 @@ type Msg interface{}
 
 type Bus interface {
 	Dispatch(msg Msg) error
+	Publish(msg Msg) error
 	AddHandler(handler HandlerFunc)
+	AddEventListener(handler HandlerFunc)
 }
 
 type InProcBus struct {
-	handlers map[string]HandlerFunc
+	handlers  map[string]HandlerFunc
+	listeners map[string][]HandlerFunc
 }
 
 // temp stuff, not sure how to handle bus instance, and init yet
@@ -23,6 +26,7 @@ var globalBus = New()
 func New() Bus {
 	bus := &InProcBus{}
 	bus.handlers = make(map[string]HandlerFunc)
+	bus.listeners = make(map[string][]HandlerFunc)
 	return bus
 }
 
@@ -46,17 +50,55 @@ func (b *InProcBus) Dispatch(msg Msg) error {
 	}
 }
 
+func (b *InProcBus) Publish(msg Msg) error {
+	var msgName = reflect.TypeOf(msg).Elem().Name()
+
+	var listeners = b.listeners[msgName]
+	if len(listeners) == 0 {
+		return nil
+	}
+
+	var params = make([]reflect.Value, 1)
+	params[0] = reflect.ValueOf(msg)
+
+	for listenerHandler := range listeners {
+		ret := reflect.ValueOf(listenerHandler).Call(params)
+		err := ret[0].Interface()
+		if err != nil {
+			return err.(error)
+		}
+	}
+
+	return nil
+}
+
 func (b *InProcBus) AddHandler(handler HandlerFunc) {
 	handlerType := reflect.TypeOf(handler)
 	queryTypeName := handlerType.In(0).Elem().Name()
 	b.handlers[queryTypeName] = handler
 }
 
+func (b *InProcBus) AddEventListener(handler HandlerFunc) {
+	handlerType := reflect.TypeOf(handler)
+	eventName := handlerType.In(0).Elem().Name()
+	list, exists := b.listeners[eventName]
+	if !exists {
+		list = make([]HandlerFunc, 0)
+		b.listeners[eventName] = list
+	}
+	list = append(list, handler)
+}
+
 // Package level functions
 func AddHandler(implName string, handler HandlerFunc) {
 	globalBus.AddHandler(handler)
 }
 
+// Package level functions
+func AddEventListener(handler HandlerFunc) {
+	globalBus.AddEventListener(handler)
+}
+
 func Dispatch(msg Msg) error {
 	return globalBus.Dispatch(msg)
 }

+ 23 - 0
pkg/bus/bus_test.go

@@ -43,3 +43,26 @@ func TestQueryHandlerReturn(t *testing.T) {
 		t.Fatal("Failed to get response from handler")
 	}
 }
+
+func TestEventListeners(t *testing.T) {
+	bus := New()
+	count := 0
+
+	bus.AddEventListener(func(query *TestQuery) error {
+		count += 1
+		return nil
+	})
+
+	bus.AddEventListener(func(query *TestQuery) error {
+		count += 10
+		return nil
+	})
+
+	err := bus.Publish(&TestQuery{})
+
+	if err != nil {
+		t.Fatal("Publish event failed " + err.Error())
+	} else if count != 0 {
+		t.Fatal("Publish event failed, listeners called: %v, expected: %v", count, 11)
+	}
+}

+ 11 - 17
pkg/models/account.go

@@ -12,18 +12,17 @@ var (
 )
 
 type Account struct {
-	Id                  int64
-	Login               string `xorm:"UNIQUE NOT NULL"`
-	Email               string `xorm:"UNIQUE NOT NULL"`
-	Name                string
-	FullName            string
-	Password            string
-	IsAdmin             bool
-	Salt                string `xorm:"VARCHAR(10)"`
-	Company             string
-	NextDashboardId     int
-	UsingAccountId      int64
-	DefaultDataSourceId int64
+	Id              int64
+	Login           string `xorm:"UNIQUE NOT NULL"`
+	Email           string `xorm:"UNIQUE NOT NULL"`
+	Name            string
+	FullName        string
+	Password        string
+	IsAdmin         bool
+	Salt            string `xorm:"VARCHAR(10)"`
+	Company         string
+	NextDashboardId int
+	UsingAccountId  int64
 
 	Created time.Time
 	Updated time.Time
@@ -48,11 +47,6 @@ type SetUsingAccountCommand struct {
 	UsingAccountId int64
 }
 
-type SetDefaultDataSourceCommand struct {
-	AccountId    int64
-	DataSourceId int64
-}
-
 // ----------------------
 // QUERIES
 

+ 6 - 1
pkg/models/datasource.go

@@ -33,6 +33,7 @@ type DataSource struct {
 	User      string
 	Database  string
 	BasicAuth bool
+	IsDefault bool
 
 	Created time.Time
 	Updated time.Time
@@ -41,8 +42,9 @@ type DataSource struct {
 // ----------------------
 // COMMANDS
 
+// Also acts as api DTO
 type AddDataSourceCommand struct {
-	AccountId int64
+	AccountId int64 `json:"-"`
 	Name      string
 	Type      DsType
 	Access    DsAccess
@@ -50,10 +52,12 @@ type AddDataSourceCommand struct {
 	Password  string
 	Database  string
 	User      string
+	IsDefault bool
 
 	Result *DataSource
 }
 
+// Also acts as api DTO
 type UpdateDataSourceCommand struct {
 	Id        int64
 	AccountId int64
@@ -64,6 +68,7 @@ type UpdateDataSourceCommand struct {
 	Password  string
 	User      string
 	Database  string
+	IsDefault bool
 }
 
 type DeleteDataSourceCommand struct {

+ 0 - 9
pkg/services/account/handlers.go

@@ -1,9 +0,0 @@
-package account
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/bus"
-)
-
-func InitAccountService() {
-	bus.ListenTo()
-}

+ 31 - 10
pkg/stores/sqlstore/datasource.go

@@ -45,9 +45,7 @@ func DeleteDataSource(cmd *m.DeleteDataSourceCommand) error {
 func AddDataSource(cmd *m.AddDataSourceCommand) error {
 
 	return inTransaction(func(sess *xorm.Session) error {
-		var err error
-
-		ds := m.DataSource{
+		ds := &m.DataSource{
 			AccountId: cmd.AccountId,
 			Name:      cmd.Name,
 			Type:      cmd.Type,
@@ -56,23 +54,38 @@ func AddDataSource(cmd *m.AddDataSourceCommand) error {
 			User:      cmd.User,
 			Password:  cmd.Password,
 			Database:  cmd.Database,
+			IsDefault: cmd.IsDefault,
 			Created:   time.Now(),
 			Updated:   time.Now(),
 		}
 
-		_, err = sess.Insert(&ds)
-		cmd.Result = &ds
+		if _, err := sess.Insert(ds); err != nil {
+			return err
+		}
+		if err := updateIsDefaultFlag(ds, sess); err != nil {
+			return err
+		}
 
-		return err
+		cmd.Result = ds
+		return nil
 	})
 }
 
+func updateIsDefaultFlag(ds *m.DataSource, sess *xorm.Session) error {
+	// Handle is default flag
+	if ds.IsDefault {
+		rawSql := "UPDATE data_source SET is_default = 0 WHERE account_id=? AND id <> ?"
+		if _, err := sess.Exec(rawSql, ds.AccountId, ds.Id); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
 
 	return inTransaction(func(sess *xorm.Session) error {
-		var err error
-
-		ds := m.DataSource{
+		ds := &m.DataSource{
 			Id:        cmd.Id,
 			AccountId: cmd.AccountId,
 			Name:      cmd.Name,
@@ -83,9 +96,17 @@ func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
 			Password:  cmd.Password,
 			Database:  cmd.Database,
 			Updated:   time.Now(),
+			IsDefault: cmd.IsDefault,
+		}
+
+		sess.UseBool("is_default")
+
+		_, err := sess.Where("id=? and account_id=?", ds.Id, ds.AccountId).Update(ds)
+		if err != nil {
+			return err
 		}
 
-		_, err = sess.Where("id=? and account_id=?", ds.Id, ds.AccountId).Update(&ds)
+		err = updateIsDefaultFlag(ds, sess)
 		return err
 	})
 }

+ 0 - 0
pkg/stores/sqlstore/sqlstore_test.go → pkg/stores/sqlstore/datasource_test.go