Archived
1
0
This repository has been archived on 2023-08-12. You can view files and clone it, but cannot push or open issues or pull requests.
nntpchan/contrib/backends/srndv2/src/srnd/database.go

336 lines
10 KiB
Go
Raw Normal View History

//
// database.go
//
package srnd
import (
"log"
"net"
"strings"
"time"
)
// a ( MessageID , newsgroup ) tuple
type ArticleEntry [2]string
func (self ArticleEntry) Newsgroup() string {
return self[1]
}
func (self ArticleEntry) MessageID() string {
return self[0]
}
// a (messageID , parent messageID) tuple
type MessageIDTuple [2]string
func (self MessageIDTuple) MessageID() string {
return strings.Trim(self[0], " ")
}
func (self MessageIDTuple) Reference() string {
r := strings.Trim(self[1], " ")
if len(r) == 0 {
return self.MessageID()
}
return r
}
// a ( time point, magnitude ) tuple
type PostEntry [2]int64
func (self PostEntry) Time() time.Time {
return time.Unix(self[0], 0)
}
func (self PostEntry) Count() int64 {
return self[1]
}
// stats about newsgroup postings
type NewsgroupStats struct {
Posted []PostEntry
Delted []PostEntry
Hits []PostEntry
Start time.Time
End time.Time
Name string
}
type PostingStatsEntry struct {
Groups []NewsgroupStats
}
type PostingStats struct {
History []PostingStatsEntry
}
type Database interface {
Close()
CreateTables()
HasNewsgroup(group string) bool
HasArticle(message_id string) bool
HasArticleLocal(message_id string) bool
RegisterNewsgroup(group string)
RegisterArticle(article NNTPMessage) error
GetAllArticlesInGroup(group string, send chan ArticleEntry)
CountAllArticlesInGroup(group string) (int64, error)
GetAllArticles() []ArticleEntry
SetConnectionLifetime(seconds int)
SetMaxOpenConns(n int)
SetMaxIdleConns(n int)
// check if a newsgroup is banned
NewsgroupBanned(group string) (bool, error)
// ban / unban newsgroup
BanNewsgroup(group string) error
UnbanNewsgroup(group string) error
// delete an entire newsgroup
// delete from the article store too
NukeNewsgroup(group string, store ArticleStore)
// return true if this is root post has expired
IsExpired(root_message_id string) bool
// get an article's MessageID given the hash of the MessageID
// return an article entry or nil when it doesn't exist + and error if it happened
GetMessageIDByHash(hash string) (ArticleEntry, error)
// get root message_id, newsgroup, pageno for a post regardless if it's rootpost or not
GetInfoForMessage(msgid string) (string, string, int64, error)
// what page is the thread with this root post on?
// return newsgroup, pageno
GetPageForRootMessage(root_message_id string) (string, int64, error)
// record that a message given a message id was posted signed by this pubkey
RegisterSigned(message_id, pubkey string) error
// get the number of articles we have
ArticleCount() int64
// return true if this thread has any replies
ThreadHasReplies(root_message_id string) bool
// get the number of posts in a certain newsgroup since N seconds ago
// if N <= 0 then count all we have now
CountPostsInGroup(group string, time_frame int64) int64
// get all replies to a thread
// if last > 0 then get that many of the last replies
// start at reply number start
GetThreadReplies(root_message_id string, start, last int) []string
// count the number of replies to this thread
CountThreadReplies(root_message_id string) int64
// get all attachments for this message
GetPostAttachments(message_id string) []string
// get all attachments for this message
GetPostAttachmentModels(prefix, message_id string) []AttachmentModel
// return true if this newsgroup has posts
GroupHasPosts(newsgroup string) bool
// get all active threads on a board
// send each thread's ArticleEntry down a channel
GetGroupThreads(newsgroup string, send chan ArticleEntry)
// get every message id for root posts that need to be expired in a newsgroup
// threadcount is the upperbound limit to how many root posts we keep
GetRootPostsForExpiration(newsgroup string, threadcount int) []string
// get the number of pages a board has
GetGroupPageCount(newsgroup string) int64
// get board page number N
// prefix and frontend are injected
// does not load replies for thread, only gets root posts
GetGroupForPage(prefix, frontend, newsgroup string, pageno, perpage int) BoardModel
// get the root posts of the last N bumped threads in a given newsgroup or "" for ukko
GetLastBumpedThreads(newsgroup string, threadcount int) []ArticleEntry
// get root posts of last N bumped threads with pagination offset
GetLastBumpedThreadsPaginated(newsgroup string, threadcount, offset int) []ArticleEntry
// get the PostModels for replies to a thread
// prefix is injected into the post models
GetThreadReplyPostModels(prefix, rootMessageID string, start, limit int) []PostModel
// get a post model for a post
// prefix is injected into the post model
GetPostModel(prefix, messageID string) PostModel
// add a public key to the database
AddModPubkey(pubkey string) error
// mark that a mod with this pubkey can act on all boards
MarkModPubkeyGlobal(pubkey string) error
// revoke mod with this pubkey the privilege of being able to act on all boards
UnMarkModPubkeyGlobal(pubkey string) error
// check if this mod pubkey can moderate at a global level
CheckModPubkeyGlobal(pubkey string) bool
// check if a mod with this pubkey has permission to moderate at all
CheckModPubkey(pubkey string) bool
// check if a pubkey has admin privs
CheckAdminPubkey(pubkey string) (bool, error)
// mark a key as having admin privs
MarkPubkeyAdmin(pubkey string) error
// unmark a key as having admin privs
UnmarkPubkeyAdmin(pubkey string) error
// check if a mod with this pubkey can moderate on the given newsgroup
CheckModPubkeyCanModGroup(pubkey, newsgroup string) bool
// add a pubkey to be able to mod a newsgroup
MarkModPubkeyCanModGroup(pubkey, newsgroup string) error
// remote a pubkey to they can't mod a newsgroup
UnMarkModPubkeyCanModGroup(pubkey, newsgroup string) error
// ban an article
BanArticle(messageID, reason string) error
// check if an article is banned or not
ArticleBanned(messageID string) bool
// Get ip address given the encrypted version
// return emtpy string if we don't have it
GetIPAddress(encAddr string) (string, error)
// check if an ip is banned from our local
CheckIPBanned(addr string) (bool, error)
// check if an encrypted ip is banned from our local
CheckEncIPBanned(encAddr string) (bool, error)
// ban an ip address from the local
BanAddr(addr string) error
// unban an ip address from the local
UnbanAddr(addr string) error
// ban an encrypted ip address from the remote
BanEncAddr(encAddr string) error
// return the encrypted version of an IPAddress
// if it's not already there insert it into the database
GetEncAddress(addr string) (string, error)
// get the decryption key for an encrypted address
// return empty string if we don't have it
GetEncKey(encAddr string) (string, error)
// delete an article from the database
DeleteArticle(msg_id string) error
// detele the existance of a thread from the threads table, does NOT remove replies
DeleteThread(root_msg_id string) error
// get threads per page for a newsgroup
GetThreadsPerPage(group string) (int, error)
// get pages per board for a newsgroup
GetPagesPerBoard(group string) (int, error)
// get every newsgroup we know of
GetAllNewsgroups() []string
// get all post models in a newsgroup
// ordered from oldest to newest
GetPostsInGroup(group string) ([]PostModel, error)
// get the numerical id of the last , first article for a given group
GetLastAndFirstForGroup(group string) (int64, int64, error)
// get a message id give a newsgroup and the nntp id
GetMessageIDForNNTPID(group string, id int64) (string, error)
// get nntp id for a given message-id
GetNNTPIDForMessageID(group, msgid string) (int64, error)
// get the last N days post count in decending order
GetLastDaysPosts(n int64) []PostEntry
// get the last N days post count in decending order
GetLastDaysPostsForGroup(newsgroup string, n int64) []PostEntry
// get post history per month since beginning of time
GetMonthlyPostHistory() []PostEntry
// get the last N posts that were made globally
GetLastPostedPostModels(prefix string, n int64) []PostModel
// check if an nntp login cred is correct
CheckNNTPLogin(username, passwd string) (bool, error)
// add an nntp login credential
AddNNTPLogin(username, passwd string) error
// remove an nntp login credential
RemoveNNTPLogin(username string) error
// check if an nntp login credential given a user exists
CheckNNTPUserExists(username string) (bool, error)
// get the message ids of an article that has this header with the given value
GetMessageIDByHeader(name, value string) ([]string, error)
// get the headers for a message given its message-id
GetHeadersForMessage(msgid string) (ArticleHeaders, error)
// get all message-ids posted by posters in this cidr
GetMessageIDByCIDR(cidr *net.IPNet) ([]string, error)
// get all message-ids posted by poster with encrypted ip
GetMessageIDByEncryptedIP(encaddr string) ([]string, error)
// check if this public key is banned from posting
PubkeyIsBanned(pubkey string) (bool, error)
// ban a public key from posting
BanPubkey(pubkey string) error
// get all message-id posted before a time
GetPostsBefore(t time.Time) ([]string, error)
// get statistics about posting in a time slice
GetPostingStats(granularity, begin, end int64) (PostingStats, error)
// peform search query
SearchQuery(prefix, group, text string, chnl chan PostModel) error
// find posts with similar hash
SearchByHash(prefix, group, posthash string, chnl chan PostModel) error
// get full thread model
GetThreadModel(prefix, root_msgid string) (ThreadModel, error)
// get post models with nntp id in a newsgroup
GetNNTPPostsInGroup(newsgroup string) ([]PostModel, error)
// get post message-id where hash is similar to string
GetCitesByPostHashLike(like string) ([]MessageIDTuple, error)
}
func NewDatabase(db_type, schema, host, port, user, password string) Database {
if db_type == "postgres" {
if schema == "srnd" {
return NewPostgresDatabase(host, port, user, password)
}
}
log.Fatalf("invalid database type: %s/%s", db_type, schema)
return nil
}