an ORM-free SQL experience

add tests for insert stmt

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li 0d2a557e 46362302

verified
Changed files
+71 -14
+19 -14
query.go
··· 325 325 type insert struct { 326 326 into string 327 327 or InsertOr 328 - values map[string]any 328 + values []struct { 329 + col string 330 + val any 331 + } 329 332 } 330 333 331 334 type InsertOr int ··· 357 360 } 358 361 359 362 func Insert() insert { 360 - return insert{ 361 - values: make(map[string]any), 362 - } 363 + return insert{} 363 364 } 364 365 365 366 type InsertOpt func(s *insert) ··· 375 376 } 376 377 377 378 func (s insert) Value(column string, arg any) insert { 378 - s.values[column] = arg 379 + s.values = append(s.values, struct { 380 + col string 381 + val any 382 + }{ 383 + column, arg, 384 + }) 379 385 return s 380 386 } 381 387 ··· 388 394 if s.or != None { 389 395 sql.WriteString("OR ") 390 396 sql.WriteString(s.or.String()) 397 + sql.WriteString(" ") 391 398 } 392 399 393 400 if s.into == "" { 394 401 return "", nil, fmt.Errorf("INTO clause is required") 395 402 } 396 - sql.WriteString(" INTO ") 403 + sql.WriteString("INTO ") 397 404 sql.WriteString(s.into) 398 405 399 406 if len(s.values) == 0 { ··· 402 409 403 410 sql.WriteString(" (") 404 411 405 - first := true 406 - for col, val := range s.values { 407 - if !first { 408 - sql.WriteString(",") 409 - first = !first 412 + for i, v := range s.values { 413 + if i != 0 { 414 + sql.WriteString(", ") 410 415 } 411 416 412 - sql.WriteString(col) 413 - args = append(args, val) 417 + sql.WriteString(v.col) 418 + args = append(args, v.val) 414 419 } 415 420 416 421 sql.WriteString(") VALUES (") 417 - sql.WriteString(strings.TrimSuffix(strings.Repeat("?,", len(s.values)), ",")) 422 + sql.WriteString(strings.TrimSuffix(strings.Repeat("?, ", len(s.values)), ", ")) 418 423 sql.WriteString(")") 419 424 420 425 return sql.String(), args, nil
+52
query_test.go
··· 742 742 }) 743 743 } 744 744 } 745 + 746 + func TestInsertBuild_Success(t *testing.T) { 747 + tests := []struct { 748 + name string 749 + stmt insert 750 + expectedSql string 751 + expectedArgs []any 752 + }{ 753 + { 754 + name: "Simple insert", 755 + stmt: Insert().Into("users").Value("name", "John"), 756 + expectedSql: "INSERT INTO users (name) VALUES (?)", 757 + expectedArgs: []any{"John"}, 758 + }, 759 + { 760 + name: "Replace clause", 761 + stmt: Insert().Or(Replace).Into("users").Value("name", "John"), 762 + expectedSql: "INSERT OR REPLACE INTO users (name) VALUES (?)", 763 + expectedArgs: []any{"John"}, 764 + }, 765 + { 766 + name: "More values", 767 + stmt: Insert().Into("users").Value("name", "John").Value("age", 35), 768 + expectedSql: "INSERT INTO users (name, age) VALUES (?, ?)", 769 + expectedArgs: []any{"John", 35}, 770 + }, 771 + } 772 + 773 + for _, test := range tests { 774 + t.Run(test.name, func(t *testing.T) { 775 + sql, args, err := test.stmt.Build() 776 + 777 + if err != nil { 778 + t.Errorf("Expected no error, got %v", err) 779 + } 780 + 781 + if sql != test.expectedSql { 782 + t.Errorf("Expected '%s', got '%s'", test.expectedSql, sql) 783 + } 784 + 785 + if len(args) != len(test.expectedArgs) { 786 + t.Errorf("Expected '%d' args, got '%d' args", len(test.expectedArgs), len(args)) 787 + } 788 + 789 + for i := range len(args) { 790 + if args[i] != test.expectedArgs[i] { 791 + t.Errorf("Expected '%v', got '%v' at index %d", test.expectedArgs[i], args[i], i) 792 + } 793 + } 794 + }) 795 + } 796 + }