692 lines
14 KiB
Go
692 lines
14 KiB
Go
|
|
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())
|
||
|
|
}
|
||
|
|
}
|