// 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 }
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") }
func (cd *ConnectionDetails) RetryLimit() int { i, err := strconv.Atoi(defaults.String(cd.Options["retry_limit"], "1000")) if err != nil { return 100 } return i }
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 }
// 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) }
// 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) }
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 }
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 }
"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 {
"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) } }
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) }, }