Renaming and cleanupUnverified
bb615b0 parent: 0548274 modified
internal/cluster/jaccard_test.go +78 -78 | @@ -15,7 +15,7 @@ import ( | ||
| 15 | 15 | "gotest.tools/v3/assert" |
| 16 | 16 | ) |
| 17 | 17 | |
| 18 | -func setupClusterTestDB(t *testing.T) *db.Databases { | |
| 18 | +func setupClusterTestDB(t *testing.T) *db.Store { | |
| 19 | 19 | t.Helper() |
| 20 | 20 | vec.Auto() |
| 21 | 21 | f, err := os.CreateTemp("", "glean-cluster-test-*.db") |
| @@ -35,19 +35,19 @@ func setupClusterTestDB(t *testing.T) *db.Databases { | ||
| 35 | 35 | _ = os.Remove(path + "_recs-wal") |
| 36 | 36 | }) |
| 37 | 37 | |
| 38 | - dbs, err := db.OpenAll(path) | |
| 38 | + dbs, err := db.Open(path) | |
| 39 | 39 | assert.NilError(t, err) |
| 40 | 40 | t.Cleanup(func() { _ = dbs.Close() }) |
| 41 | 41 | assert.NilError(t, dbs.InitVecTables(8)) |
| 42 | 42 | return dbs |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | -func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | |
| 45 | +func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Store) { | |
| 46 | 46 | t.Helper() |
| 47 | 47 | |
| 48 | 48 | users := []string{"did:test:alice", "did:test:bob", "did:test:carol", "did:test:dave"} |
| 49 | 49 | for _, did := range users { |
| 50 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, did) | |
| 50 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, did) | |
| 51 | 51 | assert.NilError(t, err) |
| 52 | 52 | } |
| 53 | 53 | |
| @@ -59,7 +59,7 @@ func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | ||
| 59 | 59 | {"https://e.com/feed", "Feed E"}, |
| 60 | 60 | } |
| 61 | 61 | for _, f := range feeds { |
| 62 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, '', 'rss', 2)`, f.url, f.title, f.url) | |
| 62 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, '', 'rss', 2)`, f.url, f.title, f.url) | |
| 63 | 63 | assert.NilError(t, err) |
| 64 | 64 | } |
| 65 | 65 | |
| @@ -75,12 +75,12 @@ func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | ||
| 75 | 75 | {"did:test:carol", "https://c.com/feed"}, |
| 76 | 76 | } |
| 77 | 77 | for _, s := range subs { |
| 78 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, s.user, s.feed) | |
| 78 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, s.user, s.feed) | |
| 79 | 79 | assert.NilError(t, err) |
| 80 | 80 | } |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | -func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Databases) { | |
| 83 | +func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Store) { | |
| 84 | 84 | t.Helper() |
| 85 | 85 | follows := []struct{ user, target string }{ |
| 86 | 86 | {"did:test:alice", "did:test:bob"}, |
| @@ -88,13 +88,13 @@ func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Databases) { | ||
| 88 | 88 | {"did:test:carol", "did:test:dave"}, |
| 89 | 89 | } |
| 90 | 90 | for _, f := range follows { |
| 91 | - _, err := dbs.DB().ExecContext(ctx, `INSERT OR IGNORE INTO follows (user_did, target_did) VALUES (?, ?)`, f.user, f.target) | |
| 91 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT OR IGNORE INTO follows (user_did, target_did) VALUES (?, ?)`, f.user, f.target) | |
| 92 | 92 | assert.NilError(t, err) |
| 93 | 93 | } |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | -func newTestEngine(dbs *db.Databases) *Engine { | |
| 97 | - return NewEngine(dbs.DB(), NewMockEmbedder(8), slog.Default()) | |
| 96 | +func newTestEngine(dbs *db.Store) *Engine { | |
| 97 | + return NewEngine(dbs.SQLDB(), NewMockEmbedder(8), slog.Default()) | |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | 100 | func TestComputeFeedSimilarity(t *testing.T) { |
| @@ -107,7 +107,7 @@ func TestComputeFeedSimilarity(t *testing.T) { | ||
| 107 | 107 | assert.NilError(t, err) |
| 108 | 108 | |
| 109 | 109 | var count int |
| 110 | - err = dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_similarity`).Scan(&count) | |
| 110 | + err = dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_similarity`).Scan(&count) | |
| 111 | 111 | assert.NilError(t, err) |
| 112 | 112 | assert.Assert(t, count > 0, "expected feed similarity pairs") |
| 113 | 113 | } |
| @@ -122,7 +122,7 @@ func TestComputeUserSimilarity(t *testing.T) { | ||
| 122 | 122 | assert.NilError(t, err) |
| 123 | 123 | |
| 124 | 124 | var count int |
| 125 | - err = dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_similarity`).Scan(&count) | |
| 125 | + err = dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_similarity`).Scan(&count) | |
| 126 | 126 | assert.NilError(t, err) |
| 127 | 127 | assert.Assert(t, count > 0, "expected user similarity pairs") |
| 128 | 128 | } |
| @@ -224,14 +224,14 @@ func TestRecordImpressions(t *testing.T) { | ||
| 224 | 224 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) |
| 225 | 225 | |
| 226 | 226 | var count int |
| 227 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 227 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 228 | 228 | `SELECT COUNT(*) FROM main.recommendation_impressions WHERE user_did = 'did:test:alice'`).Scan(&count)) |
| 229 | 229 | assert.Equal(t, count, 2) |
| 230 | 230 | |
| 231 | 231 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) |
| 232 | 232 | |
| 233 | 233 | var shownCount int |
| 234 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 234 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 235 | 235 | `SELECT shown_count FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&shownCount)) |
| 236 | 236 | assert.Equal(t, shownCount, 2, "shown_count should increment on repeated impression") |
| 237 | 237 | } |
| @@ -249,7 +249,7 @@ func TestMarkImpressionActed(t *testing.T) { | ||
| 249 | 249 | assert.NilError(t, engine.MarkImpressionActed(ctx, "did:test:alice", "feed", "https://a.com/feed")) |
| 250 | 250 | |
| 251 | 251 | var acted bool |
| 252 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 252 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 253 | 253 | `SELECT acted FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&acted)) |
| 254 | 254 | assert.Assert(t, acted, "impression should be marked as acted") |
| 255 | 255 | } |
| @@ -264,22 +264,22 @@ func TestComputeFollowDistances(t *testing.T) { | ||
| 264 | 264 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) |
| 265 | 265 | |
| 266 | 266 | var d1, d2, d3 int |
| 267 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 267 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 268 | 268 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 1`).Scan(&d1)) |
| 269 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 269 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 270 | 270 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 2`).Scan(&d2)) |
| 271 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 271 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 272 | 272 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 3`).Scan(&d3)) |
| 273 | 273 | assert.Assert(t, d1 >= 3, "expected at least 3 direct follow distances") |
| 274 | 274 | assert.Assert(t, d2 >= 1, "expected at least 1 two-hop distance (alice -> bob -> carol)") |
| 275 | 275 | assert.Assert(t, d3 >= 1, "expected at least 1 three-hop distance (alice -> bob -> carol -> dave)") |
| 276 | 276 | |
| 277 | 277 | var exists int |
| 278 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 278 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 279 | 279 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:carol'`).Scan(&exists)) |
| 280 | 280 | assert.Assert(t, exists == 1, "alice should reach carol") |
| 281 | 281 | |
| 282 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 282 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 283 | 283 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:dave'`).Scan(&exists)) |
| 284 | 284 | assert.Assert(t, exists == 1, "alice should reach dave via 3 hops") |
| 285 | 285 | } |
| @@ -300,7 +300,7 @@ func TestComputeFollowDistancesData_SplitReadWrite(t *testing.T) { | ||
| 300 | 300 | assert.NilError(t, engine.WriteFollowDistances(ctx, distances)) |
| 301 | 301 | |
| 302 | 302 | var count int |
| 303 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.follow_distances`).Scan(&count)) | |
| 303 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.follow_distances`).Scan(&count)) | |
| 304 | 304 | assert.Equal(t, count, len(distances)) |
| 305 | 305 | } |
| 306 | 306 | |
| @@ -311,7 +311,7 @@ func TestAutoDismissStale(t *testing.T) { | ||
| 311 | 311 | |
| 312 | 312 | engine := newTestEngine(dbs) |
| 313 | 313 | |
| 314 | - _, err := dbs.DB().ExecContext(ctx, ` | |
| 314 | + _, err := dbs.SQLDB().ExecContext(ctx, ` | |
| 315 | 315 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 316 | 316 | VALUES ('did:test:alice', 'feed', 'https://stale.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 0) |
| 317 | 317 | `) |
| @@ -331,7 +331,7 @@ func TestAutoDismissStale_DoesNotDismissRecent(t *testing.T) { | ||
| 331 | 331 | |
| 332 | 332 | engine := newTestEngine(dbs) |
| 333 | 333 | |
| 334 | - _, err := dbs.DB().ExecContext(ctx, ` | |
| 334 | + _, err := dbs.SQLDB().ExecContext(ctx, ` | |
| 335 | 335 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 336 | 336 | VALUES ('did:test:alice', 'feed', 'https://recent.com/feed', datetime('now'), datetime('now'), 5, 0) |
| 337 | 337 | `) |
| @@ -351,7 +351,7 @@ func TestAutoDismissStale_DoesNotDismissActed(t *testing.T) { | ||
| 351 | 351 | |
| 352 | 352 | engine := newTestEngine(dbs) |
| 353 | 353 | |
| 354 | - _, err := dbs.DB().ExecContext(ctx, ` | |
| 354 | + _, err := dbs.SQLDB().ExecContext(ctx, ` | |
| 355 | 355 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 356 | 356 | VALUES ('did:test:alice', 'feed', 'https://acted.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 1) |
| 357 | 357 | `) |
| @@ -427,13 +427,13 @@ func TestSignalWeights_RewardPenalize(t *testing.T) { | ||
| 427 | 427 | |
| 428 | 428 | engine := newTestEngine(dbs) |
| 429 | 429 | |
| 430 | - _, err := dbs.DB().ExecContext(ctx, ` | |
| 430 | + _, err := dbs.SQLDB().ExecContext(ctx, ` | |
| 431 | 431 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 432 | 432 | VALUES ('did:test:alice', 'feed', 'https://a.com/feed', datetime('now'), datetime('now'), 1, 1) |
| 433 | 433 | `) |
| 434 | 434 | assert.NilError(t, err) |
| 435 | 435 | for i := range minActionsTune { |
| 436 | - _, err = dbs.DB().ExecContext(ctx, ` | |
| 436 | + _, err = dbs.SQLDB().ExecContext(ctx, ` | |
| 437 | 437 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 438 | 438 | VALUES ('did:test:alice', 'feed', ?, datetime('now'), datetime('now'), 1, 1) |
| 439 | 439 | `, fmt.Sprintf("https://%d.com/feed", i)) |
| @@ -455,12 +455,12 @@ func TestColdStartRecommendations(t *testing.T) { | ||
| 455 | 455 | engine := newTestEngine(dbs) |
| 456 | 456 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) |
| 457 | 457 | |
| 458 | - _, err := dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://a.com/feed'`) | |
| 458 | + _, err := dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://a.com/feed'`) | |
| 459 | 459 | assert.NilError(t, err) |
| 460 | - _, err = dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://b.com/feed'`) | |
| 460 | + _, err = dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://b.com/feed'`) | |
| 461 | 461 | assert.NilError(t, err) |
| 462 | 462 | |
| 463 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | |
| 463 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | |
| 464 | 464 | assert.NilError(t, err) |
| 465 | 465 | |
| 466 | 466 | recs, err := engine.ColdStartRecommendations(ctx, "did:test:newuser", 10) |
| @@ -505,7 +505,7 @@ func TestDismissArticle(t *testing.T) { | ||
| 505 | 505 | assert.NilError(t, engine.DismissArticle(ctx, "did:test:alice", "https://a.com/article1", "not_interested")) |
| 506 | 506 | |
| 507 | 507 | var count int |
| 508 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 508 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 509 | 509 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'article'`).Scan(&count)) |
| 510 | 510 | assert.Equal(t, count, 1) |
| 511 | 511 | } |
| @@ -519,7 +519,7 @@ func TestComputeSignalProfiles(t *testing.T) { | ||
| 519 | 519 | assert.NilError(t, engine.ComputeSignalProfiles(ctx)) |
| 520 | 520 | |
| 521 | 521 | var count int |
| 522 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_signal_profiles`).Scan(&count)) | |
| 522 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_signal_profiles`).Scan(&count)) | |
| 523 | 523 | assert.Assert(t, count >= 3, "expected signal profiles for all users") |
| 524 | 524 | } |
| 525 | 525 | |
| @@ -534,7 +534,7 @@ func TestDismissFeed_Idempotent(t *testing.T) { | ||
| 534 | 534 | assert.NilError(t, engine.DismissFeed(ctx, "did:test:alice", "https://a.com/feed", "reason2")) |
| 535 | 535 | |
| 536 | 536 | var count int |
| 537 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 537 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 538 | 538 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'feed'`).Scan(&count)) |
| 539 | 539 | assert.Equal(t, count, 1, "duplicate dismiss should not create extra rows") |
| 540 | 540 | } |
| @@ -543,25 +543,25 @@ func TestEmbeddingBasedFeedSimilarity(t *testing.T) { | ||
| 543 | 543 | ctx := context.Background() |
| 544 | 544 | dbs := setupClusterTestDB(t) |
| 545 | 545 | |
| 546 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 546 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 547 | 547 | assert.NilError(t, err) |
| 548 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 548 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 549 | 549 | assert.NilError(t, err) |
| 550 | 550 | |
| 551 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 551 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 552 | 552 | "https://go.com/feed", "Go Blog", "https://go.com", "programming language golang software development") |
| 553 | 553 | assert.NilError(t, err) |
| 554 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 554 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 555 | 555 | "https://rust.com/feed", "Rust Blog", "https://rust.com", "programming language rust software development") |
| 556 | 556 | assert.NilError(t, err) |
| 557 | 557 | |
| 558 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://go.com/feed") | |
| 558 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://go.com/feed") | |
| 559 | 559 | assert.NilError(t, err) |
| 560 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://rust.com/feed") | |
| 560 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://rust.com/feed") | |
| 561 | 561 | assert.NilError(t, err) |
| 562 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://go.com/feed") | |
| 562 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://go.com/feed") | |
| 563 | 563 | assert.NilError(t, err) |
| 564 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://rust.com/feed") | |
| 564 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://rust.com/feed") | |
| 565 | 565 | assert.NilError(t, err) |
| 566 | 566 | |
| 567 | 567 | engine := newTestEngine(dbs) |
| @@ -570,7 +570,7 @@ func TestEmbeddingBasedFeedSimilarity(t *testing.T) { | ||
| 570 | 570 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) |
| 571 | 571 | |
| 572 | 572 | var jaccard float64 |
| 573 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 573 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 574 | 574 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = ? AND feed_b = ?`, |
| 575 | 575 | "https://go.com/feed", "https://rust.com/feed").Scan(&jaccard)) |
| 576 | 576 | assert.Assert(t, jaccard > 1.0, "embedding cosine similarity should boost feed similarity above pure Jaccard") |
| @@ -610,17 +610,17 @@ func TestComputeArticleEmbeddings(t *testing.T) { | ||
| 610 | 610 | ctx := context.Background() |
| 611 | 611 | dbs := setupClusterTestDB(t) |
| 612 | 612 | |
| 613 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 1)`, | |
| 613 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 1)`, | |
| 614 | 614 | "https://tech.com/feed", "Tech Feed", "https://tech.com") |
| 615 | 615 | assert.NilError(t, err) |
| 616 | 616 | |
| 617 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 617 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 618 | 618 | "https://tech.com/feed", "1", "golang programming language tutorial", "learn the go programming language for backend development", "https://tech.com/go") |
| 619 | 619 | assert.NilError(t, err) |
| 620 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 620 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 621 | 621 | "https://tech.com/feed", "2", "rust programming language guide", "learn the rust programming language for systems development", "https://tech.com/rust") |
| 622 | 622 | assert.NilError(t, err) |
| 623 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 623 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | |
| 624 | 624 | "https://tech.com/feed", "3", "cooking recipes for dinner", "easy dinner recipes for the whole family", "https://tech.com/cook") |
| 625 | 625 | assert.NilError(t, err) |
| 626 | 626 | |
| @@ -629,7 +629,7 @@ func TestComputeArticleEmbeddings(t *testing.T) { | ||
| 629 | 629 | assert.NilError(t, engine.ComputeArticleEmbeddings(ctx)) |
| 630 | 630 | |
| 631 | 631 | var count int |
| 632 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.article_embeddings`).Scan(&count)) | |
| 632 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.article_embeddings`).Scan(&count)) | |
| 633 | 633 | assert.Equal(t, count, 3, "expected 3 article embeddings") |
| 634 | 634 | } |
| 635 | 635 | |
| @@ -637,44 +637,44 @@ func TestArticleRecommendationsWithContentBoost(t *testing.T) { | ||
| 637 | 637 | ctx := context.Background() |
| 638 | 638 | dbs := setupClusterTestDB(t) |
| 639 | 639 | |
| 640 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 640 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 641 | 641 | assert.NilError(t, err) |
| 642 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 642 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 643 | 643 | assert.NilError(t, err) |
| 644 | 644 | |
| 645 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 645 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 646 | 646 | "https://tech.com/feed", "Tech Feed", "https://tech.com") |
| 647 | 647 | assert.NilError(t, err) |
| 648 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 648 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 649 | 649 | "https://dev.com/feed", "Dev Feed", "https://dev.com") |
| 650 | 650 | assert.NilError(t, err) |
| 651 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 651 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 652 | 652 | "https://shared.com/feed", "Shared Feed", "https://shared.com") |
| 653 | 653 | assert.NilError(t, err) |
| 654 | 654 | |
| 655 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://tech.com/feed") | |
| 655 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://tech.com/feed") | |
| 656 | 656 | assert.NilError(t, err) |
| 657 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://shared.com/feed") | |
| 657 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://shared.com/feed") | |
| 658 | 658 | assert.NilError(t, err) |
| 659 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://dev.com/feed") | |
| 659 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://dev.com/feed") | |
| 660 | 660 | assert.NilError(t, err) |
| 661 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://shared.com/feed") | |
| 661 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://shared.com/feed") | |
| 662 | 662 | assert.NilError(t, err) |
| 663 | 663 | |
| 664 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 664 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 665 | 665 | "https://tech.com/feed", "1", "golang programming tutorial", "learn go programming", "https://tech.com/go") |
| 666 | 666 | assert.NilError(t, err) |
| 667 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 667 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 668 | 668 | "https://dev.com/feed", "2", "rust programming tutorial", "learn rust programming", "https://dev.com/rust") |
| 669 | 669 | assert.NilError(t, err) |
| 670 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 670 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | |
| 671 | 671 | "https://dev.com/feed", "3", "cooking dinner recipes", "easy dinner recipes", "https://dev.com/cook") |
| 672 | 672 | assert.NilError(t, err) |
| 673 | 673 | |
| 674 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | |
| 674 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | |
| 675 | 675 | "at://alice/like/1", "did:test:alice", "https://tech.com/feed", "https://tech.com/go") |
| 676 | 676 | assert.NilError(t, err) |
| 677 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | |
| 677 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | |
| 678 | 678 | "at://bob/like/1", "did:test:bob", "https://dev.com/feed", "https://dev.com/rust") |
| 679 | 679 | assert.NilError(t, err) |
| 680 | 680 | |
| @@ -693,7 +693,7 @@ func TestFeedEmbeddingRecomputedOnDescriptionChange(t *testing.T) { | ||
| 693 | 693 | ctx := context.Background() |
| 694 | 694 | dbs := setupClusterTestDB(t) |
| 695 | 695 | |
| 696 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type) VALUES (?, ?, ?, ?, 'rss')`, | |
| 696 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type) VALUES (?, ?, ?, ?, 'rss')`, | |
| 697 | 697 | "https://go.com/feed", "Go Blog", "https://go.com", "old description") |
| 698 | 698 | assert.NilError(t, err) |
| 699 | 699 | |
| @@ -702,16 +702,16 @@ func TestFeedEmbeddingRecomputedOnDescriptionChange(t *testing.T) { | ||
| 702 | 702 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) |
| 703 | 703 | |
| 704 | 704 | var count int |
| 705 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_embeddings`).Scan(&count)) | |
| 705 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_embeddings`).Scan(&count)) | |
| 706 | 706 | assert.Equal(t, count, 1) |
| 707 | 707 | |
| 708 | - _, err = dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET description = 'new description' WHERE feed_url = 'https://go.com/feed'`) | |
| 708 | + _, err = dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET description = 'new description' WHERE feed_url = 'https://go.com/feed'`) | |
| 709 | 709 | assert.NilError(t, err) |
| 710 | 710 | |
| 711 | 711 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) |
| 712 | 712 | |
| 713 | 713 | var sourceText string |
| 714 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT source_text FROM recs.feed_embedding_meta WHERE feed_url = 'https://go.com/feed'`).Scan(&sourceText)) | |
| 714 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT source_text FROM recs.feed_embedding_meta WHERE feed_url = 'https://go.com/feed'`).Scan(&sourceText)) | |
| 715 | 715 | assert.Assert(t, sourceText == "Go Blog new description", "embedding should be recomputed when description changes, got: %s", sourceText) |
| 716 | 716 | } |
| 717 | 717 | |
| @@ -719,28 +719,28 @@ func TestTimeDecayedFeedSimilarity(t *testing.T) { | ||
| 719 | 719 | ctx := context.Background() |
| 720 | 720 | dbs := setupClusterTestDB(t) |
| 721 | 721 | |
| 722 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 722 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | |
| 723 | 723 | assert.NilError(t, err) |
| 724 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 724 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | |
| 725 | 725 | assert.NilError(t, err) |
| 726 | 726 | |
| 727 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 727 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 728 | 728 | "https://a.com/feed", "Feed A", "https://a.com") |
| 729 | 729 | assert.NilError(t, err) |
| 730 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 730 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | |
| 731 | 731 | "https://b.com/feed", "Feed B", "https://b.com") |
| 732 | 732 | assert.NilError(t, err) |
| 733 | 733 | |
| 734 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now', '-60 days'))`, | |
| 734 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now', '-60 days'))`, | |
| 735 | 735 | "did:test:alice", "https://a.com/feed") |
| 736 | 736 | assert.NilError(t, err) |
| 737 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 737 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 738 | 738 | "did:test:bob", "https://a.com/feed") |
| 739 | 739 | assert.NilError(t, err) |
| 740 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 740 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 741 | 741 | "did:test:alice", "https://b.com/feed") |
| 742 | 742 | assert.NilError(t, err) |
| 743 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 743 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | |
| 744 | 744 | "did:test:bob", "https://b.com/feed") |
| 745 | 745 | assert.NilError(t, err) |
| 746 | 746 | |
| @@ -748,7 +748,7 @@ func TestTimeDecayedFeedSimilarity(t *testing.T) { | ||
| 748 | 748 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) |
| 749 | 749 | |
| 750 | 750 | var jaccard float64 |
| 751 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | |
| 751 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, | |
| 752 | 752 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = 'https://a.com/feed' AND feed_b = 'https://b.com/feed'`).Scan(&jaccard)) |
| 753 | 753 | assert.Assert(t, jaccard > 0, "time-decayed feed similarity should be positive") |
| 754 | 754 | assert.Assert(t, jaccard < 1.0, "time decay should reduce similarity below raw Jaccard") |
| @@ -758,20 +758,20 @@ func TestColdStartFromEmbeddings(t *testing.T) { | ||
| 758 | 758 | ctx := context.Background() |
| 759 | 759 | dbs := setupClusterTestDB(t) |
| 760 | 760 | |
| 761 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | |
| 761 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | |
| 762 | 762 | assert.NilError(t, err) |
| 763 | 763 | |
| 764 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 764 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 765 | 765 | "https://go.com/feed", "Go Blog", "https://go.com", "golang programming language") |
| 766 | 766 | assert.NilError(t, err) |
| 767 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 767 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 768 | 768 | "https://godev.com/feed", "Go Dev", "https://godev.com", "golang development tutorials") |
| 769 | 769 | assert.NilError(t, err) |
| 770 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 770 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | |
| 771 | 771 | "https://cooking.com/feed", "Cooking", "https://cooking.com", "recipes for dinner") |
| 772 | 772 | assert.NilError(t, err) |
| 773 | 773 | |
| 774 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, | |
| 774 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, | |
| 775 | 775 | "did:test:newuser", "https://go.com/feed") |
| 776 | 776 | assert.NilError(t, err) |
| 777 | 777 | |
| @@ -15,7 +15,7 @@ import ( | |||
| 15 | "gotest.tools/v3/assert" | 15 | "gotest.tools/v3/assert" |
| 16 | ) | 16 | ) |
| 17 | 17 | ||
| 18 | -func setupClusterTestDB(t *testing.T) *db.Databases { | 18 | +func setupClusterTestDB(t *testing.T) *db.Store { |
| 19 | t.Helper() | 19 | t.Helper() |
| 20 | vec.Auto() | 20 | vec.Auto() |
| 21 | f, err := os.CreateTemp("", "glean-cluster-test-*.db") | 21 | f, err := os.CreateTemp("", "glean-cluster-test-*.db") |
| @@ -35,19 +35,19 @@ func setupClusterTestDB(t *testing.T) *db.Databases { | |||
| 35 | _ = os.Remove(path + "_recs-wal") | 35 | _ = os.Remove(path + "_recs-wal") |
| 36 | }) | 36 | }) |
| 37 | 37 | ||
| 38 | - dbs, err := db.OpenAll(path) | 38 | + dbs, err := db.Open(path) |
| 39 | assert.NilError(t, err) | 39 | assert.NilError(t, err) |
| 40 | t.Cleanup(func() { _ = dbs.Close() }) | 40 | t.Cleanup(func() { _ = dbs.Close() }) |
| 41 | assert.NilError(t, dbs.InitVecTables(8)) | 41 | assert.NilError(t, dbs.InitVecTables(8)) |
| 42 | return dbs | 42 | return dbs |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | -func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | 45 | +func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Store) { |
| 46 | t.Helper() | 46 | t.Helper() |
| 47 | 47 | ||
| 48 | users := []string{"did:test:alice", "did:test:bob", "did:test:carol", "did:test:dave"} | 48 | users := []string{"did:test:alice", "did:test:bob", "did:test:carol", "did:test:dave"} |
| 49 | for _, did := range users { | 49 | for _, did := range users { |
| 50 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, did) | 50 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, did) |
| 51 | assert.NilError(t, err) | 51 | assert.NilError(t, err) |
| 52 | } | 52 | } |
| 53 | 53 | ||
| @@ -59,7 +59,7 @@ func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | |||
| 59 | {"https://e.com/feed", "Feed E"}, | 59 | {"https://e.com/feed", "Feed E"}, |
| 60 | } | 60 | } |
| 61 | for _, f := range feeds { | 61 | for _, f := range feeds { |
| 62 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, '', 'rss', 2)`, f.url, f.title, f.url) | 62 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, '', 'rss', 2)`, f.url, f.title, f.url) |
| 63 | assert.NilError(t, err) | 63 | assert.NilError(t, err) |
| 64 | } | 64 | } |
| 65 | 65 | ||
| @@ -75,12 +75,12 @@ func seedClusterData(t *testing.T, ctx context.Context, dbs *db.Databases) { | |||
| 75 | {"did:test:carol", "https://c.com/feed"}, | 75 | {"did:test:carol", "https://c.com/feed"}, |
| 76 | } | 76 | } |
| 77 | for _, s := range subs { | 77 | for _, s := range subs { |
| 78 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, s.user, s.feed) | 78 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, s.user, s.feed) |
| 79 | assert.NilError(t, err) | 79 | assert.NilError(t, err) |
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | -func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Databases) { | 83 | +func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Store) { |
| 84 | t.Helper() | 84 | t.Helper() |
| 85 | follows := []struct{ user, target string }{ | 85 | follows := []struct{ user, target string }{ |
| 86 | {"did:test:alice", "did:test:bob"}, | 86 | {"did:test:alice", "did:test:bob"}, |
| @@ -88,13 +88,13 @@ func seedFollowData(t *testing.T, ctx context.Context, dbs *db.Databases) { | |||
| 88 | {"did:test:carol", "did:test:dave"}, | 88 | {"did:test:carol", "did:test:dave"}, |
| 89 | } | 89 | } |
| 90 | for _, f := range follows { | 90 | for _, f := range follows { |
| 91 | - _, err := dbs.DB().ExecContext(ctx, `INSERT OR IGNORE INTO follows (user_did, target_did) VALUES (?, ?)`, f.user, f.target) | 91 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT OR IGNORE INTO follows (user_did, target_did) VALUES (?, ?)`, f.user, f.target) |
| 92 | assert.NilError(t, err) | 92 | assert.NilError(t, err) |
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | -func newTestEngine(dbs *db.Databases) *Engine { | 96 | +func newTestEngine(dbs *db.Store) *Engine { |
| 97 | - return NewEngine(dbs.DB(), NewMockEmbedder(8), slog.Default()) | 97 | + return NewEngine(dbs.SQLDB(), NewMockEmbedder(8), slog.Default()) |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | func TestComputeFeedSimilarity(t *testing.T) { | 100 | func TestComputeFeedSimilarity(t *testing.T) { |
| @@ -107,7 +107,7 @@ func TestComputeFeedSimilarity(t *testing.T) { | |||
| 107 | assert.NilError(t, err) | 107 | assert.NilError(t, err) |
| 108 | 108 | ||
| 109 | var count int | 109 | var count int |
| 110 | - err = dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_similarity`).Scan(&count) | 110 | + err = dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_similarity`).Scan(&count) |
| 111 | assert.NilError(t, err) | 111 | assert.NilError(t, err) |
| 112 | assert.Assert(t, count > 0, "expected feed similarity pairs") | 112 | assert.Assert(t, count > 0, "expected feed similarity pairs") |
| 113 | } | 113 | } |
| @@ -122,7 +122,7 @@ func TestComputeUserSimilarity(t *testing.T) { | |||
| 122 | assert.NilError(t, err) | 122 | assert.NilError(t, err) |
| 123 | 123 | ||
| 124 | var count int | 124 | var count int |
| 125 | - err = dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_similarity`).Scan(&count) | 125 | + err = dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_similarity`).Scan(&count) |
| 126 | assert.NilError(t, err) | 126 | assert.NilError(t, err) |
| 127 | assert.Assert(t, count > 0, "expected user similarity pairs") | 127 | assert.Assert(t, count > 0, "expected user similarity pairs") |
| 128 | } | 128 | } |
| @@ -224,14 +224,14 @@ func TestRecordImpressions(t *testing.T) { | |||
| 224 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) | 224 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) |
| 225 | 225 | ||
| 226 | var count int | 226 | var count int |
| 227 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 227 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 228 | `SELECT COUNT(*) FROM main.recommendation_impressions WHERE user_did = 'did:test:alice'`).Scan(&count)) | 228 | `SELECT COUNT(*) FROM main.recommendation_impressions WHERE user_did = 'did:test:alice'`).Scan(&count)) |
| 229 | assert.Equal(t, count, 2) | 229 | assert.Equal(t, count, 2) |
| 230 | 230 | ||
| 231 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) | 231 | assert.NilError(t, engine.RecordImpressions(ctx, "did:test:alice", impressions)) |
| 232 | 232 | ||
| 233 | var shownCount int | 233 | var shownCount int |
| 234 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 234 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 235 | `SELECT shown_count FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&shownCount)) | 235 | `SELECT shown_count FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&shownCount)) |
| 236 | assert.Equal(t, shownCount, 2, "shown_count should increment on repeated impression") | 236 | assert.Equal(t, shownCount, 2, "shown_count should increment on repeated impression") |
| 237 | } | 237 | } |
| @@ -249,7 +249,7 @@ func TestMarkImpressionActed(t *testing.T) { | |||
| 249 | assert.NilError(t, engine.MarkImpressionActed(ctx, "did:test:alice", "feed", "https://a.com/feed")) | 249 | assert.NilError(t, engine.MarkImpressionActed(ctx, "did:test:alice", "feed", "https://a.com/feed")) |
| 250 | 250 | ||
| 251 | var acted bool | 251 | var acted bool |
| 252 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 252 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 253 | `SELECT acted FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&acted)) | 253 | `SELECT acted FROM main.recommendation_impressions WHERE user_did = 'did:test:alice' AND target_id = 'https://a.com/feed'`).Scan(&acted)) |
| 254 | assert.Assert(t, acted, "impression should be marked as acted") | 254 | assert.Assert(t, acted, "impression should be marked as acted") |
| 255 | } | 255 | } |
| @@ -264,22 +264,22 @@ func TestComputeFollowDistances(t *testing.T) { | |||
| 264 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) | 264 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) |
| 265 | 265 | ||
| 266 | var d1, d2, d3 int | 266 | var d1, d2, d3 int |
| 267 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 267 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 268 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 1`).Scan(&d1)) | 268 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 1`).Scan(&d1)) |
| 269 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 269 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 270 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 2`).Scan(&d2)) | 270 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 2`).Scan(&d2)) |
| 271 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 271 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 272 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 3`).Scan(&d3)) | 272 | `SELECT COUNT(*) FROM recs.follow_distances WHERE distance = 3`).Scan(&d3)) |
| 273 | assert.Assert(t, d1 >= 3, "expected at least 3 direct follow distances") | 273 | assert.Assert(t, d1 >= 3, "expected at least 3 direct follow distances") |
| 274 | assert.Assert(t, d2 >= 1, "expected at least 1 two-hop distance (alice -> bob -> carol)") | 274 | assert.Assert(t, d2 >= 1, "expected at least 1 two-hop distance (alice -> bob -> carol)") |
| 275 | assert.Assert(t, d3 >= 1, "expected at least 1 three-hop distance (alice -> bob -> carol -> dave)") | 275 | assert.Assert(t, d3 >= 1, "expected at least 1 three-hop distance (alice -> bob -> carol -> dave)") |
| 276 | 276 | ||
| 277 | var exists int | 277 | var exists int |
| 278 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 278 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 279 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:carol'`).Scan(&exists)) | 279 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:carol'`).Scan(&exists)) |
| 280 | assert.Assert(t, exists == 1, "alice should reach carol") | 280 | assert.Assert(t, exists == 1, "alice should reach carol") |
| 281 | 281 | ||
| 282 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 282 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 283 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:dave'`).Scan(&exists)) | 283 | `SELECT COUNT(*) FROM recs.follow_distances WHERE user_a = 'did:test:alice' AND user_b = 'did:test:dave'`).Scan(&exists)) |
| 284 | assert.Assert(t, exists == 1, "alice should reach dave via 3 hops") | 284 | assert.Assert(t, exists == 1, "alice should reach dave via 3 hops") |
| 285 | } | 285 | } |
| @@ -300,7 +300,7 @@ func TestComputeFollowDistancesData_SplitReadWrite(t *testing.T) { | |||
| 300 | assert.NilError(t, engine.WriteFollowDistances(ctx, distances)) | 300 | assert.NilError(t, engine.WriteFollowDistances(ctx, distances)) |
| 301 | 301 | ||
| 302 | var count int | 302 | var count int |
| 303 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.follow_distances`).Scan(&count)) | 303 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.follow_distances`).Scan(&count)) |
| 304 | assert.Equal(t, count, len(distances)) | 304 | assert.Equal(t, count, len(distances)) |
| 305 | } | 305 | } |
| 306 | 306 | ||
| @@ -311,7 +311,7 @@ func TestAutoDismissStale(t *testing.T) { | |||
| 311 | 311 | ||
| 312 | engine := newTestEngine(dbs) | 312 | engine := newTestEngine(dbs) |
| 313 | 313 | ||
| 314 | - _, err := dbs.DB().ExecContext(ctx, ` | 314 | + _, err := dbs.SQLDB().ExecContext(ctx, ` |
| 315 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) | 315 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 316 | VALUES ('did:test:alice', 'feed', 'https://stale.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 0) | 316 | VALUES ('did:test:alice', 'feed', 'https://stale.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 0) |
| 317 | `) | 317 | `) |
| @@ -331,7 +331,7 @@ func TestAutoDismissStale_DoesNotDismissRecent(t *testing.T) { | |||
| 331 | 331 | ||
| 332 | engine := newTestEngine(dbs) | 332 | engine := newTestEngine(dbs) |
| 333 | 333 | ||
| 334 | - _, err := dbs.DB().ExecContext(ctx, ` | 334 | + _, err := dbs.SQLDB().ExecContext(ctx, ` |
| 335 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) | 335 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 336 | VALUES ('did:test:alice', 'feed', 'https://recent.com/feed', datetime('now'), datetime('now'), 5, 0) | 336 | VALUES ('did:test:alice', 'feed', 'https://recent.com/feed', datetime('now'), datetime('now'), 5, 0) |
| 337 | `) | 337 | `) |
| @@ -351,7 +351,7 @@ func TestAutoDismissStale_DoesNotDismissActed(t *testing.T) { | |||
| 351 | 351 | ||
| 352 | engine := newTestEngine(dbs) | 352 | engine := newTestEngine(dbs) |
| 353 | 353 | ||
| 354 | - _, err := dbs.DB().ExecContext(ctx, ` | 354 | + _, err := dbs.SQLDB().ExecContext(ctx, ` |
| 355 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) | 355 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 356 | VALUES ('did:test:alice', 'feed', 'https://acted.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 1) | 356 | VALUES ('did:test:alice', 'feed', 'https://acted.com/feed', datetime('now', '-6 days'), datetime('now'), 6, 1) |
| 357 | `) | 357 | `) |
| @@ -427,13 +427,13 @@ func TestSignalWeights_RewardPenalize(t *testing.T) { | |||
| 427 | 427 | ||
| 428 | engine := newTestEngine(dbs) | 428 | engine := newTestEngine(dbs) |
| 429 | 429 | ||
| 430 | - _, err := dbs.DB().ExecContext(ctx, ` | 430 | + _, err := dbs.SQLDB().ExecContext(ctx, ` |
| 431 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) | 431 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 432 | VALUES ('did:test:alice', 'feed', 'https://a.com/feed', datetime('now'), datetime('now'), 1, 1) | 432 | VALUES ('did:test:alice', 'feed', 'https://a.com/feed', datetime('now'), datetime('now'), 1, 1) |
| 433 | `) | 433 | `) |
| 434 | assert.NilError(t, err) | 434 | assert.NilError(t, err) |
| 435 | for i := range minActionsTune { | 435 | for i := range minActionsTune { |
| 436 | - _, err = dbs.DB().ExecContext(ctx, ` | 436 | + _, err = dbs.SQLDB().ExecContext(ctx, ` |
| 437 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) | 437 | INSERT INTO main.recommendation_impressions (user_did, target_type, target_id, first_shown_at, last_shown_at, shown_count, acted) |
| 438 | VALUES ('did:test:alice', 'feed', ?, datetime('now'), datetime('now'), 1, 1) | 438 | VALUES ('did:test:alice', 'feed', ?, datetime('now'), datetime('now'), 1, 1) |
| 439 | `, fmt.Sprintf("https://%d.com/feed", i)) | 439 | `, fmt.Sprintf("https://%d.com/feed", i)) |
| @@ -455,12 +455,12 @@ func TestColdStartRecommendations(t *testing.T) { | |||
| 455 | engine := newTestEngine(dbs) | 455 | engine := newTestEngine(dbs) |
| 456 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) | 456 | assert.NilError(t, engine.ComputeFollowDistances(ctx)) |
| 457 | 457 | ||
| 458 | - _, err := dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://a.com/feed'`) | 458 | + _, err := dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://a.com/feed'`) |
| 459 | assert.NilError(t, err) | 459 | assert.NilError(t, err) |
| 460 | - _, err = dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://b.com/feed'`) | 460 | + _, err = dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET subscriber_count = 2 WHERE feed_url = 'https://b.com/feed'`) |
| 461 | assert.NilError(t, err) | 461 | assert.NilError(t, err) |
| 462 | 462 | ||
| 463 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | 463 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") |
| 464 | assert.NilError(t, err) | 464 | assert.NilError(t, err) |
| 465 | 465 | ||
| 466 | recs, err := engine.ColdStartRecommendations(ctx, "did:test:newuser", 10) | 466 | recs, err := engine.ColdStartRecommendations(ctx, "did:test:newuser", 10) |
| @@ -505,7 +505,7 @@ func TestDismissArticle(t *testing.T) { | |||
| 505 | assert.NilError(t, engine.DismissArticle(ctx, "did:test:alice", "https://a.com/article1", "not_interested")) | 505 | assert.NilError(t, engine.DismissArticle(ctx, "did:test:alice", "https://a.com/article1", "not_interested")) |
| 506 | 506 | ||
| 507 | var count int | 507 | var count int |
| 508 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 508 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 509 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'article'`).Scan(&count)) | 509 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'article'`).Scan(&count)) |
| 510 | assert.Equal(t, count, 1) | 510 | assert.Equal(t, count, 1) |
| 511 | } | 511 | } |
| @@ -519,7 +519,7 @@ func TestComputeSignalProfiles(t *testing.T) { | |||
| 519 | assert.NilError(t, engine.ComputeSignalProfiles(ctx)) | 519 | assert.NilError(t, engine.ComputeSignalProfiles(ctx)) |
| 520 | 520 | ||
| 521 | var count int | 521 | var count int |
| 522 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_signal_profiles`).Scan(&count)) | 522 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.user_signal_profiles`).Scan(&count)) |
| 523 | assert.Assert(t, count >= 3, "expected signal profiles for all users") | 523 | assert.Assert(t, count >= 3, "expected signal profiles for all users") |
| 524 | } | 524 | } |
| 525 | 525 | ||
| @@ -534,7 +534,7 @@ func TestDismissFeed_Idempotent(t *testing.T) { | |||
| 534 | assert.NilError(t, engine.DismissFeed(ctx, "did:test:alice", "https://a.com/feed", "reason2")) | 534 | assert.NilError(t, engine.DismissFeed(ctx, "did:test:alice", "https://a.com/feed", "reason2")) |
| 535 | 535 | ||
| 536 | var count int | 536 | var count int |
| 537 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 537 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 538 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'feed'`).Scan(&count)) | 538 | `SELECT COUNT(*) FROM main.dismissed_recommendations WHERE user_did = 'did:test:alice' AND target_type = 'feed'`).Scan(&count)) |
| 539 | assert.Equal(t, count, 1, "duplicate dismiss should not create extra rows") | 539 | assert.Equal(t, count, 1, "duplicate dismiss should not create extra rows") |
| 540 | } | 540 | } |
| @@ -543,25 +543,25 @@ func TestEmbeddingBasedFeedSimilarity(t *testing.T) { | |||
| 543 | ctx := context.Background() | 543 | ctx := context.Background() |
| 544 | dbs := setupClusterTestDB(t) | 544 | dbs := setupClusterTestDB(t) |
| 545 | 545 | ||
| 546 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | 546 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") |
| 547 | assert.NilError(t, err) | 547 | assert.NilError(t, err) |
| 548 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | 548 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") |
| 549 | assert.NilError(t, err) | 549 | assert.NilError(t, err) |
| 550 | 550 | ||
| 551 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | 551 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, |
| 552 | "https://go.com/feed", "Go Blog", "https://go.com", "programming language golang software development") | 552 | "https://go.com/feed", "Go Blog", "https://go.com", "programming language golang software development") |
| 553 | assert.NilError(t, err) | 553 | assert.NilError(t, err) |
| 554 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | 554 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, |
| 555 | "https://rust.com/feed", "Rust Blog", "https://rust.com", "programming language rust software development") | 555 | "https://rust.com/feed", "Rust Blog", "https://rust.com", "programming language rust software development") |
| 556 | assert.NilError(t, err) | 556 | assert.NilError(t, err) |
| 557 | 557 | ||
| 558 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://go.com/feed") | 558 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://go.com/feed") |
| 559 | assert.NilError(t, err) | 559 | assert.NilError(t, err) |
| 560 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://rust.com/feed") | 560 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:alice", "https://rust.com/feed") |
| 561 | assert.NilError(t, err) | 561 | assert.NilError(t, err) |
| 562 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://go.com/feed") | 562 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://go.com/feed") |
| 563 | assert.NilError(t, err) | 563 | assert.NilError(t, err) |
| 564 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://rust.com/feed") | 564 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, CURRENT_TIMESTAMP)`, "did:test:bob", "https://rust.com/feed") |
| 565 | assert.NilError(t, err) | 565 | assert.NilError(t, err) |
| 566 | 566 | ||
| 567 | engine := newTestEngine(dbs) | 567 | engine := newTestEngine(dbs) |
| @@ -570,7 +570,7 @@ func TestEmbeddingBasedFeedSimilarity(t *testing.T) { | |||
| 570 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) | 570 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) |
| 571 | 571 | ||
| 572 | var jaccard float64 | 572 | var jaccard float64 |
| 573 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 573 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 574 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = ? AND feed_b = ?`, | 574 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = ? AND feed_b = ?`, |
| 575 | "https://go.com/feed", "https://rust.com/feed").Scan(&jaccard)) | 575 | "https://go.com/feed", "https://rust.com/feed").Scan(&jaccard)) |
| 576 | assert.Assert(t, jaccard > 1.0, "embedding cosine similarity should boost feed similarity above pure Jaccard") | 576 | assert.Assert(t, jaccard > 1.0, "embedding cosine similarity should boost feed similarity above pure Jaccard") |
| @@ -610,17 +610,17 @@ func TestComputeArticleEmbeddings(t *testing.T) { | |||
| 610 | ctx := context.Background() | 610 | ctx := context.Background() |
| 611 | dbs := setupClusterTestDB(t) | 611 | dbs := setupClusterTestDB(t) |
| 612 | 612 | ||
| 613 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 1)`, | 613 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 1)`, |
| 614 | "https://tech.com/feed", "Tech Feed", "https://tech.com") | 614 | "https://tech.com/feed", "Tech Feed", "https://tech.com") |
| 615 | assert.NilError(t, err) | 615 | assert.NilError(t, err) |
| 616 | 616 | ||
| 617 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | 617 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, |
| 618 | "https://tech.com/feed", "1", "golang programming language tutorial", "learn the go programming language for backend development", "https://tech.com/go") | 618 | "https://tech.com/feed", "1", "golang programming language tutorial", "learn the go programming language for backend development", "https://tech.com/go") |
| 619 | assert.NilError(t, err) | 619 | assert.NilError(t, err) |
| 620 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | 620 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, |
| 621 | "https://tech.com/feed", "2", "rust programming language guide", "learn the rust programming language for systems development", "https://tech.com/rust") | 621 | "https://tech.com/feed", "2", "rust programming language guide", "learn the rust programming language for systems development", "https://tech.com/rust") |
| 622 | assert.NilError(t, err) | 622 | assert.NilError(t, err) |
| 623 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, | 623 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url) VALUES (?, ?, ?, ?, ?)`, |
| 624 | "https://tech.com/feed", "3", "cooking recipes for dinner", "easy dinner recipes for the whole family", "https://tech.com/cook") | 624 | "https://tech.com/feed", "3", "cooking recipes for dinner", "easy dinner recipes for the whole family", "https://tech.com/cook") |
| 625 | assert.NilError(t, err) | 625 | assert.NilError(t, err) |
| 626 | 626 | ||
| @@ -629,7 +629,7 @@ func TestComputeArticleEmbeddings(t *testing.T) { | |||
| 629 | assert.NilError(t, engine.ComputeArticleEmbeddings(ctx)) | 629 | assert.NilError(t, engine.ComputeArticleEmbeddings(ctx)) |
| 630 | 630 | ||
| 631 | var count int | 631 | var count int |
| 632 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.article_embeddings`).Scan(&count)) | 632 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.article_embeddings`).Scan(&count)) |
| 633 | assert.Equal(t, count, 3, "expected 3 article embeddings") | 633 | assert.Equal(t, count, 3, "expected 3 article embeddings") |
| 634 | } | 634 | } |
| 635 | 635 | ||
| @@ -637,44 +637,44 @@ func TestArticleRecommendationsWithContentBoost(t *testing.T) { | |||
| 637 | ctx := context.Background() | 637 | ctx := context.Background() |
| 638 | dbs := setupClusterTestDB(t) | 638 | dbs := setupClusterTestDB(t) |
| 639 | 639 | ||
| 640 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | 640 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") |
| 641 | assert.NilError(t, err) | 641 | assert.NilError(t, err) |
| 642 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | 642 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") |
| 643 | assert.NilError(t, err) | 643 | assert.NilError(t, err) |
| 644 | 644 | ||
| 645 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | 645 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, |
| 646 | "https://tech.com/feed", "Tech Feed", "https://tech.com") | 646 | "https://tech.com/feed", "Tech Feed", "https://tech.com") |
| 647 | assert.NilError(t, err) | 647 | assert.NilError(t, err) |
| 648 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | 648 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, |
| 649 | "https://dev.com/feed", "Dev Feed", "https://dev.com") | 649 | "https://dev.com/feed", "Dev Feed", "https://dev.com") |
| 650 | assert.NilError(t, err) | 650 | assert.NilError(t, err) |
| 651 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | 651 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, |
| 652 | "https://shared.com/feed", "Shared Feed", "https://shared.com") | 652 | "https://shared.com/feed", "Shared Feed", "https://shared.com") |
| 653 | assert.NilError(t, err) | 653 | assert.NilError(t, err) |
| 654 | 654 | ||
| 655 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://tech.com/feed") | 655 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://tech.com/feed") |
| 656 | assert.NilError(t, err) | 656 | assert.NilError(t, err) |
| 657 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://shared.com/feed") | 657 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:alice", "https://shared.com/feed") |
| 658 | assert.NilError(t, err) | 658 | assert.NilError(t, err) |
| 659 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://dev.com/feed") | 659 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://dev.com/feed") |
| 660 | assert.NilError(t, err) | 660 | assert.NilError(t, err) |
| 661 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://shared.com/feed") | 661 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, "did:test:bob", "https://shared.com/feed") |
| 662 | assert.NilError(t, err) | 662 | assert.NilError(t, err) |
| 663 | 663 | ||
| 664 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | 664 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, |
| 665 | "https://tech.com/feed", "1", "golang programming tutorial", "learn go programming", "https://tech.com/go") | 665 | "https://tech.com/feed", "1", "golang programming tutorial", "learn go programming", "https://tech.com/go") |
| 666 | assert.NilError(t, err) | 666 | assert.NilError(t, err) |
| 667 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | 667 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, |
| 668 | "https://dev.com/feed", "2", "rust programming tutorial", "learn rust programming", "https://dev.com/rust") | 668 | "https://dev.com/feed", "2", "rust programming tutorial", "learn rust programming", "https://dev.com/rust") |
| 669 | assert.NilError(t, err) | 669 | assert.NilError(t, err) |
| 670 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, | 670 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, summary, url, published) VALUES (?, ?, ?, ?, ?, datetime('now'))`, |
| 671 | "https://dev.com/feed", "3", "cooking dinner recipes", "easy dinner recipes", "https://dev.com/cook") | 671 | "https://dev.com/feed", "3", "cooking dinner recipes", "easy dinner recipes", "https://dev.com/cook") |
| 672 | assert.NilError(t, err) | 672 | assert.NilError(t, err) |
| 673 | 673 | ||
| 674 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | 674 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, |
| 675 | "at://alice/like/1", "did:test:alice", "https://tech.com/feed", "https://tech.com/go") | 675 | "at://alice/like/1", "did:test:alice", "https://tech.com/feed", "https://tech.com/go") |
| 676 | assert.NilError(t, err) | 676 | assert.NilError(t, err) |
| 677 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, | 677 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.likes (uri, author_did, feed_url, article_url, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, |
| 678 | "at://bob/like/1", "did:test:bob", "https://dev.com/feed", "https://dev.com/rust") | 678 | "at://bob/like/1", "did:test:bob", "https://dev.com/feed", "https://dev.com/rust") |
| 679 | assert.NilError(t, err) | 679 | assert.NilError(t, err) |
| 680 | 680 | ||
| @@ -693,7 +693,7 @@ func TestFeedEmbeddingRecomputedOnDescriptionChange(t *testing.T) { | |||
| 693 | ctx := context.Background() | 693 | ctx := context.Background() |
| 694 | dbs := setupClusterTestDB(t) | 694 | dbs := setupClusterTestDB(t) |
| 695 | 695 | ||
| 696 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type) VALUES (?, ?, ?, ?, 'rss')`, | 696 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type) VALUES (?, ?, ?, ?, 'rss')`, |
| 697 | "https://go.com/feed", "Go Blog", "https://go.com", "old description") | 697 | "https://go.com/feed", "Go Blog", "https://go.com", "old description") |
| 698 | assert.NilError(t, err) | 698 | assert.NilError(t, err) |
| 699 | 699 | ||
| @@ -702,16 +702,16 @@ func TestFeedEmbeddingRecomputedOnDescriptionChange(t *testing.T) { | |||
| 702 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) | 702 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) |
| 703 | 703 | ||
| 704 | var count int | 704 | var count int |
| 705 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_embeddings`).Scan(&count)) | 705 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT COUNT(*) FROM recs.feed_embeddings`).Scan(&count)) |
| 706 | assert.Equal(t, count, 1) | 706 | assert.Equal(t, count, 1) |
| 707 | 707 | ||
| 708 | - _, err = dbs.DB().ExecContext(ctx, `UPDATE articles.feeds SET description = 'new description' WHERE feed_url = 'https://go.com/feed'`) | 708 | + _, err = dbs.SQLDB().ExecContext(ctx, `UPDATE articles.feeds SET description = 'new description' WHERE feed_url = 'https://go.com/feed'`) |
| 709 | assert.NilError(t, err) | 709 | assert.NilError(t, err) |
| 710 | 710 | ||
| 711 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) | 711 | assert.NilError(t, engine.ComputeFeedEmbeddings(ctx)) |
| 712 | 712 | ||
| 713 | var sourceText string | 713 | var sourceText string |
| 714 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, `SELECT source_text FROM recs.feed_embedding_meta WHERE feed_url = 'https://go.com/feed'`).Scan(&sourceText)) | 714 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, `SELECT source_text FROM recs.feed_embedding_meta WHERE feed_url = 'https://go.com/feed'`).Scan(&sourceText)) |
| 715 | assert.Assert(t, sourceText == "Go Blog new description", "embedding should be recomputed when description changes, got: %s", sourceText) | 715 | assert.Assert(t, sourceText == "Go Blog new description", "embedding should be recomputed when description changes, got: %s", sourceText) |
| 716 | } | 716 | } |
| 717 | 717 | ||
| @@ -719,28 +719,28 @@ func TestTimeDecayedFeedSimilarity(t *testing.T) { | |||
| 719 | ctx := context.Background() | 719 | ctx := context.Background() |
| 720 | dbs := setupClusterTestDB(t) | 720 | dbs := setupClusterTestDB(t) |
| 721 | 721 | ||
| 722 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") | 722 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:alice") |
| 723 | assert.NilError(t, err) | 723 | assert.NilError(t, err) |
| 724 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") | 724 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:bob") |
| 725 | assert.NilError(t, err) | 725 | assert.NilError(t, err) |
| 726 | 726 | ||
| 727 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | 727 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, |
| 728 | "https://a.com/feed", "Feed A", "https://a.com") | 728 | "https://a.com/feed", "Feed A", "https://a.com") |
| 729 | assert.NilError(t, err) | 729 | assert.NilError(t, err) |
| 730 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, | 730 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, feed_type, subscriber_count) VALUES (?, ?, ?, 'rss', 2)`, |
| 731 | "https://b.com/feed", "Feed B", "https://b.com") | 731 | "https://b.com/feed", "Feed B", "https://b.com") |
| 732 | assert.NilError(t, err) | 732 | assert.NilError(t, err) |
| 733 | 733 | ||
| 734 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now', '-60 days'))`, | 734 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now', '-60 days'))`, |
| 735 | "did:test:alice", "https://a.com/feed") | 735 | "did:test:alice", "https://a.com/feed") |
| 736 | assert.NilError(t, err) | 736 | assert.NilError(t, err) |
| 737 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | 737 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, |
| 738 | "did:test:bob", "https://a.com/feed") | 738 | "did:test:bob", "https://a.com/feed") |
| 739 | assert.NilError(t, err) | 739 | assert.NilError(t, err) |
| 740 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | 740 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, |
| 741 | "did:test:alice", "https://b.com/feed") | 741 | "did:test:alice", "https://b.com/feed") |
| 742 | assert.NilError(t, err) | 742 | assert.NilError(t, err) |
| 743 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, | 743 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url, added_at) VALUES (?, ?, datetime('now'))`, |
| 744 | "did:test:bob", "https://b.com/feed") | 744 | "did:test:bob", "https://b.com/feed") |
| 745 | assert.NilError(t, err) | 745 | assert.NilError(t, err) |
| 746 | 746 | ||
| @@ -748,7 +748,7 @@ func TestTimeDecayedFeedSimilarity(t *testing.T) { | |||
| 748 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) | 748 | assert.NilError(t, engine.ComputeFeedSimilarity(ctx)) |
| 749 | 749 | ||
| 750 | var jaccard float64 | 750 | var jaccard float64 |
| 751 | - assert.NilError(t, dbs.DB().QueryRowContext(ctx, | 751 | + assert.NilError(t, dbs.SQLDB().QueryRowContext(ctx, |
| 752 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = 'https://a.com/feed' AND feed_b = 'https://b.com/feed'`).Scan(&jaccard)) | 752 | `SELECT jaccard FROM recs.feed_similarity WHERE feed_a = 'https://a.com/feed' AND feed_b = 'https://b.com/feed'`).Scan(&jaccard)) |
| 753 | assert.Assert(t, jaccard > 0, "time-decayed feed similarity should be positive") | 753 | assert.Assert(t, jaccard > 0, "time-decayed feed similarity should be positive") |
| 754 | assert.Assert(t, jaccard < 1.0, "time decay should reduce similarity below raw Jaccard") | 754 | assert.Assert(t, jaccard < 1.0, "time decay should reduce similarity below raw Jaccard") |
| @@ -758,20 +758,20 @@ func TestColdStartFromEmbeddings(t *testing.T) { | |||
| 758 | ctx := context.Background() | 758 | ctx := context.Background() |
| 759 | dbs := setupClusterTestDB(t) | 759 | dbs := setupClusterTestDB(t) |
| 760 | 760 | ||
| 761 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") | 761 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, "did:test:newuser") |
| 762 | assert.NilError(t, err) | 762 | assert.NilError(t, err) |
| 763 | 763 | ||
| 764 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | 764 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, |
| 765 | "https://go.com/feed", "Go Blog", "https://go.com", "golang programming language") | 765 | "https://go.com/feed", "Go Blog", "https://go.com", "golang programming language") |
| 766 | assert.NilError(t, err) | 766 | assert.NilError(t, err) |
| 767 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | 767 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, |
| 768 | "https://godev.com/feed", "Go Dev", "https://godev.com", "golang development tutorials") | 768 | "https://godev.com/feed", "Go Dev", "https://godev.com", "golang development tutorials") |
| 769 | assert.NilError(t, err) | 769 | assert.NilError(t, err) |
| 770 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, | 770 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title, site_url, description, feed_type, subscriber_count) VALUES (?, ?, ?, ?, 'rss', 2)`, |
| 771 | "https://cooking.com/feed", "Cooking", "https://cooking.com", "recipes for dinner") | 771 | "https://cooking.com/feed", "Cooking", "https://cooking.com", "recipes for dinner") |
| 772 | assert.NilError(t, err) | 772 | assert.NilError(t, err) |
| 773 | 773 | ||
| 774 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, | 774 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, |
| 775 | "did:test:newuser", "https://go.com/feed") | 775 | "did:test:newuser", "https://go.com/feed") |
| 776 | assert.NilError(t, err) | 776 | assert.NilError(t, err) |
| 777 | 777 | ||
modified
internal/db/article.go +1 -1 | @@ -51,7 +51,7 @@ type ReadState struct { | ||
| 51 | 51 | ReadAt sql.NullTime |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | -func (s *ArticleStore) UpsertArticlesBatch(ctx context.Context, articles []feed.Article) error { | |
| 54 | +func (s *ArticleStore) BatchUpsertArticles(ctx context.Context, articles []feed.Article) error { | |
| 55 | 55 | if len(articles) == 0 { |
| 56 | 56 | return nil |
| 57 | 57 | } |
| @@ -51,7 +51,7 @@ type ReadState struct { | |||
| 51 | ReadAt sql.NullTime | 51 | ReadAt sql.NullTime |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | -func (s *ArticleStore) UpsertArticlesBatch(ctx context.Context, articles []feed.Article) error { | 54 | +func (s *ArticleStore) BatchUpsertArticles(ctx context.Context, articles []feed.Article) error { |
| 55 | if len(articles) == 0 { | 55 | if len(articles) == 0 { |
| 56 | return nil | 56 | return nil |
| 57 | } | 57 | } |
modified
internal/db/article_test.go +15 -15 | @@ -9,7 +9,7 @@ import ( | ||
| 9 | 9 | "gotest.tools/v3/assert" |
| 10 | 10 | ) |
| 11 | 11 | |
| 12 | -func setupTestDB(t *testing.T) *Databases { | |
| 12 | +func setupTestDB(t *testing.T) *Store { | |
| 13 | 13 | t.Helper() |
| 14 | 14 | f, err := os.CreateTemp("", "glean-test-*.db") |
| 15 | 15 | assert.NilError(t, err) |
| @@ -21,33 +21,33 @@ func setupTestDB(t *testing.T) *Databases { | ||
| 21 | 21 | } |
| 22 | 22 | }) |
| 23 | 23 | |
| 24 | - dbs, err := OpenAll(path) | |
| 24 | + dbs, err := Open(path) | |
| 25 | 25 | assert.NilError(t, err) |
| 26 | 26 | t.Cleanup(func() { _ = dbs.Close() }) |
| 27 | 27 | return dbs |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | -func seedArticleReadState(t *testing.T, ctx context.Context, dbs *Databases) (userDID string, feedURL string, readArticleID, unreadArticleID int64) { | |
| 30 | +func seedArticleReadState(t *testing.T, ctx context.Context, dbs *Store) (userDID string, feedURL string, readArticleID, unreadArticleID int64) { | |
| 31 | 31 | t.Helper() |
| 32 | 32 | |
| 33 | 33 | userDID = "did:test:user1" |
| 34 | 34 | feedURL = "https://example.com/feed.xml" |
| 35 | 35 | |
| 36 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 36 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 37 | 37 | assert.NilError(t, err) |
| 38 | 38 | |
| 39 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Test Feed") | |
| 39 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Test Feed") | |
| 40 | 40 | assert.NilError(t, err) |
| 41 | 41 | |
| 42 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | |
| 42 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | |
| 43 | 43 | assert.NilError(t, err) |
| 44 | 44 | |
| 45 | - res, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | |
| 45 | + res, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | |
| 46 | 46 | feedURL, "guid-read", "Read Article", "https://example.com/read") |
| 47 | 47 | assert.NilError(t, err) |
| 48 | 48 | readArticleID, _ = res.LastInsertId() |
| 49 | 49 | |
| 50 | - res, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | |
| 50 | + res, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | |
| 51 | 51 | feedURL, "guid-unread", "Unread Article", "https://example.com/unread") |
| 52 | 52 | assert.NilError(t, err) |
| 53 | 53 | unreadArticleID, _ = res.LastInsertId() |
| @@ -190,19 +190,19 @@ func TestGetArticle_IncludesFullContent(t *testing.T) { | ||
| 190 | 190 | assert.Assert(t, !article.FullContent.Valid) |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | -func seedSearchData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, feedURL string) { | |
| 193 | +func seedSearchData(t *testing.T, ctx context.Context, dbs *Store) (userDID, feedURL string) { | |
| 194 | 194 | t.Helper() |
| 195 | 195 | |
| 196 | 196 | userDID = "did:test:searcher" |
| 197 | 197 | feedURL = "https://search.example.com/feed.xml" |
| 198 | 198 | |
| 199 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 199 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 200 | 200 | assert.NilError(t, err) |
| 201 | 201 | |
| 202 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Tech Blog") | |
| 202 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Tech Blog") | |
| 203 | 203 | assert.NilError(t, err) |
| 204 | 204 | |
| 205 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | |
| 205 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | |
| 206 | 206 | assert.NilError(t, err) |
| 207 | 207 | |
| 208 | 208 | articles := []struct { |
| @@ -213,7 +213,7 @@ func seedSearchData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, | ||
| 213 | 213 | {"g3", "Python Data Science", "NumPy and Pandas tutorial", "Python is popular for data analysis"}, |
| 214 | 214 | } |
| 215 | 215 | for _, a := range articles { |
| 216 | - _, err := dbs.DB().ExecContext(ctx, ` | |
| 216 | + _, err := dbs.SQLDB().ExecContext(ctx, ` | |
| 217 | 217 | INSERT INTO articles.articles (feed_url, guid, title, summary, content) VALUES (?, ?, ?, ?, ?) |
| 218 | 218 | `, feedURL, a.guid, a.title, a.summary, a.content) |
| 219 | 219 | assert.NilError(t, err) |
| @@ -289,10 +289,10 @@ func TestSearchArticles_ScopedToSubscriptions(t *testing.T) { | ||
| 289 | 289 | userDID, feedURL := seedSearchData(t, ctx, dbs) |
| 290 | 290 | |
| 291 | 291 | otherFeed := "https://other.example.com/feed.xml" |
| 292 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, otherFeed, "Other Feed") | |
| 292 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, otherFeed, "Other Feed") | |
| 293 | 293 | assert.NilError(t, err) |
| 294 | 294 | |
| 295 | - _, err = dbs.DB().ExecContext(ctx, ` | |
| 295 | + _, err = dbs.SQLDB().ExecContext(ctx, ` | |
| 296 | 296 | INSERT INTO articles.articles (feed_url, guid, title) VALUES (?, ?, ?) |
| 297 | 297 | `, otherFeed, "other-1", "Go Concurrency Tips") |
| 298 | 298 | assert.NilError(t, err) |
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | "gotest.tools/v3/assert" | 9 | "gotest.tools/v3/assert" |
| 10 | ) | 10 | ) |
| 11 | 11 | ||
| 12 | -func setupTestDB(t *testing.T) *Databases { | 12 | +func setupTestDB(t *testing.T) *Store { |
| 13 | t.Helper() | 13 | t.Helper() |
| 14 | f, err := os.CreateTemp("", "glean-test-*.db") | 14 | f, err := os.CreateTemp("", "glean-test-*.db") |
| 15 | assert.NilError(t, err) | 15 | assert.NilError(t, err) |
| @@ -21,33 +21,33 @@ func setupTestDB(t *testing.T) *Databases { | |||
| 21 | } | 21 | } |
| 22 | }) | 22 | }) |
| 23 | 23 | ||
| 24 | - dbs, err := OpenAll(path) | 24 | + dbs, err := Open(path) |
| 25 | assert.NilError(t, err) | 25 | assert.NilError(t, err) |
| 26 | t.Cleanup(func() { _ = dbs.Close() }) | 26 | t.Cleanup(func() { _ = dbs.Close() }) |
| 27 | return dbs | 27 | return dbs |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | -func seedArticleReadState(t *testing.T, ctx context.Context, dbs *Databases) (userDID string, feedURL string, readArticleID, unreadArticleID int64) { | 30 | +func seedArticleReadState(t *testing.T, ctx context.Context, dbs *Store) (userDID string, feedURL string, readArticleID, unreadArticleID int64) { |
| 31 | t.Helper() | 31 | t.Helper() |
| 32 | 32 | ||
| 33 | userDID = "did:test:user1" | 33 | userDID = "did:test:user1" |
| 34 | feedURL = "https://example.com/feed.xml" | 34 | feedURL = "https://example.com/feed.xml" |
| 35 | 35 | ||
| 36 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | 36 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) |
| 37 | assert.NilError(t, err) | 37 | assert.NilError(t, err) |
| 38 | 38 | ||
| 39 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Test Feed") | 39 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Test Feed") |
| 40 | assert.NilError(t, err) | 40 | assert.NilError(t, err) |
| 41 | 41 | ||
| 42 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | 42 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) |
| 43 | assert.NilError(t, err) | 43 | assert.NilError(t, err) |
| 44 | 44 | ||
| 45 | - res, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | 45 | + res, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, |
| 46 | feedURL, "guid-read", "Read Article", "https://example.com/read") | 46 | feedURL, "guid-read", "Read Article", "https://example.com/read") |
| 47 | assert.NilError(t, err) | 47 | assert.NilError(t, err) |
| 48 | readArticleID, _ = res.LastInsertId() | 48 | readArticleID, _ = res.LastInsertId() |
| 49 | 49 | ||
| 50 | - res, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, | 50 | + res, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.articles (feed_url, guid, title, url) VALUES (?, ?, ?, ?)`, |
| 51 | feedURL, "guid-unread", "Unread Article", "https://example.com/unread") | 51 | feedURL, "guid-unread", "Unread Article", "https://example.com/unread") |
| 52 | assert.NilError(t, err) | 52 | assert.NilError(t, err) |
| 53 | unreadArticleID, _ = res.LastInsertId() | 53 | unreadArticleID, _ = res.LastInsertId() |
| @@ -190,19 +190,19 @@ func TestGetArticle_IncludesFullContent(t *testing.T) { | |||
| 190 | assert.Assert(t, !article.FullContent.Valid) | 190 | assert.Assert(t, !article.FullContent.Valid) |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | -func seedSearchData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, feedURL string) { | 193 | +func seedSearchData(t *testing.T, ctx context.Context, dbs *Store) (userDID, feedURL string) { |
| 194 | t.Helper() | 194 | t.Helper() |
| 195 | 195 | ||
| 196 | userDID = "did:test:searcher" | 196 | userDID = "did:test:searcher" |
| 197 | feedURL = "https://search.example.com/feed.xml" | 197 | feedURL = "https://search.example.com/feed.xml" |
| 198 | 198 | ||
| 199 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | 199 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) |
| 200 | assert.NilError(t, err) | 200 | assert.NilError(t, err) |
| 201 | 201 | ||
| 202 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Tech Blog") | 202 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, feedURL, "Tech Blog") |
| 203 | assert.NilError(t, err) | 203 | assert.NilError(t, err) |
| 204 | 204 | ||
| 205 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) | 205 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.subscriptions (user_did, feed_url) VALUES (?, ?)`, userDID, feedURL) |
| 206 | assert.NilError(t, err) | 206 | assert.NilError(t, err) |
| 207 | 207 | ||
| 208 | articles := []struct { | 208 | articles := []struct { |
| @@ -213,7 +213,7 @@ func seedSearchData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, | |||
| 213 | {"g3", "Python Data Science", "NumPy and Pandas tutorial", "Python is popular for data analysis"}, | 213 | {"g3", "Python Data Science", "NumPy and Pandas tutorial", "Python is popular for data analysis"}, |
| 214 | } | 214 | } |
| 215 | for _, a := range articles { | 215 | for _, a := range articles { |
| 216 | - _, err := dbs.DB().ExecContext(ctx, ` | 216 | + _, err := dbs.SQLDB().ExecContext(ctx, ` |
| 217 | INSERT INTO articles.articles (feed_url, guid, title, summary, content) VALUES (?, ?, ?, ?, ?) | 217 | INSERT INTO articles.articles (feed_url, guid, title, summary, content) VALUES (?, ?, ?, ?, ?) |
| 218 | `, feedURL, a.guid, a.title, a.summary, a.content) | 218 | `, feedURL, a.guid, a.title, a.summary, a.content) |
| 219 | assert.NilError(t, err) | 219 | assert.NilError(t, err) |
| @@ -289,10 +289,10 @@ func TestSearchArticles_ScopedToSubscriptions(t *testing.T) { | |||
| 289 | userDID, feedURL := seedSearchData(t, ctx, dbs) | 289 | userDID, feedURL := seedSearchData(t, ctx, dbs) |
| 290 | 290 | ||
| 291 | otherFeed := "https://other.example.com/feed.xml" | 291 | otherFeed := "https://other.example.com/feed.xml" |
| 292 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, otherFeed, "Other Feed") | 292 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO articles.feeds (feed_url, title) VALUES (?, ?)`, otherFeed, "Other Feed") |
| 293 | assert.NilError(t, err) | 293 | assert.NilError(t, err) |
| 294 | 294 | ||
| 295 | - _, err = dbs.DB().ExecContext(ctx, ` | 295 | + _, err = dbs.SQLDB().ExecContext(ctx, ` |
| 296 | INSERT INTO articles.articles (feed_url, guid, title) VALUES (?, ?, ?) | 296 | INSERT INTO articles.articles (feed_url, guid, title) VALUES (?, ?, ?) |
| 297 | `, otherFeed, "other-1", "Go Concurrency Tips") | 297 | `, otherFeed, "other-1", "Go Concurrency Tips") |
| 298 | assert.NilError(t, err) | 298 | assert.NilError(t, err) |
modified
internal/db/batch_test.go +2 -2 | @@ -47,10 +47,10 @@ func TestBatchCreateUsers_Empty(t *testing.T) { | ||
| 47 | 47 | assert.NilError(t, err) |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | -func seedSubscriptionData(t *testing.T, ctx context.Context, dbs *Databases) (userDID string) { | |
| 50 | +func seedSubscriptionData(t *testing.T, ctx context.Context, dbs *Store) (userDID string) { | |
| 51 | 51 | t.Helper() |
| 52 | 52 | userDID = "did:test:subuser" |
| 53 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 53 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 54 | 54 | assert.NilError(t, err) |
| 55 | 55 | return userDID |
| 56 | 56 | } |
| @@ -47,10 +47,10 @@ func TestBatchCreateUsers_Empty(t *testing.T) { | |||
| 47 | assert.NilError(t, err) | 47 | assert.NilError(t, err) |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | -func seedSubscriptionData(t *testing.T, ctx context.Context, dbs *Databases) (userDID string) { | 50 | +func seedSubscriptionData(t *testing.T, ctx context.Context, dbs *Store) (userDID string) { |
| 51 | t.Helper() | 51 | t.Helper() |
| 52 | userDID = "did:test:subuser" | 52 | userDID = "did:test:subuser" |
| 53 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | 53 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) |
| 54 | assert.NilError(t, err) | 54 | assert.NilError(t, err) |
| 55 | return userDID | 55 | return userDID |
| 56 | } | 56 | } |
modified
internal/db/db.go +10 -10 | @@ -16,7 +16,7 @@ type DB struct { | ||
| 16 | 16 | *sql.DB |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | -type Databases struct { | |
| 19 | +type Store struct { | |
| 20 | 20 | Users *UserStore |
| 21 | 21 | Articles *ArticleStore |
| 22 | 22 | |
| @@ -25,7 +25,7 @@ type Databases struct { | ||
| 25 | 25 | |
| 26 | 26 | var multiDriverSeq int64 |
| 27 | 27 | |
| 28 | -func OpenAll(basePath string) (*Databases, error) { | |
| 28 | +func Open(basePath string) (*Store, error) { | |
| 29 | 29 | articlesPath := basePath + "_articles" |
| 30 | 30 | recsPath := basePath + "_recs" |
| 31 | 31 | |
| @@ -113,21 +113,21 @@ func OpenAll(basePath string) (*Databases, error) { | ||
| 113 | 113 | return nil, err |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | - return &Databases{ | |
| 116 | + return &Store{ | |
| 117 | 117 | Users: NewUserStore(d), |
| 118 | 118 | Articles: NewArticleStore(d), |
| 119 | 119 | db: d, |
| 120 | 120 | }, nil |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | -func (d *Databases) Close() error { | |
| 124 | - if d.db != nil { | |
| 125 | - _ = d.db.Close() | |
| 123 | +func (s *Store) Close() error { | |
| 124 | + if s.db != nil { | |
| 125 | + _ = s.db.Close() | |
| 126 | 126 | } |
| 127 | 127 | return nil |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | -func (d *Databases) InitVecTables(dimension int) error { | |
| 130 | +func (s *Store) InitVecTables(dimension int) error { | |
| 131 | 131 | if dimension <= 0 { |
| 132 | 132 | return nil |
| 133 | 133 | } |
| @@ -135,15 +135,15 @@ func (d *Databases) InitVecTables(dimension int) error { | ||
| 135 | 135 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.feed_embeddings USING vec0(feed_url TEXT PRIMARY KEY, embedding float[%d])`, dimension), |
| 136 | 136 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.article_embeddings USING vec0(article_id INTEGER PRIMARY KEY, embedding float[%d])`, dimension), |
| 137 | 137 | } { |
| 138 | - if _, err := d.db.ExecContext(context.Background(), stmt); err != nil { | |
| 138 | + if _, err := s.db.ExecContext(context.Background(), stmt); err != nil { | |
| 139 | 139 | return fmt.Errorf("create vec0 table: %w", err) |
| 140 | 140 | } |
| 141 | 141 | } |
| 142 | 142 | return nil |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | -func (d *Databases) DB() *sql.DB { | |
| 146 | - return d.db.DB | |
| 145 | +func (s *Store) SQLDB() *sql.DB { | |
| 146 | + return s.db.DB | |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | func initUsersSchema(db *DB) error { |
| @@ -16,7 +16,7 @@ type DB struct { | |||
| 16 | *sql.DB | 16 | *sql.DB |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | -type Databases struct { | 19 | +type Store struct { |
| 20 | Users *UserStore | 20 | Users *UserStore |
| 21 | Articles *ArticleStore | 21 | Articles *ArticleStore |
| 22 | 22 | ||
| @@ -25,7 +25,7 @@ type Databases struct { | |||
| 25 | 25 | ||
| 26 | var multiDriverSeq int64 | 26 | var multiDriverSeq int64 |
| 27 | 27 | ||
| 28 | -func OpenAll(basePath string) (*Databases, error) { | 28 | +func Open(basePath string) (*Store, error) { |
| 29 | articlesPath := basePath + "_articles" | 29 | articlesPath := basePath + "_articles" |
| 30 | recsPath := basePath + "_recs" | 30 | recsPath := basePath + "_recs" |
| 31 | 31 | ||
| @@ -113,21 +113,21 @@ func OpenAll(basePath string) (*Databases, error) { | |||
| 113 | return nil, err | 113 | return nil, err |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | - return &Databases{ | 116 | + return &Store{ |
| 117 | Users: NewUserStore(d), | 117 | Users: NewUserStore(d), |
| 118 | Articles: NewArticleStore(d), | 118 | Articles: NewArticleStore(d), |
| 119 | db: d, | 119 | db: d, |
| 120 | }, nil | 120 | }, nil |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | -func (d *Databases) Close() error { | 123 | +func (s *Store) Close() error { |
| 124 | - if d.db != nil { | 124 | + if s.db != nil { |
| 125 | - _ = d.db.Close() | 125 | + _ = s.db.Close() |
| 126 | } | 126 | } |
| 127 | return nil | 127 | return nil |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | -func (d *Databases) InitVecTables(dimension int) error { | 130 | +func (s *Store) InitVecTables(dimension int) error { |
| 131 | if dimension <= 0 { | 131 | if dimension <= 0 { |
| 132 | return nil | 132 | return nil |
| 133 | } | 133 | } |
| @@ -135,15 +135,15 @@ func (d *Databases) InitVecTables(dimension int) error { | |||
| 135 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.feed_embeddings USING vec0(feed_url TEXT PRIMARY KEY, embedding float[%d])`, dimension), | 135 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.feed_embeddings USING vec0(feed_url TEXT PRIMARY KEY, embedding float[%d])`, dimension), |
| 136 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.article_embeddings USING vec0(article_id INTEGER PRIMARY KEY, embedding float[%d])`, dimension), | 136 | fmt.Sprintf(`CREATE VIRTUAL TABLE IF NOT EXISTS recs.article_embeddings USING vec0(article_id INTEGER PRIMARY KEY, embedding float[%d])`, dimension), |
| 137 | } { | 137 | } { |
| 138 | - if _, err := d.db.ExecContext(context.Background(), stmt); err != nil { | 138 | + if _, err := s.db.ExecContext(context.Background(), stmt); err != nil { |
| 139 | return fmt.Errorf("create vec0 table: %w", err) | 139 | return fmt.Errorf("create vec0 table: %w", err) |
| 140 | } | 140 | } |
| 141 | } | 141 | } |
| 142 | return nil | 142 | return nil |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | -func (d *Databases) DB() *sql.DB { | 145 | +func (s *Store) SQLDB() *sql.DB { |
| 146 | - return d.db.DB | 146 | + return s.db.DB |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | func initUsersSchema(db *DB) error { | 149 | func initUsersSchema(db *DB) error { |
modified
internal/db/follow.go +1 -1 | @@ -106,7 +106,7 @@ func (s *UserStore) IsFollowing(ctx context.Context, userDID, targetDID string) | ||
| 106 | 106 | return true, nil |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | -func (s *UserStore) GetFollowDIDs(ctx context.Context, userDID string) ([]string, error) { | |
| 109 | +func (s *UserStore) FollowDIDs(ctx context.Context, userDID string) ([]string, error) { | |
| 110 | 110 | rows, err := s.db.QueryContext(ctx, ` |
| 111 | 111 | SELECT target_did FROM follows WHERE user_did = ? |
| 112 | 112 | `, userDID) |
| @@ -106,7 +106,7 @@ func (s *UserStore) IsFollowing(ctx context.Context, userDID, targetDID string) | |||
| 106 | return true, nil | 106 | return true, nil |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | -func (s *UserStore) GetFollowDIDs(ctx context.Context, userDID string) ([]string, error) { | 109 | +func (s *UserStore) FollowDIDs(ctx context.Context, userDID string) ([]string, error) { |
| 110 | rows, err := s.db.QueryContext(ctx, ` | 110 | rows, err := s.db.QueryContext(ctx, ` |
| 111 | SELECT target_did FROM follows WHERE user_did = ? | 111 | SELECT target_did FROM follows WHERE user_did = ? |
| 112 | `, userDID) | 112 | `, userDID) |
modified
internal/db/follow_test.go +9 -9 | @@ -7,15 +7,15 @@ import ( | ||
| 7 | 7 | "gotest.tools/v3/assert" |
| 8 | 8 | ) |
| 9 | 9 | |
| 10 | -func seedFollowData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, targetDID string) { | |
| 10 | +func seedFollowData(t *testing.T, ctx context.Context, dbs *Store) (userDID, targetDID string) { | |
| 11 | 11 | t.Helper() |
| 12 | 12 | |
| 13 | 13 | userDID = "did:test:follower" |
| 14 | 14 | targetDID = "did:test:followed" |
| 15 | 15 | |
| 16 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 16 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | |
| 17 | 17 | assert.NilError(t, err) |
| 18 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, targetDID) | |
| 18 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, targetDID) | |
| 19 | 19 | assert.NilError(t, err) |
| 20 | 20 | |
| 21 | 21 | return userDID, targetDID |
| @@ -83,7 +83,7 @@ func TestListFollows(t *testing.T) { | ||
| 83 | 83 | userDID, _ := seedFollowData(t, ctx, dbs) |
| 84 | 84 | |
| 85 | 85 | target2 := "did:test:followed2" |
| 86 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | |
| 86 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | |
| 87 | 87 | assert.NilError(t, err) |
| 88 | 88 | |
| 89 | 89 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") |
| @@ -102,7 +102,7 @@ func TestListFollowers(t *testing.T) { | ||
| 102 | 102 | _, targetDID := seedFollowData(t, ctx, dbs) |
| 103 | 103 | |
| 104 | 104 | follower2 := "did:test:follower2" |
| 105 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, follower2) | |
| 105 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, follower2) | |
| 106 | 106 | assert.NilError(t, err) |
| 107 | 107 | |
| 108 | 108 | err = dbs.Users.UpsertFollow(ctx, "did:test:follower", targetDID, "uri1", "cid1") |
| @@ -115,13 +115,13 @@ func TestListFollowers(t *testing.T) { | ||
| 115 | 115 | assert.Equal(t, len(followers), 2) |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | -func TestGetFollowDIDs(t *testing.T) { | |
| 118 | +func TestFollowDIDs(t *testing.T) { | |
| 119 | 119 | ctx := context.Background() |
| 120 | 120 | dbs := setupTestDB(t) |
| 121 | 121 | userDID, _ := seedFollowData(t, ctx, dbs) |
| 122 | 122 | |
| 123 | 123 | target2 := "did:test:followed2" |
| 124 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | |
| 124 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | |
| 125 | 125 | assert.NilError(t, err) |
| 126 | 126 | |
| 127 | 127 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") |
| @@ -129,7 +129,7 @@ func TestGetFollowDIDs(t *testing.T) { | ||
| 129 | 129 | err = dbs.Users.UpsertFollow(ctx, userDID, target2, "uri2", "cid2") |
| 130 | 130 | assert.NilError(t, err) |
| 131 | 131 | |
| 132 | - dids, err := dbs.Users.GetFollowDIDs(ctx, userDID) | |
| 132 | + dids, err := dbs.Users.FollowDIDs(ctx, userDID) | |
| 133 | 133 | assert.NilError(t, err) |
| 134 | 134 | assert.Equal(t, len(dids), 2) |
| 135 | 135 | } |
| @@ -162,7 +162,7 @@ func TestSyncFollows_AddsNewRemovesStale(t *testing.T) { | ||
| 162 | 162 | assert.NilError(t, err) |
| 163 | 163 | assert.Equal(t, following2, true) |
| 164 | 164 | |
| 165 | - dids, err := dbs.Users.GetFollowDIDs(ctx, userDID) | |
| 165 | + dids, err := dbs.Users.FollowDIDs(ctx, userDID) | |
| 166 | 166 | assert.NilError(t, err) |
| 167 | 167 | assert.Equal(t, len(dids), 2) |
| 168 | 168 | } |
| @@ -7,15 +7,15 @@ import ( | |||
| 7 | "gotest.tools/v3/assert" | 7 | "gotest.tools/v3/assert" |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | -func seedFollowData(t *testing.T, ctx context.Context, dbs *Databases) (userDID, targetDID string) { | 10 | +func seedFollowData(t *testing.T, ctx context.Context, dbs *Store) (userDID, targetDID string) { |
| 11 | t.Helper() | 11 | t.Helper() |
| 12 | 12 | ||
| 13 | userDID = "did:test:follower" | 13 | userDID = "did:test:follower" |
| 14 | targetDID = "did:test:followed" | 14 | targetDID = "did:test:followed" |
| 15 | 15 | ||
| 16 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) | 16 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, userDID) |
| 17 | assert.NilError(t, err) | 17 | assert.NilError(t, err) |
| 18 | - _, err = dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, targetDID) | 18 | + _, err = dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, targetDID) |
| 19 | assert.NilError(t, err) | 19 | assert.NilError(t, err) |
| 20 | 20 | ||
| 21 | return userDID, targetDID | 21 | return userDID, targetDID |
| @@ -83,7 +83,7 @@ func TestListFollows(t *testing.T) { | |||
| 83 | userDID, _ := seedFollowData(t, ctx, dbs) | 83 | userDID, _ := seedFollowData(t, ctx, dbs) |
| 84 | 84 | ||
| 85 | target2 := "did:test:followed2" | 85 | target2 := "did:test:followed2" |
| 86 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | 86 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) |
| 87 | assert.NilError(t, err) | 87 | assert.NilError(t, err) |
| 88 | 88 | ||
| 89 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") | 89 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") |
| @@ -102,7 +102,7 @@ func TestListFollowers(t *testing.T) { | |||
| 102 | _, targetDID := seedFollowData(t, ctx, dbs) | 102 | _, targetDID := seedFollowData(t, ctx, dbs) |
| 103 | 103 | ||
| 104 | follower2 := "did:test:follower2" | 104 | follower2 := "did:test:follower2" |
| 105 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, follower2) | 105 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, follower2) |
| 106 | assert.NilError(t, err) | 106 | assert.NilError(t, err) |
| 107 | 107 | ||
| 108 | err = dbs.Users.UpsertFollow(ctx, "did:test:follower", targetDID, "uri1", "cid1") | 108 | err = dbs.Users.UpsertFollow(ctx, "did:test:follower", targetDID, "uri1", "cid1") |
| @@ -115,13 +115,13 @@ func TestListFollowers(t *testing.T) { | |||
| 115 | assert.Equal(t, len(followers), 2) | 115 | assert.Equal(t, len(followers), 2) |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | -func TestGetFollowDIDs(t *testing.T) { | 118 | +func TestFollowDIDs(t *testing.T) { |
| 119 | ctx := context.Background() | 119 | ctx := context.Background() |
| 120 | dbs := setupTestDB(t) | 120 | dbs := setupTestDB(t) |
| 121 | userDID, _ := seedFollowData(t, ctx, dbs) | 121 | userDID, _ := seedFollowData(t, ctx, dbs) |
| 122 | 122 | ||
| 123 | target2 := "did:test:followed2" | 123 | target2 := "did:test:followed2" |
| 124 | - _, err := dbs.DB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) | 124 | + _, err := dbs.SQLDB().ExecContext(ctx, `INSERT INTO users (did) VALUES (?)`, target2) |
| 125 | assert.NilError(t, err) | 125 | assert.NilError(t, err) |
| 126 | 126 | ||
| 127 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") | 127 | err = dbs.Users.UpsertFollow(ctx, userDID, "did:test:followed", "uri1", "cid1") |
| @@ -129,7 +129,7 @@ func TestGetFollowDIDs(t *testing.T) { | |||
| 129 | err = dbs.Users.UpsertFollow(ctx, userDID, target2, "uri2", "cid2") | 129 | err = dbs.Users.UpsertFollow(ctx, userDID, target2, "uri2", "cid2") |
| 130 | assert.NilError(t, err) | 130 | assert.NilError(t, err) |
| 131 | 131 | ||
| 132 | - dids, err := dbs.Users.GetFollowDIDs(ctx, userDID) | 132 | + dids, err := dbs.Users.FollowDIDs(ctx, userDID) |
| 133 | assert.NilError(t, err) | 133 | assert.NilError(t, err) |
| 134 | assert.Equal(t, len(dids), 2) | 134 | assert.Equal(t, len(dids), 2) |
| 135 | } | 135 | } |
| @@ -162,7 +162,7 @@ func TestSyncFollows_AddsNewRemovesStale(t *testing.T) { | |||
| 162 | assert.NilError(t, err) | 162 | assert.NilError(t, err) |
| 163 | assert.Equal(t, following2, true) | 163 | assert.Equal(t, following2, true) |
| 164 | 164 | ||
| 165 | - dids, err := dbs.Users.GetFollowDIDs(ctx, userDID) | 165 | + dids, err := dbs.Users.FollowDIDs(ctx, userDID) |
| 166 | assert.NilError(t, err) | 166 | assert.NilError(t, err) |
| 167 | assert.Equal(t, len(dids), 2) | 167 | assert.Equal(t, len(dids), 2) |
| 168 | } | 168 | } |
modified
internal/db/oauth_store.go +1 -1 | @@ -14,7 +14,7 @@ type OAuthStore struct { | ||
| 14 | 14 | db *DB |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | -func NewOAuthStore(dbs *Databases) *OAuthStore { | |
| 17 | +func NewOAuthStore(dbs *Store) *OAuthStore { | |
| 18 | 18 | return &OAuthStore{db: dbs.db} |
| 19 | 19 | } |
| 20 | 20 | |
| @@ -14,7 +14,7 @@ type OAuthStore struct { | |||
| 14 | db *DB | 14 | db *DB |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | -func NewOAuthStore(dbs *Databases) *OAuthStore { | 17 | +func NewOAuthStore(dbs *Store) *OAuthStore { |
| 18 | return &OAuthStore{db: dbs.db} | 18 | return &OAuthStore{db: dbs.db} |
| 19 | } | 19 | } |
| 20 | 20 | ||
modified
internal/db/store.go +7 -7 | @@ -8,15 +8,15 @@ import ( | ||
| 8 | 8 | "pkg.rbrt.fr/glean/internal/feed" |
| 9 | 9 | ) |
| 10 | 10 | |
| 11 | -type FeedStoreAdapter struct { | |
| 11 | +type FeedAdapter struct { | |
| 12 | 12 | store *ArticleStore |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | -func NewFeedStoreAdapter(store *ArticleStore) *FeedStoreAdapter { | |
| 16 | - return &FeedStoreAdapter{store: store} | |
| 15 | +func NewFeedAdapter(store *ArticleStore) *FeedAdapter { | |
| 16 | + return &FeedAdapter{store: store} | |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | -func (a *FeedStoreAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.Duration, limit int) ([]*feed.Feed, error) { | |
| 19 | +func (a *FeedAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.Duration, limit int) ([]*feed.Feed, error) { | |
| 20 | 20 | dbFeeds, err := a.store.GetFeedsToFetch(ctx, olderThan, limit) |
| 21 | 21 | if err != nil { |
| 22 | 22 | return nil, err |
| @@ -28,13 +28,13 @@ func (a *FeedStoreAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.D | ||
| 28 | 28 | return feeds, nil |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | -func (a *FeedStoreAdapter) RecordFetchError(ctx context.Context, feedURL, lastError string) error { | |
| 31 | +func (a *FeedAdapter) RecordFetchError(ctx context.Context, feedURL, lastError string) error { | |
| 32 | 32 | return a.store.MarkFeedFetchError(ctx, feedURL, lastError) |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | -func (a *FeedStoreAdapter) StoreFetchResult(ctx context.Context, feedURL string, articles []feed.Article, faviconURL string) error { | |
| 35 | +func (a *FeedAdapter) StoreFetchResult(ctx context.Context, feedURL string, articles []feed.Article, faviconURL string) error { | |
| 36 | 36 | if len(articles) > 0 { |
| 37 | - if err := a.store.UpsertArticlesBatch(ctx, articles); err != nil { | |
| 37 | + if err := a.store.BatchUpsertArticles(ctx, articles); err != nil { | |
| 38 | 38 | return fmt.Errorf("failed to save articles: %w", err) |
| 39 | 39 | } |
| 40 | 40 | } |
| @@ -8,15 +8,15 @@ import ( | |||
| 8 | "pkg.rbrt.fr/glean/internal/feed" | 8 | "pkg.rbrt.fr/glean/internal/feed" |
| 9 | ) | 9 | ) |
| 10 | 10 | ||
| 11 | -type FeedStoreAdapter struct { | 11 | +type FeedAdapter struct { |
| 12 | store *ArticleStore | 12 | store *ArticleStore |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | -func NewFeedStoreAdapter(store *ArticleStore) *FeedStoreAdapter { | 15 | +func NewFeedAdapter(store *ArticleStore) *FeedAdapter { |
| 16 | - return &FeedStoreAdapter{store: store} | 16 | + return &FeedAdapter{store: store} |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | -func (a *FeedStoreAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.Duration, limit int) ([]*feed.Feed, error) { | 19 | +func (a *FeedAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.Duration, limit int) ([]*feed.Feed, error) { |
| 20 | dbFeeds, err := a.store.GetFeedsToFetch(ctx, olderThan, limit) | 20 | dbFeeds, err := a.store.GetFeedsToFetch(ctx, olderThan, limit) |
| 21 | if err != nil { | 21 | if err != nil { |
| 22 | return nil, err | 22 | return nil, err |
| @@ -28,13 +28,13 @@ func (a *FeedStoreAdapter) GetFeedsToFetch(ctx context.Context, olderThan time.D | |||
| 28 | return feeds, nil | 28 | return feeds, nil |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | -func (a *FeedStoreAdapter) RecordFetchError(ctx context.Context, feedURL, lastError string) error { | 31 | +func (a *FeedAdapter) RecordFetchError(ctx context.Context, feedURL, lastError string) error { |
| 32 | return a.store.MarkFeedFetchError(ctx, feedURL, lastError) | 32 | return a.store.MarkFeedFetchError(ctx, feedURL, lastError) |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | -func (a *FeedStoreAdapter) StoreFetchResult(ctx context.Context, feedURL string, articles []feed.Article, faviconURL string) error { | 35 | +func (a *FeedAdapter) StoreFetchResult(ctx context.Context, feedURL string, articles []feed.Article, faviconURL string) error { |
| 36 | if len(articles) > 0 { | 36 | if len(articles) > 0 { |
| 37 | - if err := a.store.UpsertArticlesBatch(ctx, articles); err != nil { | 37 | + if err := a.store.BatchUpsertArticles(ctx, articles); err != nil { |
| 38 | return fmt.Errorf("failed to save articles: %w", err) | 38 | return fmt.Errorf("failed to save articles: %w", err) |
| 39 | } | 39 | } |
| 40 | } | 40 | } |
modified
internal/db/user.go +1 -1 | @@ -69,7 +69,7 @@ func (s *UserStore) GetUser(ctx context.Context, did string) (*User, error) { | ||
| 69 | 69 | return u, nil |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | -func (s *UserStore) ListUserDIDs(ctx context.Context) (map[string]bool, error) { | |
| 72 | +func (s *UserStore) UserDIDs(ctx context.Context) (map[string]bool, error) { | |
| 73 | 73 | rows, err := s.db.QueryContext(ctx, `SELECT did FROM users`) |
| 74 | 74 | if err != nil { |
| 75 | 75 | return nil, err |
| @@ -69,7 +69,7 @@ func (s *UserStore) GetUser(ctx context.Context, did string) (*User, error) { | |||
| 69 | return u, nil | 69 | return u, nil |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | -func (s *UserStore) ListUserDIDs(ctx context.Context) (map[string]bool, error) { | 72 | +func (s *UserStore) UserDIDs(ctx context.Context) (map[string]bool, error) { |
| 73 | rows, err := s.db.QueryContext(ctx, `SELECT did FROM users`) | 73 | rows, err := s.db.QueryContext(ctx, `SELECT did FROM users`) |
| 74 | if err != nil { | 74 | if err != nil { |
| 75 | return nil, err | 75 | return nil, err |
modified
internal/server/server.go +4 -4 | @@ -58,7 +58,7 @@ func splitString(s, sep string) []string { | ||
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | type Server struct { |
| 61 | - dbs *db.Databases | |
| 61 | + dbs *db.Store | |
| 62 | 62 | router *chi.Mux |
| 63 | 63 | templates *template.Template |
| 64 | 64 | logger *slog.Logger |
| @@ -73,7 +73,7 @@ type Server struct { | ||
| 73 | 73 | sessionKey []byte |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | -func New(dbs *db.Databases, clientID, callbackURL, addr string, scheduler *feed.Scheduler, engine *cluster.Engine, logger *slog.Logger, sessionKey []byte) *Server { | |
| 76 | +func New(dbs *db.Store, clientID, callbackURL, addr string, scheduler *feed.Scheduler, engine *cluster.Engine, logger *slog.Logger, sessionKey []byte) *Server { | |
| 77 | 77 | oauthStore := db.NewOAuthStore(dbs) |
| 78 | 78 | |
| 79 | 79 | var config oauth.ClientConfig |
| @@ -204,7 +204,7 @@ func (s *Server) setupRoutes() { | ||
| 204 | 204 | s.router.Post("/auth/logout", s.handleAuthLogout) |
| 205 | 205 | s.router.Get("/oauth/client-metadata", s.handleOAuthClientMetadata) |
| 206 | 206 | |
| 207 | - xrpc := atproto.NewXRPCHandler(s.dbs.DB(), s.engine) | |
| 207 | + xrpc := atproto.NewXRPCHandler(s.dbs.SQLDB(), s.engine) | |
| 208 | 208 | s.router.Get("/xrpc/at.glean.listSubscriptions", xrpc.ListSubscriptions) |
| 209 | 209 | s.router.Get("/xrpc/at.glean.listAnnotations", xrpc.ListAnnotations) |
| 210 | 210 | s.router.Get("/xrpc/at.glean.listLikes", xrpc.ListLikes) |
| @@ -416,7 +416,7 @@ func (s *Server) BackfillFromCollectionDir(ctx context.Context, collectionDirURL | ||
| 416 | 416 | return |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | - existing, err := s.dbs.Users.ListUserDIDs(ctx) | |
| 419 | + existing, err := s.dbs.Users.UserDIDs(ctx) | |
| 420 | 420 | if err != nil { |
| 421 | 421 | s.logger.Error("failed to list existing users", "error", err) |
| 422 | 422 | return |
| @@ -58,7 +58,7 @@ func splitString(s, sep string) []string { | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | type Server struct { | 60 | type Server struct { |
| 61 | - dbs *db.Databases | 61 | + dbs *db.Store |
| 62 | router *chi.Mux | 62 | router *chi.Mux |
| 63 | templates *template.Template | 63 | templates *template.Template |
| 64 | logger *slog.Logger | 64 | logger *slog.Logger |
| @@ -73,7 +73,7 @@ type Server struct { | |||
| 73 | sessionKey []byte | 73 | sessionKey []byte |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | -func New(dbs *db.Databases, clientID, callbackURL, addr string, scheduler *feed.Scheduler, engine *cluster.Engine, logger *slog.Logger, sessionKey []byte) *Server { | 76 | +func New(dbs *db.Store, clientID, callbackURL, addr string, scheduler *feed.Scheduler, engine *cluster.Engine, logger *slog.Logger, sessionKey []byte) *Server { |
| 77 | oauthStore := db.NewOAuthStore(dbs) | 77 | oauthStore := db.NewOAuthStore(dbs) |
| 78 | 78 | ||
| 79 | var config oauth.ClientConfig | 79 | var config oauth.ClientConfig |
| @@ -204,7 +204,7 @@ func (s *Server) setupRoutes() { | |||
| 204 | s.router.Post("/auth/logout", s.handleAuthLogout) | 204 | s.router.Post("/auth/logout", s.handleAuthLogout) |
| 205 | s.router.Get("/oauth/client-metadata", s.handleOAuthClientMetadata) | 205 | s.router.Get("/oauth/client-metadata", s.handleOAuthClientMetadata) |
| 206 | 206 | ||
| 207 | - xrpc := atproto.NewXRPCHandler(s.dbs.DB(), s.engine) | 207 | + xrpc := atproto.NewXRPCHandler(s.dbs.SQLDB(), s.engine) |
| 208 | s.router.Get("/xrpc/at.glean.listSubscriptions", xrpc.ListSubscriptions) | 208 | s.router.Get("/xrpc/at.glean.listSubscriptions", xrpc.ListSubscriptions) |
| 209 | s.router.Get("/xrpc/at.glean.listAnnotations", xrpc.ListAnnotations) | 209 | s.router.Get("/xrpc/at.glean.listAnnotations", xrpc.ListAnnotations) |
| 210 | s.router.Get("/xrpc/at.glean.listLikes", xrpc.ListLikes) | 210 | s.router.Get("/xrpc/at.glean.listLikes", xrpc.ListLikes) |
| @@ -416,7 +416,7 @@ func (s *Server) BackfillFromCollectionDir(ctx context.Context, collectionDirURL | |||
| 416 | return | 416 | return |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | - existing, err := s.dbs.Users.ListUserDIDs(ctx) | 419 | + existing, err := s.dbs.Users.UserDIDs(ctx) |
| 420 | if err != nil { | 420 | if err != nil { |
| 421 | s.logger.Error("failed to list existing users", "error", err) | 421 | s.logger.Error("failed to list existing users", "error", err) |
| 422 | return | 422 | return |
modified
main.go +3 -3 | @@ -43,7 +43,7 @@ func main() { | ||
| 43 | 43 | logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) |
| 44 | 44 | |
| 45 | 45 | vec.Auto() |
| 46 | - dbs, err := db.OpenAll(*dbPath) | |
| 46 | + dbs, err := db.Open(*dbPath) | |
| 47 | 47 | if err != nil { |
| 48 | 48 | logger.Error("failed to open databases", "error", err) |
| 49 | 49 | os.Exit(1) |
| @@ -53,7 +53,7 @@ func main() { | ||
| 53 | 53 | clientID := envOr("GLEAN_OAUTH_CLIENT_ID", "") |
| 54 | 54 | callbackURL := envOr("GLEAN_OAUTH_REDIRECT_URL", "") |
| 55 | 55 | |
| 56 | - storeAdapter := db.NewFeedStoreAdapter(dbs.Articles) | |
| 56 | + storeAdapter := db.NewFeedAdapter(dbs.Articles) | |
| 57 | 57 | scheduler := feed.NewScheduler(storeAdapter, logger, *fetchInterval, 30*time.Minute) |
| 58 | 58 | |
| 59 | 59 | var embedder cluster.Embedder |
| @@ -73,7 +73,7 @@ func main() { | ||
| 73 | 73 | } |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | - engine := cluster.NewEngine(dbs.DB(), embedder, logger) | |
| 76 | + engine := cluster.NewEngine(dbs.SQLDB(), embedder, logger) | |
| 77 | 77 | |
| 78 | 78 | srv := server.New(dbs, clientID, callbackURL, *addr, scheduler, engine, logger, []byte(sessionKey)) |
| 79 | 79 | |
| @@ -43,7 +43,7 @@ func main() { | |||
| 43 | logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) | 43 | logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) |
| 44 | 44 | ||
| 45 | vec.Auto() | 45 | vec.Auto() |
| 46 | - dbs, err := db.OpenAll(*dbPath) | 46 | + dbs, err := db.Open(*dbPath) |
| 47 | if err != nil { | 47 | if err != nil { |
| 48 | logger.Error("failed to open databases", "error", err) | 48 | logger.Error("failed to open databases", "error", err) |
| 49 | os.Exit(1) | 49 | os.Exit(1) |
| @@ -53,7 +53,7 @@ func main() { | |||
| 53 | clientID := envOr("GLEAN_OAUTH_CLIENT_ID", "") | 53 | clientID := envOr("GLEAN_OAUTH_CLIENT_ID", "") |
| 54 | callbackURL := envOr("GLEAN_OAUTH_REDIRECT_URL", "") | 54 | callbackURL := envOr("GLEAN_OAUTH_REDIRECT_URL", "") |
| 55 | 55 | ||
| 56 | - storeAdapter := db.NewFeedStoreAdapter(dbs.Articles) | 56 | + storeAdapter := db.NewFeedAdapter(dbs.Articles) |
| 57 | scheduler := feed.NewScheduler(storeAdapter, logger, *fetchInterval, 30*time.Minute) | 57 | scheduler := feed.NewScheduler(storeAdapter, logger, *fetchInterval, 30*time.Minute) |
| 58 | 58 | ||
| 59 | var embedder cluster.Embedder | 59 | var embedder cluster.Embedder |
| @@ -73,7 +73,7 @@ func main() { | |||
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | - engine := cluster.NewEngine(dbs.DB(), embedder, logger) | 76 | + engine := cluster.NewEngine(dbs.SQLDB(), embedder, logger) |
| 77 | 77 | ||
| 78 | srv := server.New(dbs, clientID, callbackURL, *addr, scheduler, engine, logger, []byte(sessionKey)) | 78 | srv := server.New(dbs, clientID, callbackURL, *addr, scheduler, engine, logger, []byte(sessionKey)) |
| 79 | 79 | ||