Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion generator/templates/client.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type sqliteDialect struct{}
func (sqliteDialect) Quote(ident string) string { return `"` + ident + `"` }
func (sqliteDialect) BindVar(idx int) string { return "?" }
func (sqliteDialect) SupportsReturning() bool { return true }
func (sqliteDialect) SupportsBulkInsert() bool { return false }
func (sqliteDialect) SupportsBulkInsert() bool { return true }
func (sqliteDialect) FormatLimitOffset(take *int, skip *int) string {
if take != nil {
if skip != nil {
Expand Down
43 changes: 36 additions & 7 deletions generator/templates/model_create.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,32 @@ func (s *{{ .Model.Name }}Select) hasAnyRelation() bool {
{{- end }}
}

func (d *{{ .Model.Name }}Delegate) Create(assignments ...FieldAssignment) *CreateBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit] {
return &CreateBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit]{
client: d.client,
assignments: assignments,
execFunc: d.client.execute{{ .Model.Name }}Create,
type {{ .Model.Name }}CreateBuilder struct {
*CreateBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit]
}

{{ range $field := .Model.ScalarFields }}
{{- $fieldType := trimPrefix $field.GoType "*" }}
{{- if $field.EnumRef }}
{{- if $field.IsArray }}
{{- $fieldType = printf "[]%sType" $field.EnumRef.Name }}
{{- else }}
{{- $fieldType = printf "%sType" $field.EnumRef.Name }}
{{- end }}
{{- end }}
func (b *{{ $.Model.Name }}CreateBuilder) Set{{ capitalize $field.Name }}(v {{ $fieldType }}) *{{ $.Model.Name }}CreateBuilder {
b.assignments = append(b.assignments, FieldAssignment{Col: "{{ $field.EffectiveColName }}", Val: v})
return b
}
{{- end }}

func (d *{{ .Model.Name }}Delegate) Create(assignments ...FieldAssignment) *{{ .Model.Name }}CreateBuilder {
return &{{ .Model.Name }}CreateBuilder{
CreateBuilder: &CreateBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit]{
client: d.client,
assignments: assignments,
execFunc: d.client.execute{{ .Model.Name }}Create,
},
}
}

Expand Down Expand Up @@ -279,15 +300,23 @@ func (q *Queries) execute{{ .Model.Name }}Create(ctx context.Context, assignment
return res, nil
}

func (d *{{ .Model.Name }}Delegate) CreateMany(records ...RecordInput) *CreateManyBuilder[{{ .Model.Name }}] {
func (d *{{ .Model.Name }}Delegate) CreateMany(builders ...*{{ .Model.Name }}CreateBuilder) *CreateManyBuilder[{{ .Model.Name }}] {
records := make([]RecordInput, len(builders))
for i, b := range builders {
records[i] = RecordInput{Assignments: b.assignments}
}
return &CreateManyBuilder[{{ .Model.Name }}]{
client: d.client,
records: records,
execFunc: d.client.execute{{ .Model.Name }}CreateMany,
}
}

func (d *{{ .Model.Name }}Delegate) CreateManyAndReturn(records ...RecordInput) *CreateManyAndReturnBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit] {
func (d *{{ .Model.Name }}Delegate) CreateManyAndReturn(builders ...*{{ .Model.Name }}CreateBuilder) *CreateManyAndReturnBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit] {
records := make([]RecordInput, len(builders))
for i, b := range builders {
records[i] = RecordInput{Assignments: b.assignments}
}
return &CreateManyAndReturnBuilder[{{ .Model.Name }}, {{ .Model.Name }}Select, {{ .Model.Name }}Omit]{
client: d.client,
records: records,
Expand Down
1 change: 1 addition & 0 deletions generator/templates/model_predicate.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (p UniquePredicate) Validate() error {
type Select = {{ .ParentPackageName }}.{{ .Model.Name }}Select
type Omit = {{ .ParentPackageName }}.{{ .Model.Name }}Omit
type QueryBuilder = {{ .ParentPackageName }}.{{ .Model.Name }}QueryBuilder
type CreateBuilder = {{ .ParentPackageName }}.{{ .Model.Name }}CreateBuilder

func Query() *QueryBuilder {
return &QueryBuilder{}
Expand Down
42 changes: 16 additions & 26 deletions integration/create_many_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"integration/valk"
"integration/valk/post"
"integration/valk/user"
"strings"
"testing"
Expand All @@ -26,8 +25,8 @@ func TestCreateMany_Hooks(t *testing.T) {
})

count, err := client.User.CreateMany(
user.Record(user.Email.Set("hooked@example.com"), user.PhoneNum.Set("+100000000")),
user.Record(user.Email.Set("normal@example.com"), user.PhoneNum.Set("+200000000")),
client.User.Create().SetEmail("hooked@example.com").SetPhoneNum("+100000000"),
client.User.Create().SetEmail("normal@example.com").SetPhoneNum("+200000000"),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -58,8 +57,8 @@ func TestCreateMany_Hooks(t *testing.T) {
})

users, err := client.User.CreateManyAndReturn(
user.Record(user.Email.Set("hooked@example.com"), user.PhoneNum.Set("+100000001")),
user.Record(user.Email.Set("normal@example.com"), user.PhoneNum.Set("+200000001")),
client.User.Create().SetEmail("hooked@example.com").SetPhoneNum("+100000001"),
client.User.Create().SetEmail("normal@example.com").SetPhoneNum("+200000001"),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -88,8 +87,8 @@ func TestCreateMany_Hooks(t *testing.T) {
})

_, err := client.User.CreateMany(
user.Record(user.Email.Set("good@example.com"), user.PhoneNum.Set("+300000000")),
user.Record(user.Email.Set("reject@example.com"), user.PhoneNum.Set("+300000001")),
client.User.Create().SetEmail("good@example.com").SetPhoneNum("+300000000"),
client.User.Create().SetEmail("reject@example.com").SetPhoneNum("+300000001"),
).Exec(ctx)

if err == nil {
Expand Down Expand Up @@ -118,7 +117,7 @@ func TestCreateMany_Hooks(t *testing.T) {
})

users, err := client.User.CreateManyAndReturn(
user.Record(user.Email.Set("after@example.com"), user.PhoneNum.Set("+500000000")),
client.User.Create().SetEmail("after@example.com").SetPhoneNum("+500000000"),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -148,7 +147,7 @@ func TestCreateMany_Hooks(t *testing.T) {
prevCount := count

_, err := client.User.CreateManyAndReturn(
user.Record(user.Email.Set("aftershoot@example.com"), user.PhoneNum.Set("+600000000")),
client.User.Create().SetEmail("aftershoot@example.com").SetPhoneNum("+600000000"),
).Exec(ctx)

if err == nil {
Expand Down Expand Up @@ -177,14 +176,8 @@ func TestCreateMany_Hooks(t *testing.T) {
})

count, err := client.User.CreateMany(
user.Record(
user.Email.Set("bulk1@example.com"),
user.PhoneNum.Set("+700000001"),
),
user.Record(
user.Email.Set("bulk2@example.com"),
user.PhoneNum.Set("+700000002"),
),
client.User.Create().SetEmail("bulk1@example.com").SetPhoneNum("+700000001"),
client.User.Create().SetEmail("bulk2@example.com").SetPhoneNum("+700000002"),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -216,10 +209,7 @@ func TestCreateMany_Hooks(t *testing.T) {
})

_, err := client.User.CreateMany(
user.Record(
user.Email.Set("ghost@example.com"),
user.PhoneNum.Set("+800000000"),
),
client.User.Create().SetEmail("ghost@example.com").SetPhoneNum("+800000000"),
).Exec(ctx)

if err == nil {
Expand Down Expand Up @@ -247,9 +237,9 @@ func TestCreateMany(t *testing.T) {

t.Run("CreateMany returns correct count", func(t *testing.T) {
count, err := client.User.CreateMany(
user.Record(user.Email.Set("bulk1@example.com"), user.PhoneNum.Set("+111")),
user.Record(user.Email.Set("bulk2@example.com"), user.PhoneNum.Set("+222")),
user.Record(user.Email.Set("bulk3@example.com"), user.PhoneNum.Set("+333")),
client.User.Create().SetEmail("bulk1@example.com").SetPhoneNum("+111"),
client.User.Create().SetEmail("bulk2@example.com").SetPhoneNum("+222"),
client.User.Create().SetEmail("bulk3@example.com").SetPhoneNum("+333"),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -280,8 +270,8 @@ func TestCreateMany(t *testing.T) {
}

posts, err := client.Post.CreateManyAndReturn(
post.Record(post.Title.Set("Post One"), post.AuthorId.Set(author.Id)),
post.Record(post.Title.Set("Post Two"), post.AuthorId.Set(author.Id)),
client.Post.Create().SetTitle("Post One").SetAuthorId(author.Id),
client.Post.Create().SetTitle("Post Two").SetAuthorId(author.Id),
).Select(valk.PostSelect{
Id: true,
Title: true,
Expand Down
111 changes: 68 additions & 43 deletions integration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,60 @@ type SeedData struct {
Meta2 json.RawMessage
}

func dbReset(db *valk.DB) error {
tx, err := db.Raw().Begin()
if err != nil {
return err
}
defer tx.Rollback()

if _, err := tx.Exec(`DROP SCHEMA public CASCADE`); err != nil {
return err
}

if _, err := tx.Exec(`CREATE SCHEMA public`); err != nil {
return err
}

return tx.Commit()
}

func main() {

err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
// db := openConn()
db := openPGConn()
defer dbReset(db)
defer db.Close()
var test user.CreateBuilder
_ = test
rawDB := db.Raw()
rawDB.SetMaxOpenConns(10)
ctx := context.Background()

runMigrations(db, ctx)

var builders []*user.CreateBuilder
for i := range 20 {
builder := db.User.Create().
SetEmail(fmt.Sprintf("user%d@gmail.com", i)).
SetPassword(fmt.Sprintf("pass%d", i)).
SetPhoneNum(fmt.Sprintf("+1111%d", i))

builders = append(builders, builder)
}
count, err := db.User.CreateMany(builders...).Exec(ctx)
if err != nil {
log.Fatalf("failed to seed users: %v", err)
}

printJSON(count)

}

func seed(db *valk.DB, ctx context.Context) *SeedData {

db.User.BeforeCreate(func(ctx context.Context, user *valk.UserCreate) error {
Expand All @@ -51,14 +105,14 @@ func seed(db *valk.DB, ctx context.Context) *SeedData {
return nil
})

var usersToCreate []valk.RecordInput
var usersToCreate []*user.CreateBuilder

for i := range 20 {
usersToCreate = append(usersToCreate, user.Record(
user.Email.Set(fmt.Sprintf("email-%d", i)),
user.PhoneNum.Set(fmt.Sprintf("555-%d", i)),
user.Password.Set(fmt.Sprintf("password-%d", i)),
))
usersToCreate = append(usersToCreate, db.User.Create().
SetEmail(fmt.Sprintf("email-%d", i)).
SetPhoneNum(fmt.Sprintf("555-%d", i)).
SetPassword(fmt.Sprintf("password-%d", i)),
)
}

_, err := db.User.FindUnique(
Expand Down Expand Up @@ -91,16 +145,14 @@ func seed(db *valk.DB, ctx context.Context) *SeedData {
fmt.Printf("CreateManyAndReturn: %d users returned with auto-generated IDs\n", len(users))

if _, err := db.User.CreateMany(
user.Record(
user.Email.Set("test"),
user.PhoneNum.Set("555-test"),
user.Password.Set("passwd"),
),
user.Record(
user.Email.Set("again"),
user.PhoneNum.Set("555-again"),
user.Password.Set("123456"),
),
db.User.Create().
SetEmail("test").
SetPhoneNum("555-test").
SetPassword("passwd"),
db.User.Create().
SetEmail("again").
SetPhoneNum("555-again").
SetPassword("123456"),
).Exec(ctx); err != nil {
log.Fatalf("failed to CreateMany: %v", err)
}
Expand Down Expand Up @@ -218,33 +270,6 @@ func seed(db *valk.DB, ctx context.Context) *SeedData {
}
}

func main() {

err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
// db := openConn()
db := openPGConn()
defer db.Close()

rawDB := db.Raw()
rawDB.SetMaxOpenConns(10)
ctx := context.Background()

runMigrations(db, ctx)
res, err := db.User.FindUnique(
user.EmailPhoneUnique("x@y.com", "+1111"),
user.RoleOptional.EQ(valk.UserRole.Admin),
).Exec(ctx)
if err != nil {
log.Fatalf("failed to find user: %v", err)
}
fmt.Println(res)
printJSON(res)

}

func openConn() *valk.DB {
db, err := valk.Open("sqlite", "file::memory:?_pragma=foreign_keys(1)&_time_format=sqlite")

Expand Down
34 changes: 10 additions & 24 deletions integration/postgres_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -838,15 +838,13 @@ func TestNativeDefaults_CreateMany(t *testing.T) {

base := baseAllFields(t)

rec1 := allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("many-1"),
allFieldsSoFar.IntReq.Set(10),
)...)
rec1 := db.AllFieldsSoFar.Create(base...).
SetStringReq("many-1").
SetIntReq(10)

rec2 := allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("many-2"),
allFieldsSoFar.IntReq.Set(20),
)...)
rec2 := db.AllFieldsSoFar.Create(base...).
SetStringReq("many-2").
SetIntReq(20)

count, err := db.AllFieldsSoFar.CreateMany(rec1, rec2).Exec(ctx)
if err != nil {
Expand All @@ -865,14 +863,8 @@ func TestNativeDefaults_CreateManyAndReturn(t *testing.T) {
base := baseAllFields(t)

recs, err := db.AllFieldsSoFar.CreateManyAndReturn(
allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("ret-1"),
allFieldsSoFar.IntReq.Set(100),
)...),
allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("ret-2"),
allFieldsSoFar.IntReq.Set(200),
)...),
db.AllFieldsSoFar.Create(base...).SetStringReq("ret-1").SetIntReq(100),
db.AllFieldsSoFar.Create(base...).SetStringReq("ret-2").SetIntReq(200),
).Exec(ctx)

if err != nil {
Expand Down Expand Up @@ -955,14 +947,8 @@ func TestNativeDefaults_Hooks(t *testing.T) {
})

base := baseAllFields(t)
r1 := allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("hook-cm-1"),
allFieldsSoFar.IntReq.Set(1),
)...)
r2 := allFieldsSoFar.Record(append(base,
allFieldsSoFar.StringReq.Set("hook-cm-2"),
allFieldsSoFar.IntReq.Set(2),
)...)
r1 := db.AllFieldsSoFar.Create(base...).SetStringReq("hook-cm-1").SetIntReq(1)
r2 := db.AllFieldsSoFar.Create(base...).SetStringReq("hook-cm-2").SetIntReq(2)

_, err := db.AllFieldsSoFar.CreateMany(r1, r2).Exec(ctx)
if err != nil {
Expand Down
Loading
Loading