Esempio n. 1
0
// Finalize cleans up the connection details by normalizing names,
// filling in default values, etc...
func (cd *ConnectionDetails) Finalize() error {
	if cd.URL != "" {
		u, err := url.Parse(cd.URL)
		if err != nil {
			return errors.Wrapf(err, "couldn't parse %s", cd.URL)
		}
		cd.Dialect = u.Scheme
		cd.Database = u.Path

		hp := strings.Split(u.Host, ":")
		cd.Host = hp[0]
		if len(hp) > 1 {
			cd.Port = hp[1]
		}

		if u.User != nil {
			cd.User = u.User.Username()
			cd.Password, _ = u.User.Password()
		}
	}
	switch strings.ToLower(cd.Dialect) {
	case "postgres", "postgresql", "pg":
		cd.Dialect = "postgres"
		cd.Port = defaults.String(cd.Port, "5432")
		cd.Database = strings.TrimPrefix(cd.Database, "/")
	case "mysql":
		cd.Port = defaults.String(cd.Port, "3006")
		cd.Database = strings.TrimPrefix(cd.Database, "/")
	case "sqlite", "sqlite3":
		cd.Dialect = "sqlite3"
	default:
		return errors.Errorf("Unknown dialect %s!", cd.Dialect)
	}
	return nil
}
Esempio n. 2
0
func Test_String(t *testing.T) {
	a := assert.New(t)

	a.Equal(defaults.String("", "foo"), "foo")
	a.Equal(defaults.String("bar", "foo"), "bar")
	var s string
	a.Equal(defaults.String(s, "foo"), "foo")
}
Esempio n. 3
0
func (cd *ConnectionDetails) RetryLimit() int {
	i, err := strconv.Atoi(defaults.String(cd.Options["retry_limit"], "1000"))
	if err != nil {
		return 100
	}
	return i
}
Esempio n. 4
0
func (cd *ConnectionDetails) RetrySleep() time.Duration {
	d, err := time.ParseDuration(defaults.String(cd.Options["retry_sleep"], "1ms"))
	if err != nil {
		return 1 * time.Millisecond
	}
	return d
}
Esempio n. 5
0
// NewPaginatorFromParams takes an interface of type `PaginationParams`,
// the `url.Values` type works great with this interface, and returns
// a new `Paginator` based on the params or `PaginatorPageKey` and
// `PaginatorPerPageKey`. Defaults are `1` for the page and
// PaginatorPerPageDefault for the per page value.
func NewPaginatorFromParams(params PaginationParams) *Paginator {
	page := defaults.String(params.Get("page"), "1")

	per_page := defaults.String(params.Get("per_page"), strconv.Itoa(PaginatorPerPageDefault))

	p, err := strconv.Atoi(page)
	if err != nil {
		p = 1
	}

	pp, err := strconv.Atoi(per_page)
	if err != nil {
		pp = PaginatorPerPageDefault
	}
	return NewPaginator(p, pp)
}
Esempio n. 6
0
// Connect takes the name of a connection, default is "development", and will
// return that connection from the available `Connections`. If a connection with
// that name can not be found an error will be returned. If a connection is
// found, and it has yet to open a connection with its underlying datastore,
// a connection to that store will be opened.
func Connect(e string) (*Connection, error) {
	e = defaults.String(e, "development")
	c := Connections[e]
	if c == nil {
		return c, errors.Errorf("Could not find connection named %s!", e)
	}
	err := c.Open()
	return c, errors.Wrapf(err, "couldn't open connection for %s", e)
}
Esempio n. 7
0
func (m *sqlite) locker(l *sync.Mutex, fn func() error) error {
	if defaults.String(m.Details().Options["lock"], "true") == "true" {
		defer l.Unlock()
		l.Lock()
	}
	err := fn()
	attempts := 0
	for err != nil && err.Error() == "database is locked" && attempts <= m.Details().RetryLimit() {
		time.Sleep(m.Details().RetrySleep())
		err = fn()
		attempts++
	}
	return err
}
Esempio n. 8
0
func loadConfig(path string) error {
	if Debug {
		fmt.Printf("[POP]: Loading config file from %s\n", path)
	}
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return errors.Wrapf(err, "couldn't read file %s", path)
	}

	tmpl := template.New("test")
	tmpl.Funcs(map[string]interface{}{
		"envOr": func(s1, s2 string) string {
			return defaults.String(os.Getenv(s1), s2)
		},
		"env": func(s1 string) string {
			return os.Getenv(s1)
		},
	})
	t, err := tmpl.Parse(string(b))
	if err != nil {
		return errors.Wrap(err, "couldn't parse config template")
	}

	var bb bytes.Buffer
	err = t.Execute(&bb, nil)
	if err != nil {
		return errors.Wrap(err, "couldn't execute config template")
	}

	deets := map[string]*ConnectionDetails{}
	err = yaml.Unmarshal(bb.Bytes(), &deets)
	if err != nil {
		return errors.Wrap(err, "couldn't unmarshal config to yaml")
	}
	for n, d := range deets {
		con, err := NewConnection(d)
		if err != nil {
			return err
		}
		Connections[n] = con
	}
	return nil
}
Esempio n. 9
0
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

func init() {
	ConfigCmd.Flags().StringVarP(&dialect, "type", "t", "postgres", "What type of database do you want to use? (postgres, mysql, sqlite3)")
}

var dialect string

var ConfigCmd = &cobra.Command{
	Use:   "config",
	Short: "Generates a database.yml file for your project.",
	RunE: func(cmd *cobra.Command, args []string) error {
		cflag := cmd.Flag("config")
		cfgFile := defaults.String(cflag.Value.String(), "database.yml")
		dir, err := os.Getwd()
		if err != nil {
			return errors.Wrap(err, "couldn't get the current directory")
		}
		data := map[string]interface{}{
			"dialect": dialect,
			"name":    path.Base(dir),
		}
		return GenerateConfig(cfgFile, data)
	},
}

func GenerateConfig(cfgFile string, data map[string]interface{}) error {
	dialect = strings.ToLower(data["dialect"].(string))
	if t, ok := configTemplates[dialect]; ok {
Esempio n. 10
0
	"github.com/markbates/going/defaults"
	"github.com/markbates/pop"
	"github.com/spf13/cobra"
)

var cfgFile string
var env string
var version bool

var RootCmd = &cobra.Command{
	Use:     "soda",
	Aliases: []string{"db"},
	Short:   "A tasty treat for all your database needs",
	PersistentPreRun: func(c *cobra.Command, args []string) {
		fmt.Printf("Soda v%s\n\n", Version)
		env = defaults.String(os.Getenv("GO_ENV"), env)
		setConfigLocation()
	},
	Run: func(cmd *cobra.Command, args []string) {
		if !version {
			cmd.Help()
		}
	},
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
Esempio n. 11
0
package generate

import (
	"github.com/pkg/errors"

	"github.com/markbates/going/defaults"
	"github.com/markbates/pop"
	"github.com/spf13/cobra"
)

var FizzCmd = &cobra.Command{
	Use:     "fizz [name]",
	Aliases: []string{"migration"},
	Short:   "Generates Up/Down migrations for your database using fizz.",
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) == 0 {
			return errors.New("You must supply a name for your migration!")
		}
		cflag := cmd.Flag("path")
		migrationPath := defaults.String(cflag.Value.String(), "./migrations")
		return pop.MigrationCreate(migrationPath, args[0], "fizz", nil, nil)
	},
}