<commit_before>package datasources

import (
	"io/ioutil"
	"path/filepath"

	"github.com/grafana/grafana/pkg/bus"
	"github.com/grafana/grafana/pkg/log"

	"github.com/grafana/grafana/pkg/models"
	yaml "gopkg.in/yaml.v2"
)

type DatasourcesAsConfig struct {
	PurgeOtherDatasources bool
	Datasources           []DataSourceFromConfig
}

func Init(configPath string) error {
	dc := NewDatasourceConfiguration()
	return dc.applyChanges(configPath)
}

type DatasourceConfigurator struct {
	log         log.Logger
	cfgProvider configProvider
	repository  datasourceRepository
}

func NewDatasourceConfiguration() DatasourceConfigurator {
	return newDatasourceConfiguration(log.New("setting.datasource"), diskConfigReader{}, sqlDatasourceRepository{})
}

func newDatasourceConfiguration(log log.Logger, cfgProvider configProvider, repo datasourceRepository) DatasourceConfigurator {
	return DatasourceConfigurator{
		log:         log.New("setting.datasource"),
		repository:  repo,
		cfgProvider: cfgProvider,
	}
}

func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
	cfg, err := dc.cfgProvider.readConfig(configPath)
	if err != nil {
		return err
	}

	allDatasources, err := dc.repository.loadAllDatasources()
	if err != nil {
		return err
	}

	for i := range cfg.Datasources {
		if cfg.Datasources[i].OrgId == 0 {
			cfg.Datasources[i].OrgId = 1
		}
	}

	if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
		return err
	}

	for _, ds := range cfg.Datasources {
		var dbDatasource *models.DataSource
		for _, ddd := range allDatasources {
			if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
				dbDatasource = ddd
				break
			}
		}

		if dbDatasource == nil {
			dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
			insertCmd := createInsertCommand(ds)
			if err := dc.repository.insert(insertCmd); err != nil {
				return err
			}
		} else {
			dc.log.Info("updating datasource from configuration", "name", ds.Name)
			updateCmd := createUpdateCommand(ds, dbDatasource.Id)
			if err := dc.repository.update(updateCmd); err != nil {
				return err
			}
		}
	}

	return nil
}

func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
	if cfg.PurgeOtherDatasources {
		for _, dbDS := range allDatasources {
			delete := true
			for _, cfgDS := range cfg.Datasources {
				if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
					delete = false
				}
			}<commit_msg>datasource as cfg: ignore datasource all ready exist for inserts<commit_after>package datasources

import (
	"io/ioutil"
	"path/filepath"

	"github.com/grafana/grafana/pkg/bus"
	"github.com/grafana/grafana/pkg/log"

	"github.com/grafana/grafana/pkg/models"
	yaml "gopkg.in/yaml.v2"
)

type DatasourcesAsConfig struct {
	PurgeOtherDatasources bool
	Datasources           []DataSourceFromConfig
}

func Init(configPath string) error {
	dc := NewDatasourceConfiguration()
	return dc.applyChanges(configPath)
}

type DatasourceConfigurator struct {
	log         log.Logger
	cfgProvider configProvider
	repository  datasourceRepository
}

func NewDatasourceConfiguration() DatasourceConfigurator {
	return newDatasourceConfiguration(log.New("setting.datasource"), diskConfigReader{}, sqlDatasourceRepository{})
}

func newDatasourceConfiguration(log log.Logger, cfgProvider configProvider, repo datasourceRepository) DatasourceConfigurator {
	return DatasourceConfigurator{
		log:         log.New("setting.datasource"),
		repository:  repo,
		cfgProvider: cfgProvider,
	}
}

func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
	cfg, err := dc.cfgProvider.readConfig(configPath)
	if err != nil {
		return err
	}

	allDatasources, err := dc.repository.loadAllDatasources()
	if err != nil {
		return err
	}

	for i := range cfg.Datasources {
		if cfg.Datasources[i].OrgId == 0 {
			cfg.Datasources[i].OrgId = 1
		}
	}

	if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
		return err
	}

	for _, ds := range cfg.Datasources {
		var dbDatasource *models.DataSource
		for _, ddd := range allDatasources {
			if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
				dbDatasource = ddd
				break
			}
		}

		if dbDatasource == nil {
			dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
			insertCmd := createInsertCommand(ds)
			err := dc.repository.insert(insertCmd)
			if err != nil && err != models.ErrDataSourceNameExists {
				return err
			}
		} else {
			dc.log.Info("updating datasource from configuration", "name", ds.Name)
			updateCmd := createUpdateCommand(ds, dbDatasource.Id)
			if err := dc.repository.update(updateCmd); err != nil {
				return err
			}
		}
	}

	return nil
}

func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
	if cfg.PurgeOtherDatasources {
		for _, dbDS := range allDatasources {
			delete := true
			for _, cfgDS := range cfg.Datasources {
				if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
					delete = false
				}
			}
{'fraction_non_alphanumeric': 0.10858585858585859, 'fraction_numerical': 0.0011655011655011655, 'mean_word_length': 4.108134920634921, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6873165', 'n_tokens_mistral': 1891, 'n_tokens_neox': 1704, 'n_words': 369}