package testing import ( "context" "testing" "time" ) type User struct { ID int64 `db:"id"` Name string `db:"name"` Email string `db:"email"` Age int `db:"age"` Balance float64 `db:"balance"` Active bool `db:"active"` CreatedAt time.Time `db:"created_at"` } type Profile struct { UserID int `db:"user_id"` Bio string `db:"bio"` Avatar string `db:"avatar"` } type NestedUser struct { ID int64 `db:"id"` Name string `db:"name"` Profile `db:"---"` } func TestStarRows_Orm_Single(t *testing.T) { db := setupTestDB(t) defer db.Close() rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var user User err = rows.Orm(&user) if err != nil { t.Fatalf("Orm failed: %v", err) } if user.Name != "Alice" { t.Errorf("Expected name 'Alice', got '%s'", user.Name) } if user.Email != "alice@example.com" { t.Errorf("Expected email 'alice@example.com', got '%s'", user.Email) } if user.Age != 25 { t.Errorf("Expected age 25, got %d", user.Age) } if user.Balance != 100.50 { t.Errorf("Expected balance 100.50, got %f", user.Balance) } if !user.Active { t.Errorf("Expected user to be active") } } func TestStarRows_Orm_Multiple(t *testing.T) { db := setupTestDB(t) defer db.Close() rows, err := db.Query("SELECT * FROM users ORDER BY name") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var users []User err = rows.Orm(&users) if err != nil { t.Fatalf("Orm failed: %v", err) } if len(users) != 3 { t.Fatalf("Expected 3 users, got %d", len(users)) } expectedNames := []string{"Alice", "Bob", "Charlie"} for i, user := range users { if user.Name != expectedNames[i] { t.Errorf("Expected name '%s', got '%s'", expectedNames[i], user.Name) } } } func TestStarRows_Orm_Empty(t *testing.T) { db := setupTestDB(t) defer db.Close() rows, err := db.Query("SELECT * FROM users WHERE name = ?", "NonExistent") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var users []User err = rows.Orm(&users) if err != nil { t.Fatalf("Orm failed: %v", err) } if len(users) != 0 { t.Errorf("Expected 0 users, got %d", len(users)) } } func TestStarRows_Orm_NotPointer(t *testing.T) { db := setupTestDB(t) defer db.Close() rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var user User err = rows.Orm(user) // Not a pointer if err == nil { t.Errorf("Expected error when passing non-pointer, got nil") } } func TestStarDB_Insert(t *testing.T) { db := setupTestDB(t) defer db.Close() user := User{ Name: "David", Email: "david@example.com", Age: 40, Balance: 400.00, Active: true, CreatedAt: time.Now(), } result, err := db.Insert(&user, "users", "id") if err != nil { t.Fatalf("Insert failed: %v", err) } lastID, err := result.LastInsertId() if err != nil { t.Fatalf("LastInsertId failed: %v", err) } if lastID <= 0 { t.Errorf("Expected positive last insert ID, got %d", lastID) } // Verify insertion rows, err := db.Query("SELECT * FROM users WHERE name = ?", "David") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var insertedUser User err = rows.Orm(&insertedUser) if err != nil { t.Fatalf("Orm failed: %v", err) } if insertedUser.Name != "David" { t.Errorf("Expected name 'David', got '%s'", insertedUser.Name) } if insertedUser.Email != "david@example.com" { t.Errorf("Expected email 'david@example.com', got '%s'", insertedUser.Email) } if insertedUser.Age != 40 { t.Errorf("Expected age 40, got %d", insertedUser.Age) } } func TestStarDB_InsertContext(t *testing.T) { db := setupTestDB(t) defer db.Close() ctx := context.Background() user := User{ Name: "Eve", Email: "eve@example.com", Age: 28, Balance: 250.00, Active: true, CreatedAt: time.Now(), } result, err := db.InsertContext(ctx, &user, "users", "id") if err != nil { t.Fatalf("InsertContext failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } } func TestStarDB_Update(t *testing.T) { db := setupTestDB(t) defer db.Close() // First, get the user rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Alice") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var user User err = rows.Orm(&user) if err != nil { t.Fatalf("Orm failed: %v", err) } // Update the user user.Age = 26 user.Balance = 150.75 result, err := db.Update(&user, "users", "id") if err != nil { t.Fatalf("Update failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } // Verify the update rows2, err := db.Query("SELECT * FROM users WHERE id = ?", user.ID) if err != nil { t.Fatalf("Query failed: %v", err) } defer rows2.Close() var updatedUser User err = rows2.Orm(&updatedUser) if err != nil { t.Fatalf("Orm failed: %v", err) } if updatedUser.Age != 26 { t.Errorf("Expected age 26, got %d", updatedUser.Age) } if updatedUser.Balance != 150.75 { t.Errorf("Expected balance 150.75, got %f", updatedUser.Balance) } } func TestStarDB_UpdateContext(t *testing.T) { db := setupTestDB(t) defer db.Close() ctx := context.Background() // Get user rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Bob") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() var user User err = rows.Orm(&user) if err != nil { t.Fatalf("Orm failed: %v", err) } // Update user.Active = false result, err := db.UpdateContext(ctx, &user, "users", "id") if err != nil { t.Fatalf("UpdateContext failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } } func TestStarDB_QueryX(t *testing.T) { db := setupTestDB(t) defer db.Close() user := User{ Name: "Alice", } rows, err := db.QueryX(&user, "SELECT * FROM users WHERE name = ?", ":name") if err != nil { t.Fatalf("QueryX failed: %v", err) } defer rows.Close() if rows.Length() != 1 { t.Errorf("Expected 1 row, got %d", rows.Length()) } var result User err = rows.Orm(&result) if err != nil { t.Fatalf("Orm failed: %v", err) } if result.Name != "Alice" { t.Errorf("Expected name 'Alice', got '%s'", result.Name) } } func TestStarDB_QueryXContext(t *testing.T) { db := setupTestDB(t) defer db.Close() ctx := context.Background() user := User{ Age: 30, } rows, err := db.QueryXContext(ctx, &user, "SELECT * FROM users WHERE age = ?", ":age") if err != nil { t.Fatalf("QueryXContext failed: %v", err) } defer rows.Close() if rows.Length() != 1 { t.Errorf("Expected 1 row, got %d", rows.Length()) } } func TestStarDB_QueryXS(t *testing.T) { db := setupTestDB(t) defer db.Close() users := []User{ {Name: "Alice"}, {Name: "Bob"}, } results, err := db.QueryXS(&users, "SELECT * FROM users WHERE name = ?", ":name") if err != nil { t.Fatalf("QueryXS failed: %v", err) } if len(results) != 2 { t.Errorf("Expected 2 results, got %d", len(results)) } for i, rows := range results { if rows.Length() != 1 { t.Errorf("Expected 1 row in result %d, got %d", i, rows.Length()) } } } func TestStarDB_ExecX(t *testing.T) { db := setupTestDB(t) defer db.Close() user := User{ Name: "Alice", Age: 99, } result, err := db.ExecX(&user, "UPDATE users SET age = ? WHERE name = ?", ":age", ":name") if err != nil { t.Fatalf("ExecX failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } // Verify rows, err := db.Query("SELECT age FROM users WHERE name = ?", "Alice") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() age := rows.Row(0).MustInt("age") if age != 99 { t.Errorf("Expected age 99, got %d", age) } } func TestStarDB_ExecXContext(t *testing.T) { db := setupTestDB(t) defer db.Close() ctx := context.Background() user := User{ Name: "Bob", Active: false, } result, err := db.ExecXContext(ctx, &user, "UPDATE users SET active = ? WHERE name = ?", ":active", ":name") if err != nil { t.Fatalf("ExecXContext failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } } func TestStarDB_ExecXS(t *testing.T) { db := setupTestDB(t) defer db.Close() users := []User{ {Name: "Alice", Age: 26}, {Name: "Bob", Age: 31}, } results, err := db.ExecXS(&users, "UPDATE users SET age = ? WHERE name = ?", ":age", ":name") if err != nil { t.Fatalf("ExecXS failed: %v", err) } if len(results) != 2 { t.Errorf("Expected 2 results, got %d", len(results)) } for i, result := range results { affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed for result %d: %v", i, err) } if affected != 1 { t.Errorf("Expected 1 row affected in result %d, got %d", i, affected) } } } func TestStarTx_Insert(t *testing.T) { db := setupTestDB(t) defer db.Close() tx, err := db.Begin() if err != nil { t.Fatalf("Begin failed: %v", err) } user := User{ Name: "Frank", Email: "frank@example.com", Age: 45, Balance: 500.00, Active: true, CreatedAt: time.Now(), } result, err := tx.Insert(&user, "users", "id") if err != nil { tx.Rollback() t.Fatalf("Tx.Insert failed: %v", err) } err = tx.Commit() if err != nil { t.Fatalf("Commit failed: %v", err) } lastID, err := result.LastInsertId() if err != nil { t.Fatalf("LastInsertId failed: %v", err) } if lastID <= 0 { t.Errorf("Expected positive last insert ID, got %d", lastID) } // Verify rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Frank") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() if rows.Length() != 1 { t.Errorf("Expected 1 row, got %d", rows.Length()) } } func TestStarTx_Update(t *testing.T) { db := setupTestDB(t) defer db.Close() tx, err := db.Begin() if err != nil { t.Fatalf("Begin failed: %v", err) } // Get user rows, err := tx.Query("SELECT * FROM users WHERE name = ?", "Alice") if err != nil { tx.Rollback() t.Fatalf("Query failed: %v", err) } var user User err = rows.Orm(&user) rows.Close() if err != nil { tx.Rollback() t.Fatalf("Orm failed: %v", err) } // Update user.Age = 27 result, err := tx.Update(&user, "users", "id") if err != nil { tx.Rollback() t.Fatalf("Tx.Update failed: %v", err) } err = tx.Commit() if err != nil { t.Fatalf("Commit failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } } func TestStarTx_QueryX(t *testing.T) { db := setupTestDB(t) defer db.Close() tx, err := db.Begin() if err != nil { t.Fatalf("Begin failed: %v", err) } defer tx.Rollback() user := User{ Name: "Charlie", } rows, err := tx.QueryX(&user, "SELECT * FROM users WHERE name = ?", ":name") if err != nil { t.Fatalf("Tx.QueryX failed: %v", err) } defer rows.Close() if rows.Length() != 1 { t.Errorf("Expected 1 row, got %d", rows.Length()) } } func TestStarTx_ExecX(t *testing.T) { db := setupTestDB(t) defer db.Close() tx, err := db.Begin() if err != nil { t.Fatalf("Begin failed: %v", err) } user := User{ Name: "Charlie", Age: 36, } result, err := tx.ExecX(&user, "UPDATE users SET age = ? WHERE name = ?", ":age", ":name") if err != nil { tx.Rollback() t.Fatalf("Tx.ExecX failed: %v", err) } err = tx.Commit() if err != nil { t.Fatalf("Commit failed: %v", err) } affected, err := result.RowsAffected() if err != nil { t.Fatalf("RowsAffected failed: %v", err) } if affected != 1 { t.Errorf("Expected 1 row affected, got %d", affected) } } func TestStarTx_Rollback(t *testing.T) { db := setupTestDB(t) defer db.Close() tx, err := db.Begin() if err != nil { t.Fatalf("Begin failed: %v", err) } user := User{ Name: "Rollback User", Email: "rollback@example.com", Age: 50, Balance: 600.00, Active: true, CreatedAt: time.Now(), } _, err = tx.Insert(&user, "users", "id") if err != nil { tx.Rollback() t.Fatalf("Tx.Insert failed: %v", err) } // Rollback instead of commit err = tx.Rollback() if err != nil { t.Fatalf("Rollback failed: %v", err) } // Verify the insert was rolled back rows, err := db.Query("SELECT * FROM users WHERE name = ?", "Rollback User") if err != nil { t.Fatalf("Query failed: %v", err) } defer rows.Close() if rows.Length() != 0 { t.Errorf("Expected 0 rows after rollback, got %d", rows.Length()) } } func TestNamedParameterEscape(t *testing.T) { db := setupTestDB(t) defer db.Close() user := User{ Name: "Alice", } // Test escaped colon rows, err := db.QueryX(&user, "SELECT * FROM users WHERE name = ?", `\:name`) if err != nil { t.Fatalf("QueryX with escaped parameter failed: %v", err) } defer rows.Close() // Should use literal ":name" string, not the field value if rows.Length() != 0 { t.Errorf("Expected 0 rows with literal ':name', got %d", rows.Length()) } }