From 930586317cf293a0b4edc4812dcf335a6e24848d Mon Sep 17 00:00:00 2001 From: MrQinlala <143786565+MrQinlala@users.noreply.github.com> Date: Wed, 1 Jul 2026 14:29:09 +0800 Subject: [PATCH] Fix PriorityQueue reopening existing databases --- priority_queue.go | 40 +++++++++++++++++++++++++++++++-------- priority_queue_test.go | 43 ++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/priority_queue.go b/priority_queue.go index dce83c3..d341b12 100644 --- a/priority_queue.go +++ b/priority_queue.go @@ -35,21 +35,45 @@ func newPriorityQueue(db *sql.DB, tableName string, opts ...Option) (*PriorityQu // initPriorityColumn adds the priority column to the table if it doesn't exist func (pq *PriorityQueue) initPriorityColumn() error { // Check if priority column exists - var name string - err := pq.client.QueryRow(fmt.Sprintf("PRAGMA table_info(%s)", quoteIdent(pq.tableName))).Scan(nil, &name, nil, nil, nil, nil) + rows, err := pq.client.Query(fmt.Sprintf("PRAGMA table_info(%s)", quoteIdent(pq.tableName))) + if err != nil { + return err + } + defer rows.Close() + + hasPriority := false + for rows.Next() { + var cid int + var name, columnType string + var notNull, pk int + var defaultValue sql.NullString + if err := rows.Scan(&cid, &name, &columnType, ¬Null, &defaultValue, &pk); err != nil { + return err + } + if name == "priority" { + hasPriority = true + break + } + } + if err := rows.Err(); err != nil { + return err + } + if err := rows.Close(); err != nil { + return err + } - if err != nil || name != "priority" { + if !hasPriority { // Add priority column with default value 0 _, err := pq.client.Exec(fmt.Sprintf("ALTER TABLE %s ADD COLUMN priority INTEGER NOT NULL DEFAULT 0", quoteIdent(pq.tableName))) if err != nil { return err } + } - // Create index on priority (ASC for lower numbers = higher priority) - _, err = pq.client.Exec(fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (priority ASC, created_at ASC)", quoteIdent(pq.tableName+"_priority_idx"), quoteIdent(pq.tableName))) - if err != nil { - return err - } + // Create index on priority (ASC for lower numbers = higher priority) + _, err = pq.client.Exec(fmt.Sprintf("CREATE INDEX IF NOT EXISTS %s ON %s (priority ASC, created_at ASC)", quoteIdent(pq.tableName+"_priority_idx"), quoteIdent(pq.tableName))) + if err != nil { + return err } return nil diff --git a/priority_queue_test.go b/priority_queue_test.go index 0d1c7da..2379b1c 100644 --- a/priority_queue_test.go +++ b/priority_queue_test.go @@ -3,11 +3,30 @@ package sqliteq import ( "fmt" "os" + "path/filepath" "testing" _ "github.com/mattn/go-sqlite3" ) +func TestPriorityQueueReopenExistingDB(t *testing.T) { + dbPath := filepath.Join(t.TempDir(), "test_priority_reopen.db") + + first := New(dbPath) + if _, err := first.NewPriorityQueue("pq"); err != nil { + t.Fatalf("first NewPriorityQueue failed: %v", err) + } + if err := first.Close(); err != nil { + t.Fatalf("first Close failed: %v", err) + } + + second := New(dbPath) + defer second.Close() + if _, err := second.NewPriorityQueue("pq"); err != nil { + t.Fatalf("second NewPriorityQueue failed: %v", err) + } +} + func TestPriorityQueue(t *testing.T) { // Create a temporary database file dbPath := "test_priority_queue.db" @@ -72,7 +91,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "high priority" { t.Errorf("Expected 'high priority', got '%s'", string(byteData)) } @@ -98,7 +117,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "second high priority" { t.Errorf("Expected 'second high priority', got '%s'", string(byteData)) } @@ -113,7 +132,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "medium priority" { t.Errorf("Expected 'medium priority', got '%s'", string(byteData)) } @@ -128,7 +147,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "low priority" { t.Errorf("Expected 'low priority', got '%s'", string(byteData)) } @@ -174,7 +193,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "highest" { t.Errorf("Expected 'highest', got '%s'", string(byteData)) } @@ -216,7 +235,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "high" { t.Errorf("Expected 'high', got '%s'", string(byteData)) } @@ -247,7 +266,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "priority 1" { t.Errorf("Expected 'priority 1', got '%s'", string(byteData)) } @@ -276,7 +295,7 @@ func TestPriorityQueue(t *testing.T) { t.Errorf("Expected []byte, got %T", item) continue } - + if string(byteData) != expected { t.Errorf("Expected '%s', got '%s'", expected, string(byteData)) } @@ -291,7 +310,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "priority 10" { t.Errorf("Expected 'priority 10', got '%s'", string(byteData)) } @@ -316,7 +335,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "negative priority" { t.Errorf("Expected 'negative priority', got '%s'", string(byteData)) } @@ -330,7 +349,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "zero priority" { t.Errorf("Expected 'zero priority', got '%s'", string(byteData)) } @@ -344,7 +363,7 @@ func TestPriorityQueue(t *testing.T) { if !ok { t.Errorf("Expected []byte, got %T", item) } - + if string(byteData) != "positive priority" { t.Errorf("Expected 'positive priority', got '%s'", string(byteData)) }