You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.4 KiB
94 lines
2.4 KiB
package db |
|
|
|
import ( |
|
"context" |
|
"database/sql" |
|
"errors" |
|
"time" |
|
|
|
_ "github.com/tursodatabase/libsql-client-go/libsql" |
|
) |
|
|
|
type Progress struct { |
|
ID string |
|
UserID string |
|
LevelID string |
|
Status string |
|
CompletedAt sql.NullTime |
|
AttemptData sql.NullString |
|
Stars sql.NullInt64 |
|
CreatedAt time.Time |
|
UpdatedAt time.Time |
|
} |
|
|
|
type ProgressClient struct { |
|
db *sql.DB |
|
} |
|
|
|
func NewProgressClient(db *sql.DB) *ProgressClient { |
|
return &ProgressClient{db: db} |
|
} |
|
|
|
func (c *ProgressClient) UpsertProgress(ctx context.Context, p *Progress) error { |
|
_, err := c.db.ExecContext(ctx, ` |
|
INSERT INTO progress (id, user_id, level_id, status, completed_at, attempt_data, stars) |
|
VALUES (?, ?, ?, ?, ?, ?, ?) |
|
ON CONFLICT(user_id, level_id) DO UPDATE SET |
|
status = excluded.status, |
|
completed_at = excluded.completed_at, |
|
attempt_data = excluded.attempt_data, |
|
stars = excluded.stars, |
|
updated_at = CURRENT_TIMESTAMP |
|
`, p.ID, p.UserID, p.LevelID, p.Status, p.CompletedAt, p.AttemptData, p.Stars) |
|
return err |
|
} |
|
|
|
func (c *ProgressClient) GetProgressByUser(ctx context.Context, userID string) ([]*Progress, error) { |
|
rows, err := c.db.QueryContext(ctx, ` |
|
SELECT id, user_id, level_id, status, completed_at, attempt_data, stars, created_at, updated_at |
|
FROM progress |
|
WHERE user_id = ? |
|
`, userID) |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer rows.Close() |
|
|
|
var progressList []*Progress |
|
for rows.Next() { |
|
var p Progress |
|
err := rows.Scan(&p.ID, &p.UserID, &p.LevelID, &p.Status, &p.CompletedAt, &p.AttemptData, &p.Stars, &p.CreatedAt, &p.UpdatedAt) |
|
if err != nil { |
|
return nil, err |
|
} |
|
progressList = append(progressList, &p) |
|
} |
|
|
|
return progressList, nil |
|
} |
|
|
|
func (c *ProgressClient) GetProgress(ctx context.Context, userID, levelID string) (*Progress, error) { |
|
row := c.db.QueryRowContext(ctx, ` |
|
SELECT id, user_id, level_id, status, completed_at, attempt_data, stars, created_at, updated_at |
|
FROM progress |
|
WHERE user_id = ? AND level_id = ? |
|
`, userID, levelID) |
|
|
|
var p Progress |
|
err := row.Scan(&p.ID, &p.UserID, &p.LevelID, &p.Status, &p.CompletedAt, &p.AttemptData, &p.Stars, &p.CreatedAt, &p.UpdatedAt) |
|
if err != nil { |
|
if errors.Is(err, sql.ErrNoRows) { |
|
return nil, nil |
|
} |
|
return nil, err |
|
} |
|
return &p, nil |
|
} |
|
|
|
func (c *ProgressClient) DeleteProgress(ctx context.Context, userID, levelID string) error { |
|
_, err := c.db.ExecContext(ctx, ` |
|
DELETE FROM progress |
|
WHERE user_id = ? AND level_id = ? |
|
`, userID, levelID) |
|
return err |
|
}
|
|
|