mirror of https://github.com/VinGarcia/ksql.git
184 lines
4.4 KiB
Go
184 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/vingarcia/ksql"
|
|
"github.com/vingarcia/ksql/adapters/ksqlite3"
|
|
"github.com/vingarcia/ksql/nullable"
|
|
)
|
|
|
|
type User struct {
|
|
ID int `ksql:"id"`
|
|
Name string `ksql:"name"`
|
|
Age int `ksql:"age"`
|
|
|
|
// The following attributes are making use of the KSQL Modifiers,
|
|
// you can find more about them on our Wiki:
|
|
//
|
|
// - https://github.com/VinGarcia/ksql/wiki/Modifiers
|
|
//
|
|
|
|
// The `json` modifier will save the address as JSON in the database
|
|
Address Address `ksql:"address,json"`
|
|
|
|
// The timeNowUTC modifier will set this field to `time.Now().UTC()` before saving it:
|
|
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
|
|
|
|
// The timeNowUTC/skipUpdates modifier will set this field to `time.Now().UTC()` only
|
|
// when first creating it and ignore it during updates.
|
|
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
|
|
}
|
|
|
|
type PartialUpdateUser struct {
|
|
ID int `ksql:"id"`
|
|
Name *string `ksql:"name"`
|
|
Age *int `ksql:"age"`
|
|
Address *Address `ksql:"address,json"`
|
|
}
|
|
|
|
type Address struct {
|
|
State string `json:"state"`
|
|
City string `json:"city"`
|
|
}
|
|
|
|
// UsersTable informs KSQL the name of the table and that it can
|
|
// use the default value for the primary key column name: "id"
|
|
var UsersTable = ksql.NewTable("users")
|
|
|
|
func main() {
|
|
ctx := context.Background()
|
|
|
|
// In this example we'll use sqlite3:
|
|
db, err := ksqlite3.New(ctx, "/tmp/hello.sqlite", ksql.Config{
|
|
MaxOpenConns: 1,
|
|
})
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
defer db.Close()
|
|
|
|
// In the definition below, please note that BLOB is
|
|
// the only type we can use in sqlite for storing JSON.
|
|
_, err = db.Exec(ctx, `CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY,
|
|
age INTEGER,
|
|
name TEXT,
|
|
address BLOB,
|
|
created_at DATETIME,
|
|
updated_at DATETIME
|
|
)`)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
var alison = User{
|
|
Name: "Alison",
|
|
Age: 22,
|
|
Address: Address{
|
|
State: "MG",
|
|
},
|
|
}
|
|
err = db.Insert(ctx, UsersTable, &alison)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
fmt.Println("Alison ID:", alison.ID)
|
|
|
|
// Inserting inline:
|
|
err = db.Insert(ctx, UsersTable, &User{
|
|
Name: "Cristina",
|
|
Age: 27,
|
|
Address: Address{
|
|
State: "SP",
|
|
},
|
|
})
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
// Deleting Alison:
|
|
err = db.Delete(ctx, UsersTable, alison.ID)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
// Retrieving Cristina, note that if you omit the SELECT part of the query
|
|
// KSQL will build it for you (efficiently) based on the fields from the struct:
|
|
var cris User
|
|
err = db.QueryOne(ctx, &cris, "FROM users WHERE name = ? ORDER BY id", "Cristina")
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
fmt.Printf("Cristina: %#v\n", cris)
|
|
|
|
// Updating all fields from Cristina:
|
|
cris.Name = "Cris"
|
|
err = db.Patch(ctx, UsersTable, cris)
|
|
|
|
// Changing the age of Cristina but not touching any other fields:
|
|
|
|
// Partial update technique 1:
|
|
err = db.Patch(ctx, UsersTable, struct {
|
|
ID int `ksql:"id"`
|
|
Age int `ksql:"age"`
|
|
}{ID: cris.ID, Age: 28})
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
// Partial update technique 2:
|
|
err = db.Patch(ctx, UsersTable, PartialUpdateUser{
|
|
ID: cris.ID,
|
|
Age: nullable.Int(28), // (just a pointer to an int, if null it won't be updated)
|
|
})
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
// Listing first 10 users from the database
|
|
// (each time you run this example a new Cristina is created)
|
|
//
|
|
// Note: Using this function it is recommended to set a LIMIT, since
|
|
// not doing so can load too many users on your computer's memory or
|
|
// cause an Out Of Memory Kill.
|
|
//
|
|
// If you need to query very big numbers of users we recommend using
|
|
// the `QueryChunks` function.
|
|
var users []User
|
|
err = db.Query(ctx, &users, "FROM users LIMIT 10")
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
fmt.Printf("Users: %#v\n", users)
|
|
|
|
// Making transactions:
|
|
err = db.Transaction(ctx, func(db ksql.Provider) error {
|
|
var cris2 User
|
|
err = db.QueryOne(ctx, &cris2, "FROM users WHERE id = ?", cris.ID)
|
|
if err != nil {
|
|
// This will cause an automatic rollback:
|
|
return err
|
|
}
|
|
|
|
err = db.Patch(ctx, UsersTable, PartialUpdateUser{
|
|
ID: cris2.ID,
|
|
Age: nullable.Int(29),
|
|
})
|
|
if err != nil {
|
|
// This will also cause an automatic rollback and then panic again
|
|
// so that we don't hide the panic inside the KSQL library
|
|
panic(err.Error())
|
|
}
|
|
|
|
// Commits the transaction
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
}
|