2025-08-08 23:37:08 -05:00

349 lines
7.5 KiB
Go

/*
Package news is the active record implementation for news posts in the game.
# Basic Usage
To retrieve a news post by ID:
newsPost, err := news.Find(db, 1)
if err != nil {
log.Fatal(err)
}
fmt.Printf("News: %s (by user %d)\n", newsPost.Content, newsPost.Author)
To get all news posts:
allNews, err := news.All(db)
if err != nil {
log.Fatal(err)
}
for _, post := range allNews {
fmt.Printf("News: %s\n", post.Content)
}
To get recent news posts:
recentNews, err := news.Recent(db, 10)
if err != nil {
log.Fatal(err)
}
To filter news by author:
authorPosts, err := news.ByAuthor(db, userID)
if err != nil {
log.Fatal(err)
}
To get news since a specific time:
yesterday := time.Now().AddDate(0, 0, -1).Unix()
recentNews, err := news.Since(db, yesterday)
if err != nil {
log.Fatal(err)
}
# Creating News with Builder Pattern
The package provides a fluent builder interface for creating new news posts:
newsPost, err := news.NewBuilder(db).
WithAuthor(userID).
WithContent("Welcome to the new update! Many exciting features await.").
WithPostedTime(time.Now()).
Create()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created news post with ID: %d\n", newsPost.ID)
The builder automatically sets the current time if no posted time is specified:
newsPost, err := news.NewBuilder(db).
WithAuthor(adminID).
WithContent("Server maintenance scheduled for tonight.").
Create() // Uses current timestamp
# Updating News
News posts can be modified and saved back to the database:
newsPost, _ := news.Find(db, 1)
newsPost.Content = "Updated: Server maintenance completed successfully."
err := newsPost.Save()
if err != nil {
log.Fatal(err)
}
# Deleting News
News posts can be removed from the database:
newsPost, _ := news.Find(db, 1)
err := newsPost.Delete()
if err != nil {
log.Fatal(err)
}
# Database Schema
The news table has the following structure:
CREATE TABLE news (
id INTEGER PRIMARY KEY AUTOINCREMENT,
author INTEGER NOT NULL,
posted INTEGER NOT NULL DEFAULT (unixepoch()),
content TEXT NOT NULL
)
Where:
- id: Unique identifier for the news post
- author: User ID of the author who created the post
- posted: Unix timestamp when the post was created
- content: The text content of the news post
# Time-Based Queries
## Recent News
Get the most recent news posts:
// Get 5 most recent posts
latestNews, err := news.Recent(db, 5)
if err != nil {
log.Fatal(err)
}
for _, post := range latestNews {
fmt.Printf("Posted %s: %s\n",
post.PostedTime().Format("2006-01-02"),
post.Preview(50))
}
## News Since Timestamp
Get news posts since a specific time:
// Get news from the last week
weekAgo := time.Now().AddDate(0, 0, -7).Unix()
weeklyNews, err := news.Since(db, weekAgo)
if err != nil {
log.Fatal(err)
}
## News Between Timestamps
Get news posts within a time range:
// Get news from last month
start := time.Now().AddDate(0, -1, 0).Unix()
end := time.Now().Unix()
monthlyNews, err := news.Between(db, start, end)
if err != nil {
log.Fatal(err)
}
# Content Management
## Content Analysis
The package provides utilities for analyzing news content:
wordCount := newsPost.WordCount()
fmt.Printf("Post contains %d words\n", wordCount)
preview := newsPost.Preview(100)
fmt.Printf("Preview: %s\n", preview)
## Author Management
Check authorship and manage posts by author:
if newsPost.IsAuthor(currentUserID) {
fmt.Println("You can edit this post")
}
// Get all posts by a specific author
authorPosts, err := news.ByAuthor(db, authorID)
fmt.Printf("Author has written %d posts\n", len(authorPosts))
# Time Utilities
## Working with Timestamps
The package provides convenient time utilities:
// Get posting time as time.Time
postTime := newsPost.PostedTime()
fmt.Printf("Posted on: %s\n", postTime.Format("January 2, 2006"))
// Set posting time from time.Time
newsPost.SetPostedTime(time.Now().Add(-2 * time.Hour))
// Check if post is recent (within 24 hours)
if newsPost.IsRecent() {
fmt.Println("This is a recent post")
}
// Get age of the post
age := newsPost.Age()
fmt.Printf("Posted %v ago\n", age)
## Time-Based Filtering
Find posts based on recency:
allNews, _ := news.All(db)
recentPosts := make([]*news.News, 0)
for _, post := range allNews {
if post.IsRecent() {
recentPosts = append(recentPosts, post)
}
}
fmt.Printf("Found %d recent posts\n", len(recentPosts))
# Administrative Features
## Moderation
Administrators can manage news posts:
// Get all posts by a user for moderation
suspiciousPosts, err := news.ByAuthor(db, reportedUserID)
for _, post := range suspiciousPosts {
if post.WordCount() < 5 {
fmt.Printf("Short post flagged: %s\n", post.Preview(50))
}
}
## Content Guidelines
Use content analysis for moderation:
if newsPost.WordCount() > 1000 {
fmt.Println("Warning: Very long post")
}
if len(newsPost.Content) < 10 {
fmt.Println("Warning: Very short post")
}
# Display and Formatting
## News Feeds
Display news in chronological order:
recentNews, _ := news.Recent(db, 20)
fmt.Println("=== Latest News ===")
for _, post := range recentNews {
age := post.Age()
var ageStr string
if age < time.Hour {
ageStr = fmt.Sprintf("%d minutes ago", int(age.Minutes()))
} else if age < 24*time.Hour {
ageStr = fmt.Sprintf("%d hours ago", int(age.Hours()))
} else {
ageStr = fmt.Sprintf("%d days ago", int(age.Hours()/24))
}
fmt.Printf("[%s] %s\n", ageStr, post.Preview(80))
}
## Preview Generation
Generate previews for different contexts:
// Short preview for mobile
mobilePreview := newsPost.Preview(30)
// Medium preview for web cards
cardPreview := newsPost.Preview(100)
// Long preview for detailed view
detailPreview := newsPost.Preview(200)
# Performance Considerations
## Query Optimization
All time-based queries are optimized with proper indexing expectations:
// Queries are ordered by posted timestamp for efficient retrieval
latestNews, _ := news.All(db) // ORDER BY posted DESC, id DESC
// Author queries include time ordering
authorPosts, _ := news.ByAuthor(db, userID) // ORDER BY posted DESC, id DESC
## Batch Operations
For processing multiple posts efficiently:
// Process posts in batches
batchSize := 100
allNews, _ := news.All(db)
for i := 0; i < len(allNews); i += batchSize {
end := i + batchSize
if end > len(allNews) {
end = len(allNews)
}
batch := allNews[i:end]
// Process batch...
}
# Error Handling
All functions return appropriate errors for common failure cases:
- News post not found (Find returns error for non-existent IDs)
- Database connection issues
- Invalid operations (e.g., saving/deleting news posts without IDs)
- Time range query errors
# Integration Patterns
## User Integration
Connect with user management:
// Example: Get news by username (assuming user lookup)
user := getUserByName("admin")
adminNews, err := news.ByAuthor(db, user.ID)
## Notification System
Use for activity feeds:
// Get user's activity since last login
lastLogin := getUserLastLogin(userID)
newsSinceLogin, err := news.Since(db, lastLogin)
if len(newsSinceLogin) > 0 {
fmt.Printf("You have %d new posts since your last visit\n", len(newsSinceLogin))
}
## Archive Management
Implement content archiving:
// Archive old posts (older than 1 year)
oneYearAgo := time.Now().AddDate(-1, 0, 0).Unix()
oldPosts, _ := news.Since(db, 0) // Get all posts
for _, post := range oldPosts {
if post.Posted < oneYearAgo {
// Archive or delete old post
post.Delete()
}
}
*/
package news