349 lines
7.5 KiB
Go
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 |