Example #1
0
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)
	}
}
Example #2
0
/* 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
}
Example #3
0
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
}
Example #4
0
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
}
Example #5
0
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)
}
Example #6
0
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{})
}
Example #7
0
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.")
}
Example #8
0
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.")
}
Example #9
0
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)
	}
}