-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add example * feat: add more comment --------- Co-authored-by: Eyo Chen <[email protected]>
- Loading branch information
Showing
7 changed files
with
410 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
"github.com/eyo-chen/gofacto/typeconv" | ||
) | ||
|
||
// order has a foreign key field `CustomerID` to customer | ||
type order struct { | ||
ID int | ||
CustomerID int `gofacto:"struct:customer"` // set the correct tag | ||
Amount int | ||
} | ||
|
||
// Example_association demonstrates how to build associations value in an easy way. | ||
// First, we need to set the correct tag on the foreign key field to tell gofacto which struct to associate with. | ||
// Then, we can use `WithOne` or `WithMany` to create the association value and set the connection between the two structs. | ||
func Example_association() { | ||
// init a oreder factory | ||
f := gofacto.New(order{}). | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
// build one order with one customer | ||
customer1 := customer{} | ||
order1, err := f.Build(ctx). | ||
WithOne(&customer1). // must pass the struct pointer to WithOne or WithMany | ||
Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(order1) // {ID: 1, CustomerID: 1, Amount: {{non-zero value}}} | ||
fmt.Println(customer1) // {ID: 1, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
fmt.Println(order1.CustomerID == customer1.ID) // true | ||
|
||
// build two orders with two customers | ||
customer2 := customer{} | ||
customer3 := customer{} | ||
orders1, err := f.BuildList(ctx, 2). | ||
WithMany([]interface{}{&customer2, &customer3}). // must pass the struct pointer to WithOne or WithMany | ||
Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(orders1[0]) // {ID: 2, CustomerID: 2, Amount: {{non-zero value}}} | ||
fmt.Println(orders1[1]) // {ID: 3, CustomerID: 3, Amount: {{non-zero value}}} | ||
fmt.Println(customer2) // {ID: 2, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
fmt.Println(customer3) // {ID: 3, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
fmt.Println(orders1[0].CustomerID == customer2.ID) // true | ||
fmt.Println(orders1[1].CustomerID == customer3.ID) // true | ||
|
||
// build two orders with one customer | ||
customer4 := customer{} | ||
orders2, err := f.BuildList(ctx, 2). | ||
WithOne(&customer4). // must pass the struct pointer to WithOne or WithMany | ||
Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(orders2[0]) // {ID: 4, CustomerID: 4, Amount: {{non-zero value}}} | ||
fmt.Println(orders2[1]) // {ID: 5, CustomerID: 4, Amount: {{non-zero value}}} | ||
fmt.Println(customer4) // {ID: 4, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
fmt.Println(orders2[0].CustomerID == customer4.ID) // true | ||
fmt.Println(orders2[1].CustomerID == customer4.ID) // true | ||
} | ||
|
||
// InsertOrders demonstrates how to use the functionality of `typeconv` package to simplify the code. | ||
// In some cases, we might want to wrap the insert logic into a function. | ||
// In this case, we define the `InsertOrders` function to insert `n` orders with `n` customers. | ||
func InsertOrders(ctx context.Context, f *gofacto.Factory[order], n int) ([]order, []customer, error) { | ||
// use `ToAnysWithOW` to generate `n` customers with any type | ||
// The first parameter is the number of customers to generate | ||
// The second parameter is the value to override the default value(we pass nil because we don't want to override the default value) | ||
customersAny := typeconv.ToAnysWithOW[customer](n, nil) | ||
|
||
orders, err := f.BuildList(ctx, n). | ||
WithMany(customersAny). | ||
Insert() | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
// convert the `[]any` to `[]customer` using `ToT` | ||
customers := typeconv.ToT[customer](customersAny) | ||
|
||
return orders, customers, nil | ||
} | ||
|
||
// Without the `typeconv` package, we would need to manually convert the `[]any` to `[]customer` using `ToT` | ||
func InsertOrdersWithoutTypeconv(ctx context.Context, f *gofacto.Factory[order], n int) ([]order, []customer, error) { | ||
// manually create `n` customers with any type | ||
customersAny := make([]interface{}, n) | ||
for i := 0; i < n; i++ { | ||
customersAny[i] = &customer{} | ||
} | ||
|
||
orders, err := f.BuildList(ctx, n). | ||
WithMany(customersAny). | ||
Insert() | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
// manually convert the `[]any` to `[]customer` | ||
customers := make([]customer, n) | ||
for i := 0; i < n; i++ { | ||
customers[i] = *customersAny[i].(*customer) | ||
} | ||
|
||
return orders, customers, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
) | ||
|
||
var ( | ||
ctx = context.Background() | ||
) | ||
|
||
// Gender is a custom defined type | ||
type gender string | ||
|
||
const ( | ||
genderMale gender = "male" | ||
genderFemale gender = "female" | ||
) | ||
|
||
type customer struct { | ||
ID int | ||
Gender gender | ||
Name string | ||
Age int | ||
} | ||
|
||
// Example_basic demonstrates the most basic usage of gofacto | ||
// when we didn't provide any configuration(except db connection), gofacto will generate non-zero value for all fields | ||
func Example_basic() { | ||
f := gofacto.New(customer{}). | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
// build and insert one data | ||
customer, err := f.Build(ctx).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer) // {ID: 1, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
// Note that because Gender is a custom defined type, gofacto will ignore it, and leave it as zero value. | ||
|
||
// build and insert multiple data | ||
customers, err := f.BuildList(ctx, 2).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers[0]) // {ID: 2, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
fmt.Println(customers[1]) // {ID: 3, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
) | ||
|
||
// Example_blueprint demonstrates how to use blueprint to generate data. | ||
// When blueprint is provided, gofacto will first use the blueprint to generate data, | ||
// then it will generate non-zero value for the rest of the fields which are not specified in the blueprint | ||
func Example_blueprint() { | ||
f := gofacto.New(customer{}). | ||
WithBlueprint(blueprint). // set the blueprint function | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
customer, err := f.Build(ctx).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer) // {ID: 1, Gender: "male", Name: "Bob", Age: 10} | ||
|
||
customers, err := f.BuildList(ctx, 2).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers[0]) // {ID: 2, Gender: "male", Name: "Bob", Age: 20} | ||
fmt.Println(customers[1]) // {ID: 3, Gender: "male", Name: "Bob", Age: 30} | ||
} | ||
|
||
// Define a blueprint function with the following signature: | ||
// type blueprintFunc[T any] func(i int) T | ||
func blueprint(i int) customer { | ||
return customer{ | ||
Name: "Bob", | ||
Gender: genderMale, | ||
Age: i * 10, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
) | ||
|
||
// Example_overwrite demonstrates how to overwrite specific fields | ||
func Example_overwrite() { | ||
f := gofacto.New(customer{}). | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
// build one data, and overwrite the Name field | ||
customer1, err := f.Build(ctx).Overwrite(customer{Name: "Alice"}).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer1) // {ID: 1, Gender: "", Name: "Alice", Age: {{non-zero value}}} | ||
// Note that because Gender is a custom defined type, gofacto will ignore it, and leave it as zero value. | ||
|
||
// build two data, and overwrite the Gender and Name fields respectively | ||
customers, err := f.BuildList(ctx, 2). | ||
Overwrites(customer{Gender: genderMale, Name: "Alice"}, customer{Gender: genderFemale, Name: "Mag"}). | ||
Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers[0]) // {ID: 2, Gender: "male", Name: "Alice", Age: {{non-zero value}}} | ||
fmt.Println(customers[1]) // {ID: 3, Gender: "female", Name: "Mag", Age: {{non-zero value}}} | ||
|
||
// build two data, and overwrite all the data list with the same value | ||
customers1, err := f.BuildList(ctx, 2). | ||
Overwrite(customer{Age: 10}). | ||
Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers1[0]) // {ID: 4, Gender: "", Name: {{non-zero value}}, Age: 10} | ||
fmt.Println(customers1[1]) // {ID: 5, Gender: "", Name: {{non-zero value}}, Age: 10} | ||
|
||
// Note that we can't overwrite with zero value | ||
// use `SetZero` or `SetTrait` to set zero value | ||
customer2, err := f.Build(ctx).Overwrite(customer{Age: 0}).Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer2) // {ID: 4, Gender: "", Name: {{non-zero value}}, Age: {{non-zero value}}} | ||
// Age is still a non-zero value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
) | ||
|
||
// Example_settrait demonstrates how to use trait function to customize the data. | ||
// We first define a trait function, then use `WithTrait` to register the trait function with a key, | ||
// finally, use `SetTrait` to invoke the trait function. | ||
func Example_settrait() { | ||
f := gofacto.New(customer{}). | ||
WithTrait("toMale", updateToMale). // set the trait function with key | ||
WithTrait("toFemale", updateToFemale). // set the trait function with key | ||
WithTrait("ageZero", updateAgeToZero). // set the trait function with key | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
// build one data, and invoke the trait function with key "toMale" | ||
customer1, err := f.Build(ctx).SetTrait("toMale").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer1) // {ID: 1, Gender: "male", Name: {{non-zero value}, Age: {{non-zero value}}} | ||
|
||
// build two data, and invoke the trait function with key "toMale" and "toFemale" respectively | ||
customers, err := f.BuildList(ctx, 2).SetTraits("toMale", "toFemale").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers[0]) // {ID: 2, Gender: "male", Name: {{non-zero value}, Age: {{non-zero value}}} | ||
fmt.Println(customers[1]) // {ID: 3, Gender: "female", Name: {{non-zero value}, Age: {{non-zero value}}} | ||
|
||
// build two data, and invoke the trait function with key "toMale" on all the data list | ||
customers1, err := f.BuildList(ctx, 2).SetTrait("toMale").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers1[0]) // {ID: 4, Gender: "male", Name: {{non-zero value}, Age: {{non-zero value}}} | ||
fmt.Println(customers1[1]) // {ID: 5, Gender: "male", Name: {{non-zero value}, Age: {{non-zero value}}} | ||
|
||
// it's also possible to set zero value | ||
customer2, err := f.Build(ctx).SetTrait("ageZero").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer2) // {ID: 6, Gender: "", Name: {{non-zero value}}, Age: 0} | ||
} | ||
|
||
// define a trait function to update the value | ||
func updateToMale(c *customer) { | ||
c.Gender = genderMale | ||
// more update logic can be added here | ||
} | ||
|
||
// define a trait function to update the value | ||
func updateToFemale(c *customer) { | ||
c.Gender = genderFemale | ||
// more update logic can be added here | ||
} | ||
|
||
// define a trait function to update the value | ||
func updateAgeToZero(c *customer) { | ||
c.Age = 0 | ||
// more update logic can be added here | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Package example_test provides examples demonstrating the usage of the gofacto library. | ||
// | ||
// These examples are for demonstration purposes and are not meant to be run directly. | ||
// They serve as reference implementations to illustrate various features and use cases of gofacto. | ||
// In a real-world scenario, you would need to provide actual database connections and adjust the code accordingly. | ||
package example_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/eyo-chen/gofacto" | ||
"github.com/eyo-chen/gofacto/db/mysqlf" | ||
) | ||
|
||
// Example_setzero demonstrates how to explicitly set zero value on the specified fields. | ||
func Example_setzero() { | ||
f := gofacto.New(customer{}). | ||
WithDB(mysqlf.NewConfig(nil)) // you should pass db connection | ||
|
||
// build one data, and set zero value on the specified fields | ||
customer, err := f.Build(ctx).SetZero("Age", "Name").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customer) // {ID: 1, Gender: "", Name: "", Age: 0} | ||
// Note that because Gender is a custom defined type, gofacto will ignore it, and leave it as zero value.. | ||
|
||
// build two data, and set zero value on the specified fields | ||
// the first parameter is the index of the list | ||
// the second parameter is the field name that you want to set zero value on | ||
customers, err := f.BuildList(ctx, 2).SetZero(0, "Age").SetZero(1, "Age", "Name").Insert() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Println(customers) // [{ID: 2, Gender: "", Name: {{non-zero value}}, Age: 0}, {ID: 3, Gender: "", Name: "", Age: 0}] | ||
} |
Oops, something went wrong.