func main() { hd, err := hood.Open("postgres", "user=greg password=greg dbname=computerblue") if err != nil { panic(err) } hd = hd.Begin() fmt.Println(hd.IsTransaction()) err = hd.CreateTable(&NewContacts{}) if err != nil { panic(err) } contacts := []NewContacts{ NewContacts{Name: "Baz", Address: "1012 Horton St. Emeryville CA"}, NewContacts{Name: "Bill", Address: "2040 Hahn St. Berkeley CA"}, } _, err = hd.SaveAll(&contacts) if err != nil { panic(err) } err = hd.Commit() if err != nil { panic(err) } }
/* Create a db connection based on a configuration string */ func GetDbConnectionByConfig(config string) *hood.Hood { hd, err := hood.Open("postgres", config) if err != nil { panic(err) } return hd }
func NewOrm(connectionString string) *Orm { hd, err := hood.Open("postgres", connectionString) if err != nil { panic(fmt.Sprintf("Failed to connect to database %s", err)) } o := &Orm{hd} return o }
func CreateDatabaseConnection() *hood.Hood { username, _ := configuration.GetString(config.CONFIG_DB_USER) password, _ := configuration.GetString(config.CONFIG_DB_PASSWORD) scheme, _ := configuration.GetString(config.CONFIG_DB_SCHEME) connectionString := fmt.Sprintf("%v/%v/%v", scheme, username, password) hd, err := hood.Open("mymysql", connectionString) if err != nil { log.Error("DatabaseHelper", "CreateDatabaseConnection", "Unable to connect to database scheme '%s' with supplied credentials '%s'.\nError: %s", scheme, username, err.Error()) return nil } return hd }
func initializeDatabase() { log.Verbose("main", "initializeDatabase", "Creating database connection") username, _ := configuration.GetString(config.CONFIG_DB_USER) password, _ := configuration.GetString(config.CONFIG_DB_PASSWORD) scheme, _ := configuration.GetString(config.CONFIG_DB_SCHEME) connectionString := fmt.Sprintf("%v/%v/%v", scheme, username, password) hd, err := hood.Open("mymysql", connectionString) if err != nil { log.Error("main", "initializeDatabase", "Unable to connect to database scheme '%s' with supplied credentials '%s'", scheme, username) panic("Unable to connect to database") } hd.Log = DEBUG_SQL mainDatabase = hd log.Info("main", "initializeDatabase", "Database connection initialized: %s", connectionString) }
func main() { // Open a DB connection, use New() alternatively for unregistered dialects hd, err := hood.Open("postgres", "user=hood dbname=hood_test sslmode=disable") if err != nil { panic(err) } // Create a table type Fruit struct { Id hood.Id Name string `validate:"presence"` Color string } err = hd.CreateTable(&Fruit{}) if err != nil { panic(err) } fruits := []Fruit{ Fruit{Name: "banana", Color: "yellow"}, Fruit{Name: "apple", Color: "red"}, Fruit{Name: "grapefruit", Color: "yellow"}, Fruit{Name: "grape", Color: "green"}, Fruit{Name: "pear", Color: "yellow"}, } // Start a transaction tx := hd.Begin() ids, err := tx.SaveAll(&fruits) if err != nil { panic(err) } fmt.Println("inserted ids:", ids) // [1 2 3 4 5] // Commit changes err = tx.Commit() if err != nil { panic(err) } // Ids are automatically updated if fruits[0].Id != 1 || fruits[1].Id != 2 || fruits[2].Id != 3 { panic("id not set") } // If an id is already set, a call to save will result in an update fruits[0].Color = "green" ids, err = hd.SaveAll(&fruits) if err != nil { panic(err) } fmt.Println("updated ids:", ids) // [1 2 3 4 5] if fruits[0].Id != 1 || fruits[1].Id != 2 || fruits[2].Id != 3 { panic("id not set") } // Let's try to save a row that does not satisfy the required validations _, err = hd.Save(&Fruit{}) if err == nil || err.Error() != "value not set" { panic("does not satisfy validations, should not save") } // Find // // The markers are db agnostic, so you can always use '?' // e.g. in Postgres they are replaced with $1, $2, ... var results []Fruit err = hd.Where("color = ?", "green").OrderBy("name").Limit(1).Find(&results) if err != nil { panic(err) } fmt.Println("results:", results) // [{1 banana green}] // Delete ids, err = hd.DeleteAll(&results) if err != nil { panic(err) } fmt.Println("deleted ids:", ids) // [1] results = nil err = hd.Find(&results) if err != nil { panic(err) } fmt.Println("results:", results) // [{2 apple red} {3 grapefruit yellow} {4 grape green} {5 pear yellow}] // Drop hd.DropTable(&Fruit{}) }
func main() { // Print action if steps > 0 { log.Printf("applying migrations...") } else if steps == -1 { log.Printf("rolling back by 1...") } else if steps < 0 { log.Printf("reset. rolling back all migrations...") } // Parse migrations stamps := []int{} ups := map[int]reflect.Method{} downs := map[int]reflect.Method{} structVal := reflect.ValueOf(&M{}) for i := 0; i < structVal.NumMethod(); i++ { method := structVal.Type().Method(i) if c := strings.Split(method.Name, "_"); len(c) >= 3 { stamp, _ := strconv.Atoi(c[len(c)-2]) if c[len(c)-1] == "Up" { ups[stamp] = method stamps = append(stamps, stamp) } else { downs[stamp] = method } } } sort.Ints(stamps) // Open hood hd, err := hood.Open(driver, source) if err != nil { panic(err) } hd.Log = true // Create migration table if necessary tx := hd.Begin() tx.CreateTableIfNotExists(&Migrations{}) err = tx.Commit() if err != nil { panic(err) } // Check if any previous migrations have been run var rows []Migrations err = hd.Find(&rows) if err != nil { panic(err) } if len(rows) > 1 { panic("invalid migrations table") } info := Migrations{} if len(rows) > 0 { info = rows[0] } // Apply cur := 0 count := 0 if steps > 0 { for _, stamp := range stamps { if stamp > info.Current { if cur++; cur <= steps { apply(stamp, stamp, &count, hd, &info, structVal, ups[stamp]) } } } } else if steps < 0 { for i := len(stamps) - 1; i >= 0; i-- { stamp := stamps[i] next := 0 if i > 0 { next = stamps[i-1] } if stamp <= info.Current { if cur--; cur >= steps { apply(stamp, next, &count, hd, &info, structVal, downs[stamp]) } } } } if steps > 0 { log.Printf("applied %d migrations", count) } else if steps < 0 { log.Printf("rolled back %d migrations", count) } log.Printf("generating new schema... %s", schemaPath) dry := hood.Dry() for _, ts := range stamps { if ts <= info.Current { method := ups[ts] method.Func.Call([]reflect.Value{structVal, reflect.ValueOf(dry)}) } } err = ioutil.WriteFile(schemaPath, []byte(dry.GoSchema()), 0666) if err != nil { panic(err) } err = exec.Command("go", "fmt", schemaPath).Run() if err != nil { panic(err) } log.Printf("wrote schema %s", schemaPath) log.Printf("done.") }
func main() { // Determine direction up := true if len(os.Args) > 1 { if x := os.Args[1]; x == "down" { up = false } } if up { fmt.Println("applying migrations...") } else { fmt.Println("rolling back...") } // Get up/down migration methods v := reflect.ValueOf(&M{}) numMethods := v.NumMethod() stamps := make([]int, 0, numMethods) ups := make(map[int]reflect.Method) downs := make(map[int]reflect.Method) for i := 0; i < numMethods; i++ { method := v.Type().Method(i) chunks := strings.Split(method.Name, "_") if l := len(chunks); l >= 3 { ts, _ := strconv.Atoi(chunks[l-2]) direction := chunks[l-1] if strings.ToLower(direction) == "up" { ups[ts] = method stamps = append(stamps, ts) } else { downs[ts] = method } } } sort.Ints(stamps) // Get config for set environment env := "development" if x := os.Getenv("HOOD_ENV"); x != "" { env = x } cfg := readConfig()[env] // Open hood hd, err := hood.Open(cfg["driver"], cfg["source"]) if err != nil { panic(err) } // Check migration table err = hd.CreateTableIfNotExists(&Migrations{}) if err != nil { panic(err) } var rows []Migrations err = hd.Find(&rows) if err != nil { panic(err) } info := Migrations{} if len(rows) > 0 { info = rows[0] } runCount := 0 for i, ts := range stamps { if up { if ts > info.Current { tx := hd.Begin() method := ups[ts] method.Func.Call([]reflect.Value{v, reflect.ValueOf(tx)}) info.Current = ts tx.Save(&info) err = tx.Commit() if err != nil { panic(err) } else { runCount++ fmt.Printf("applied %s\n", method.Name) } } } else { if info.Current == ts { tx := hd.Begin() method := downs[ts] method.Func.Call([]reflect.Value{v, reflect.ValueOf(tx)}) if i > 0 { info.Current = stamps[i-1] } else { info.Current = 0 } tx.Save(&info) err = tx.Commit() if err != nil { panic(err) } else { runCount++ fmt.Printf("rolled back %s\n", method.Name) break } } } } if up { fmt.Printf("applied %d migrations\n", runCount) } else { fmt.Printf("rolled back %d migrations\n", runCount) } fmt.Println("generating new schema...") dry := hood.Dry() for _, ts := range stamps { if ts <= info.Current { method := ups[ts] method.Func.Call([]reflect.Value{v, reflect.ValueOf(dry)}) } } wd, err := os.Getwd() if err != nil { panic(err) } schema := fmt.Sprintf( "package db\n\nimport (\n\t\"github.com/eaigner/hood\"\n)\n\n%s", dry.SchemaDefinition(), ) schemaPath := path.Join(wd, "db", "schema.go") err = ioutil.WriteFile(schemaPath, []byte(schema), 0666) if err != nil { panic(err) } fmt.Printf("wrote schema %s\n", schemaPath) fmt.Println("done.") }
func main() { // Determine direction up := true if len(os.Args) > 1 { if x := os.Args[1]; x == "down" { up = false } } if up { fmt.Println("applying migrations...") } else { fmt.Println("rolling back...") } // Get up/down migration methods v := reflect.ValueOf(&M{}) numMethods := v.NumMethod() stamps := make([]int, 0, numMethods) ups := make(map[int]reflect.Method) downs := make(map[int]reflect.Method) for i := 0; i < numMethods; i++ { method := v.Type().Method(i) chunks := strings.Split(method.Name, "_") if l := len(chunks); l >= 3 { ts, _ := strconv.Atoi(chunks[l-2]) direction := chunks[l-1] if strings.ToLower(direction) == "up" { ups[ts] = method stamps = append(stamps, ts) } else { downs[ts] = method } } } sort.Ints(stamps) // Get config for set environment env := "development" if x := os.Getenv("HOOD_ENV"); x != "" { env = x } cfg := readConfig()[env] // Open hood hd, err := hood.Open(cfg["driver"], cfg["source"]) if err != nil { panic(err) } // Check migration table err = hd.CreateTableIfNotExists(&Migrations{}) if err != nil { panic(err) } var rows []Migrations err = hd.Find(&rows) if err != nil { panic(err) } info := Migrations{} if len(rows) > 0 { info = rows[0] } runCount := 0 for i, ts := range stamps { if up { if ts > info.Current { tx := hd.Begin() method := ups[ts] method.Func.Call([]reflect.Value{v, reflect.ValueOf(tx)}) info.Current = ts tx.Save(&info) err = tx.Commit() if err != nil { panic(err) } else { runCount++ fmt.Printf("applied %s\n", method.Name) } } } else { if info.Current == ts { tx := hd.Begin() method := downs[ts] method.Func.Call([]reflect.Value{v, reflect.ValueOf(tx)}) if i > 0 { info.Current = stamps[i-1] } else { info.Current = 0 } tx.Save(&info) err = tx.Commit() if err != nil { panic(err) } else { runCount++ fmt.Printf("rolled back %s\n", method.Name) break } } } } if up { fmt.Printf("applied %d migrations\n", runCount) } else { fmt.Printf("rolled back %d migrations\n", runCount) } }