package storm_test import ( "fmt" "io/ioutil" "log" "os" "path/filepath" "strings" "time" "github.com/asdine/storm" ) func ExampleDB_Save() { dir, _ := ioutil.TempDir(os.TempDir(), "storm") defer os.RemoveAll(dir) type User struct { ID int `storm:"id"` Group string `storm:"index"` Email string `storm:"unique"` Name string Age int `storm:"index"` CreatedAt time.Time `storm:"index"` } // Open takes an optional list of options as the last argument. // AutoIncrement will auto-increment integer IDs without existing values. db, _ := storm.Open(filepath.Join(dir, "storm.db"), storm.AutoIncrement()) defer db.Close() user := User{ Group: "staff", Email: "john@provider.com", Name: "John", Age: 21, CreatedAt: time.Now(), } err := db.Save(&user) if err != nil { log.Fatal(err) } user2 := user user2.ID = 0 // Save will fail because of the unique constraint on Email err = db.Save(&user2) fmt.Println(err) // Output: // already exists } func ExampleDB_One() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var user User err := db.One("Email", "john@provider.com", &user) if err != nil { log.Fatal(err) } // One only works for indexed fields. err = db.One("Name", "John", &user) fmt.Println(err) // Output: // not found } func ExampleDB_Find() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.Find("Group", "staff", &users) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 3 } func ExampleDB_All() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.All(&users) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 3 } func ExampleDB_AllByIndex() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.AllByIndex("CreatedAt", &users) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 3 } func ExampleDB_Range() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.Range("Age", 21, 22, &users) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 2 } func ExampleLimit() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.All(&users, storm.Limit(2)) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 2 } func ExampleSkip() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var users []User err := db.All(&users, storm.Skip(1)) if err != nil { log.Fatal(err) } fmt.Println("Found", len(users)) // Output: // Found 2 } func ExampleDB_Remove() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() var user User err := db.One("ID", 1, &user) if err != nil { log.Fatal(err) } err = db.Remove(user) fmt.Println(err) // Output: // } func ExampleDB_Begin() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() // both start out with a balance of 10000 cents var account1, account2 Account tx, err := db.Begin(true) if err != nil { log.Fatal(err) } err = tx.One("ID", 1, &account1) if err != nil { log.Fatal(err) } err = tx.One("ID", 2, &account2) if err != nil { log.Fatal(err) } account1.Amount -= 1000 account2.Amount += 1000 err = tx.Save(account1) if err != nil { tx.Rollback() log.Fatal(err) } err = tx.Save(account2) if err != nil { tx.Rollback() log.Fatal(err) } tx.Commit() var account1Reloaded, account2Reloaded Account err = db.One("ID", 1, &account1Reloaded) if err != nil { log.Fatal(err) } err = db.One("ID", 2, &account2Reloaded) if err != nil { log.Fatal(err) } fmt.Println("Amount in account 1:", account1Reloaded.Amount) fmt.Println("Amount in account 2:", account2Reloaded.Amount) // Output: // Amount in account 1: 9000 // Amount in account 2: 11000 } func ExampleDB_From() { dir, db := prepareDB() defer os.RemoveAll(dir) defer db.Close() // Create some sub buckets to partition the data. privateNotes := db.From("notes", "private") workNotes := db.From("notes", "work") err := privateNotes.Save(&Note{ID: "private1", Text: "This is some private text."}) if err != nil { log.Fatal(err) } err = workNotes.Save(&Note{ID: "work1", Text: "Work related."}) if err != nil { log.Fatal(err) } var privateNote, workNote, personalNote Note err = privateNotes.One("ID", "work1", &workNote) // Not found: Wrong bucket. fmt.Println(err) err = workNotes.One("ID", "work1", &workNote) if err != nil { log.Fatal(err) } err = privateNotes.One("ID", "private1", &privateNote) if err != nil { log.Fatal(err) } fmt.Println(workNote.Text) fmt.Println(privateNote.Text) // These can be nested further if needed: personalNotes := privateNotes.From("personal") err = personalNotes.Save(&Note{ID: "personal1", Text: "This is some very personal text."}) if err != nil { log.Fatal(err) } err = personalNotes.One("ID", "personal1", &personalNote) if err != nil { log.Fatal(err) } fmt.Println(personalNote.Text) // Output: // not found // Work related. // This is some private text. // This is some very personal text. } type User struct { ID int `storm:"id"` Group string `storm:"index"` Email string `storm:"unique"` Name string Age int `storm:"index"` CreatedAt time.Time `storm:"index"` } type Account struct { ID int `storm:"id"` Amount int64 // amount in cents } type Note struct { ID string `storm:"id"` Text string } func prepareDB() (string, *storm.DB) { dir, _ := ioutil.TempDir(os.TempDir(), "storm") db, _ := storm.Open(filepath.Join(dir, "storm.db"), storm.AutoIncrement()) for i, name := range []string{"John", "Eric", "Dilbert"} { email := strings.ToLower(name + "@provider.com") user := User{ Group: "staff", Email: email, Name: name, Age: 21 + i, CreatedAt: time.Now(), } err := db.Save(&user) if err != nil { log.Fatal(err) } } for i := int64(0); i < 10; i++ { account := Account{Amount: 10000} err := db.Save(&account) if err != nil { log.Fatal(err) } } return dir, db }