Fix build and run issues
This commit is contained in:
@@ -3,9 +3,10 @@ package db
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
func Open(dsn string) (*sql.DB, error) {
|
||||
@@ -22,6 +23,10 @@ func Open(dsn string) (*sql.DB, error) {
|
||||
func Migrate(ctx context.Context, db *sql.DB) error {
|
||||
for _, stmt := range statements {
|
||||
if _, err := db.ExecContext(ctx, stmt); err != nil {
|
||||
var mysqlErr *mysql.MySQLError
|
||||
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1060 {
|
||||
continue // duplicate column — already exists
|
||||
}
|
||||
return fmt.Errorf("migrate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ var statements = []string{
|
||||
active TINYINT NOT NULL DEFAULT 1,
|
||||
is_trainee TINYINT NOT NULL DEFAULT 0,
|
||||
phone VARCHAR(20) NULL,
|
||||
operational_roles TEXT NOT NULL DEFAULT '',
|
||||
operational_roles TEXT NOT NULL,
|
||||
notification_preference VARCHAR(50) NOT NULL DEFAULT 'email',
|
||||
admin_notes TEXT NULL,
|
||||
last_login DATETIME NULL,
|
||||
@@ -19,15 +19,15 @@ var statements = []string{
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
|
||||
// Additive column migrations for existing deployments
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS is_trainee TINYINT NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS phone VARCHAR(20) NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS operational_roles TEXT NOT NULL DEFAULT ''`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS notification_preference VARCHAR(50) NOT NULL DEFAULT 'email'`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS admin_notes TEXT NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS last_login DATETIME NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS invite_token VARCHAR(255) NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN IF NOT EXISTS invite_expires_at DATETIME NULL`,
|
||||
// Additive column migrations for existing deployments (duplicates ignored at runtime)
|
||||
`ALTER TABLE volunteers ADD COLUMN is_trainee TINYINT NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE volunteers ADD COLUMN phone VARCHAR(20) NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN operational_roles TEXT NOT NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN notification_preference VARCHAR(50) NOT NULL DEFAULT 'email'`,
|
||||
`ALTER TABLE volunteers ADD COLUMN admin_notes TEXT NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN last_login DATETIME NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN invite_token VARCHAR(255) NULL`,
|
||||
`ALTER TABLE volunteers ADD COLUMN invite_expires_at DATETIME NULL`,
|
||||
`CREATE TABLE IF NOT EXISTS schedules (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
volunteer_id INT NOT NULL,
|
||||
@@ -72,11 +72,11 @@ var statements = []string{
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
volunteer_id INT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
read TINYINT NOT NULL DEFAULT 0,
|
||||
is_read TINYINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (volunteer_id) REFERENCES volunteers(id) ON DELETE CASCADE,
|
||||
INDEX idx_volunteer_id (volunteer_id),
|
||||
INDEX idx_read (read)
|
||||
INDEX idx_is_read (is_read)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
|
||||
`CREATE TABLE IF NOT EXISTS shift_templates (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
|
||||
@@ -14,7 +14,7 @@ type Notification struct {
|
||||
ID int64 `json:"id"`
|
||||
VolunteerID int64 `json:"volunteer_id"`
|
||||
Message string `json:"message"`
|
||||
Read bool `json:"read"`
|
||||
Read bool `json:"is_read"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func (s *Store) GetByID(ctx context.Context, id int64) (*Notification, error) {
|
||||
n := &Notification{}
|
||||
var createdAt string
|
||||
err := s.db.QueryRowContext(ctx,
|
||||
`SELECT id, volunteer_id, message, read, created_at FROM notifications WHERE id = ?`, id,
|
||||
`SELECT id, volunteer_id, message, is_read, created_at FROM notifications WHERE id = ?`, id,
|
||||
).Scan(&n.ID, &n.VolunteerID, &n.Message, &n.Read, &createdAt)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrNotFound
|
||||
@@ -56,7 +56,7 @@ func (s *Store) GetByID(ctx context.Context, id int64) (*Notification, error) {
|
||||
|
||||
func (s *Store) ListForVolunteer(ctx context.Context, volunteerID int64) ([]Notification, error) {
|
||||
rows, err := s.db.QueryContext(ctx,
|
||||
`SELECT id, volunteer_id, message, read, created_at FROM notifications WHERE volunteer_id = ? ORDER BY created_at DESC`,
|
||||
`SELECT id, volunteer_id, message, is_read, created_at FROM notifications WHERE volunteer_id = ? ORDER BY created_at DESC`,
|
||||
volunteerID,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -85,7 +85,7 @@ func (s *Store) CreateNotification(ctx context.Context, volunteerID int64, messa
|
||||
|
||||
func (s *Store) MarkRead(ctx context.Context, id, volunteerID int64) (*Notification, error) {
|
||||
result, err := s.db.ExecContext(ctx,
|
||||
`UPDATE notifications SET read = 1 WHERE id = ? AND volunteer_id = ?`,
|
||||
`UPDATE notifications SET is_read = 1 WHERE id = ? AND volunteer_id = ?`,
|
||||
id, volunteerID,
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user