Add regional variant tagging (us/gb) for English words

- SCOWL loader now loads american-words and british-words alongside
  english-words, tagging each with variant "us", "gb", or NULL (common)
- Words appearing in both American and British lists get NULL variant
- Add variant column to words table with schema migration
- API: /define returns variant field for English, /random and /words
  accept ?variant=us|gb filter
- Add total word count to server status line
- Fix rows.Close leak in PopulateCMUTails, add rows.Err() check
- Add tests for PopulateCMUTails, cmuTail, TotalWordCount
- Expand test seed data and assertions to cover pt-PT definitions,
  synonyms, and validity checks
- Update README with variant docs, /difficulty, /words, /rhyme
  endpoints, and current database statistics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-04-04 15:21:27 -07:00
parent 28ec11ba4e
commit 704c06f41d
8 changed files with 488 additions and 71 deletions

View File

@@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS words (
pos TEXT,
frequency INTEGER DEFAULT 0,
difficulty REAL DEFAULT NULL,
variant TEXT,
UNIQUE(word, lang)
);
@@ -159,6 +160,7 @@ func BootstrapSchema(db *sql.DB) error {
migrations := []string{
"ALTER TABLE words ADD COLUMN difficulty REAL DEFAULT NULL",
"ALTER TABLE pronunciations ADD COLUMN cmu_tail TEXT",
"ALTER TABLE words ADD COLUMN variant TEXT",
}
for _, m := range migrations {
if _, err := db.Exec(m); err != nil {
@@ -205,6 +207,7 @@ func PopulateCMUTails(db *sql.DB) (int, error) {
if err != nil {
return 0, fmt.Errorf("dictionary: populate cmu tails: %w", err)
}
defer rows.Close()
type entry struct {
id int
@@ -214,12 +217,13 @@ func PopulateCMUTails(db *sql.DB) (int, error) {
for rows.Next() {
var e entry
if err := rows.Scan(&e.id, &e.value); err != nil {
rows.Close()
return 0, fmt.Errorf("dictionary: populate cmu tails scan: %w", err)
}
entries = append(entries, e)
}
rows.Close()
if err := rows.Err(); err != nil {
return 0, fmt.Errorf("dictionary: populate cmu tails iterate: %w", err)
}
if len(entries) == 0 {
return 0, nil