summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-01-16 14:13:25 -0300
committerEuAndreh <eu@euandre.org>2026-01-16 14:13:25 -0300
commit447df4394cba7d84eaf5bdfa4fb1efb101faf74e (patch)
tree084f8e3b0544244adfbd90749f0ce621140219bb
parentsrc/papod.go: Last Go commit (diff)
downloadpapod-447df4394cba7d84eaf5bdfa4fb1efb101faf74e.tar.gz
papod-447df4394cba7d84eaf5bdfa4fb1efb101faf74e.tar.xz
Remove Go code
-rw-r--r--src/main.go7
-rw-r--r--src/papod.go1158
l---------tests/benchmarks/join-leave/main.go1
-rw-r--r--tests/benchmarks/join-leave/papod.go23
l---------tests/functional/multiple-channels-and-users/main.go1
-rw-r--r--tests/functional/multiple-channels-and-users/papod.go12
l---------tests/fuzz/api-check/main.go1
-rw-r--r--tests/fuzz/api-check/papod.go34
-rw-r--r--tests/main.go7
-rw-r--r--tests/papod.go382
-rw-r--r--tests/queries.sql1230
11 files changed, 0 insertions, 2856 deletions
diff --git a/src/main.go b/src/main.go
deleted file mode 100644
index b591f5c..0000000
--- a/src/main.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package main
-
-import "papod"
-
-func main() {
- papod.Main()
-}
diff --git a/src/papod.go b/src/papod.go
deleted file mode 100644
index 7db55e8..0000000
--- a/src/papod.go
+++ /dev/null
@@ -1,1158 +0,0 @@
-package papod
-
-import (
- "bufio"
- "bytes"
- "errors"
- "flag"
- "fmt"
- "io"
- "log/slog"
- "net"
- "os"
- "regexp"
- "strings"
- "sync"
-
- "acude"
- "cracha"
- "uuid"
- "pds"
- "stm"
- g "gobang"
- gt "gotext"
-)
-
-
-
-type newUserT struct{
-}
-
-type userT struct{
- username string
-}
-
-type newNetworkT struct{
-}
-
-type networkT struct{
-}
-
-type newMemberT struct{
-}
-
-type memberT struct{
-}
-
-type newChannelT struct{
-}
-
-type channelT struct{
-}
-
-type newEventT struct{
-}
-
-type eventT struct{
-}
-
-type queriesT struct{
- createUser func(newUserT) (userT, error)
- userByUUID func(uuid.UUID) (userT, error)
- editUser func(userT) error
- removeUser func(userT) error
- createNetwork func(userT, newNetworkT) (networkT, error)
- networkByUUID func(userT, uuid.UUID) (networkT, error)
- allNetworks func(userT) (<-chan networkT, error)
- editNetwork func(memberT, networkT) error
- removeNetwork func(memberT) error
- addMember func(memberT, newMemberT) (memberT, error)
- addRoles func(memberT, []string, memberT) error
- removeRoles func(memberT, []string, memberT) error
- memberByUUID func(memberT, uuid.UUID) (memberT, error)
- allMembers func(memberT) (<-chan memberT, error)
- editMember func(memberT, memberT) error
- removeMember func(memberT, memberT) error
- createChannel func(memberT, newChannelT) (channelT, error)
- channelsByName func(memberT, string) (<-chan channelT)
- editChannel func(memberT, channelT) error
- removeChannel func(memberT, channelT) error
- joinChannel func(memberT, channelT) error
- partChannel func(memberT, channelT) error
- addEvent func(memberT, newEventT) (eventT, error)
- eventsAfter func(memberT, eventT) (<-chan eventT, error)
- editEvent func(memberT, eventT) (eventT, error)
- removeEvent func(memberT, uuid.UUID) error
- close func() error
-}
-
-type messageT struct{
- prefix string
- command string
- params []string
- raw string
-}
-
-type replyT struct{
- command string
- params []string
-}
-
-type taskT struct{
-}
-
-type actionT struct{
- replies []replyT
- shouldClose bool
- err error
- task []taskT
-}
-
-type listenersT struct{
- daemon net.Listener
- commander net.Listener
- close func() error
-}
-
-type netConnI interface{
- Write(p []byte) (n int, err error)
- Close() error
-}
-
-type connectionT struct{
- uuid uuid.UUID
- user *userT
- conn netConnI
- send func(messageT)
-}
-
-type metricsT struct{
- activeConnections g.Gauge
- nicksInChannel g.Gauge
- sendToClientError func(...any)
- receivedMessage func(...any)
- sentReply func(...any)
-}
-
-type stateT struct{
- members *pds.Map[string, []string]
- users *pds.Map[string, []uuid.UUID]
- connections *pds.Map[uuid.UUID, connectionT]
-}
-
-type papodT struct{
- acude acude.AcudeI
- cracha cracha.CrachaI
- listeners listenersT
- state *stm.AtomT[stateT]
- metrics metricsT
-}
-
-type PapoI interface{
- Start() error
- Close() error
-}
-
-type argsT struct{
- allArgs []string
- subArgs []string
- baseDir string
- tag string
-}
-
-type envT struct{
- args argsT
- in io.Reader
- out io.Writer
- err io.Writer
-}
-
-
-
-func initListeners(
- daemonSocketPath string,
- commanderSocketPath string,
-) (listenersT, error) {
- _ = os.Remove(daemonSocketPath)
- _ = os.Remove(commanderSocketPath)
-
- daemon, err := net.Listen("unix", daemonSocketPath)
- if err != nil {
- return listenersT{}, err
- }
-
- commander, err := net.Listen("unix", commanderSocketPath)
- if err != nil {
- daemon.Close()
- return listenersT{}, err
- }
-
- return listenersT{
- daemon: daemon,
- commander: commander,
- close: func() error {
- return g.SomeFnError(
- daemon.Close,
- commander.Close,
- )
- },
- }, nil
-}
-
-func newState() stateT {
- return stateT{
- members: pds.NewMap[string, []string](nil),
- users: pds.NewMap[string, []uuid.UUID](nil),
- connections: pds.NewMap[uuid.UUID, connectionT](nil),
- }
-}
-
-func buildMetrics(tag string) metricsT {
- return metricsT{
- activeConnections: g.MakeGauge(
- "active-connection",
- "tag", tag,
- ),
- nicksInChannel: g.MakeGauge(
- "nicks-in-channel",
- "tag", tag,
- ),
- sendToClientError: g.MakeCounter(
- "send-to-client-error",
- "tag", tag,
- ),
- receivedMessage: g.MakeCounter(
- "received-message",
- "tag", tag,
- ),
- sentReply: g.MakeCounter(
- "sent-reply",
- "tag", tag,
- ),
- }
-}
-
-func initDB(path string) (acude.AcudeI, error) {
- return nil, nil
-}
-
-func newPapod(baseDir string, tag string) (papodT, error) {
- databasePath := baseDir + "/papod.dedo"
- daemonSocketPath := baseDir + "/papod.daemon.socket"
- commanderSocketPath := baseDir + "/papod.commander.socket"
-
- cracha, err := cracha.New(databasePath)
- if err != nil {
- return papodT{}, err
- }
-
- listeners, err := initListeners(daemonSocketPath, commanderSocketPath)
- if err != nil {
- cracha.Close()
- return papodT{}, err
- }
-
- acude, err := initDB(databasePath)
- if err != nil {
- cracha.Close()
- listeners.close()
- return papodT{}, err
- }
-
- return papodT{
- acude: acude,
- cracha: cracha,
- listeners: listeners,
- state: stm.Atom(newState()),
- metrics: buildMetrics(tag),
- }, nil
-}
-
-func NewWith(baseDir string, tag string) (PapoI, error) {
- return newPapod(baseDir, tag)
-}
-
-func New() (PapoI, error) {
- return NewWith(".", "papod-default")
-}
-
-func splitOnCRLF(data []byte, _atEOF bool) (int, []byte, error) {
- idx := bytes.Index(data, []byte { '\r', '\n' })
- if idx == -1 {
- return 0, nil, nil
- }
-
- return idx + 2, data[0:idx], nil
-}
-
-func splitOnRawMessage(data []byte, atEOF bool) (int, []byte, error) {
- advance, token, error := splitOnCRLF(data, atEOF)
-
- if len(token) == 0 {
- return advance, nil, error
- }
-
- return advance, token, error
-}
-
-func splitCommas(r rune) bool {
- return r == ','
-}
-
-func splitSpaces(r rune) bool {
- return r == ' '
-}
-
-func parseMessageParams(params string) []string {
- const sep = " :"
-
- idx := strings.Index(params, sep)
- if idx == -1 {
- return strings.FieldsFunc(params, splitSpaces)
- } else {
- middle := params[:idx]
- trailing := params[idx + len(sep):]
- return append(
- strings.FieldsFunc(middle, splitSpaces),
- trailing,
- )
- }
-}
-
-func stripBlankParams(params []string) []string {
- if len(params) == 1 && len(params[0]) == 0 {
- return []string{}
- }
-
- return params
-}
-
-var messageRegex = regexp.MustCompilePOSIX(
- // <prefix> <command> <params>
- //1 2 3 4
- `^(:([^ ]+) +)?([a-zA-Z]+) *( .*)$`,
-)
-func parseMessage(rawMessage string) (messageT, error) {
- var msg messageT
-
- components := messageRegex.FindStringSubmatch(rawMessage)
- if components == nil {
- return msg, errors.New("Can't parse message")
- }
-
- msg = messageT{
- prefix: components[2],
- command: components[3],
- params: stripBlankParams(parseMessageParams(components[4])),
- raw: rawMessage,
- }
- return msg, nil
-}
-
-func removeConnection(state stateT, connection *connectionT) stateT {
- return state // FIXME
-}
-
-/// Is this death by a thousand goroutines? Is the runtime able to handle the
-/// creation and destruction of hundreds of thousands of goroutines per second?
-/// For now, we'll assume that Go's (gc) runtime, scheduler and garbage
-/// collector are capable of working together to make sure this isn't a
-/// catastrophe.
-func broadcastMessage(
- message messageT,
- channelName string,
- state stateT,
-) {
- usernames, _ := state.members.Get(channelName)
- for _, username := range usernames {
- connectionIDs, _ := state.users.Get(username)
- for _, connectionID := range connectionIDs {
- connection, ok := state.connections.Get(connectionID)
- if !ok {
- continue
- }
-
- go connection.send(message)
- }
- }
-}
-
-
-/*
-Intentionally not implemented:
-
-// FIXME: why?
-- RPL_BOUNCE
-
-*/
-
-// FIXME: add check for minRPL...
-const minRPL_WELCOME = 0
-func _RPL_WELCOME(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "001",
- params: []string{
- connection.user.username,
- "Welcome to the Internet Relay Network " +
- connection.user.username,
- },
- }
-}
-
-const minRPL_YOURHOST = 0
-func _RPL_YOURHOST(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "002",
- params: []string{
- connection.user.username,
- "Your host is FIXME, running version " +
- Version,
- },
- }
-}
-
-const minRPL_CREATED = 0
-func _RPL_CREATED(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "003",
- params: []string{
- connection.user.username,
- "This server was create FIXME",
- },
- }
-}
-
-const minRPL_MYINFO = 0
-func _RPL_MYINFO(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "004",
- params: []string{
- connection.user.username,
- "FIXME " + Version + " i x",
- },
- }
-}
-
-const minRPL_UNAWAY = 0
-func _RPL_UNAWAY(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "305",
- params: []string{
- connection.user.username,
- "You are no longer marked as away",
- },
- }
-}
-
-const minRPL_NOWAWAY = 0
-func _RPL_NOWAWAY(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "306",
- params: []string{
- connection.user.username,
- "You have been marked as away",
- },
- }
-}
-
-const minRPL_WHOISUSER = 1
-func _RPL_WHOISUSER(connection *connectionT, msg messageT) replyT {
- user := msg.params[0]
- return replyT{
- command: "311",
- params: []string{
- connection.user.username,
- user,
- user,
- "samehost",
- "*",
- "my real name is: " + user,
- },
- }
-}
-
-const minRPL_WHOISSERVER = 1
-func _RPL_WHOISSERVER(connection *connectionT, msg messageT) replyT {
- user := msg.params[0]
- return replyT{
- command: "312",
- params: []string{
- connection.user.username,
- user,
- "stillsamehost",
- "some server info",
- },
- }
-}
-
-const minRPL_ENDOFWHOIS = 1
-func _RPL_ENDOFWHOIS(connection *connectionT, msg messageT) replyT {
- user := msg.params[0]
- return replyT{
- command: "318",
- params: []string{
- connection.user.username,
- user,
- "End of WHOIS list",
- },
- }
-}
-
-const minRPL_WHOISCHANNELS = 1
-func _RPL_WHOISCHANNELS(connection *connectionT, msg messageT) replyT {
- user := msg.params[0]
- return replyT{
- command: "319",
- params: []string{
- connection.user.username,
- user,
- "#default",
- },
- }
-}
-
-const minRPL_CHANNELMODEIS = 1
-func _RPL_CHANNELMODEIS(connection *connectionT, msg messageT) replyT {
- channel := msg.params[0]
- return replyT{
- command: "324",
- params: []string{
- connection.user.username,
- channel,
- "+Cnst",
- },
- }
-}
-
-const minRPL_NOTOPIC = 1
-func _RPL_NOTOPIC(connection *connectionT, msg messageT) replyT {
- channel := msg.params[0]
- return replyT{
- command: "331",
- params: []string{
- connection.user.username,
- channel,
- "No topic is set",
- },
- }
-}
-
-const minRPL_NAMREPLY = 1
-func _RPL_NAMREPLY(connection *connectionT, msg messageT) replyT {
- channel := msg.params[0]
- return replyT{
- command: "353",
- params: []string{
- connection.user.username,
- "=",
- channel,
- connection.user.username + " virtualuser",
- },
- }
-}
-
-const minRPL_ENDOFNAMES = 1
-func _RPL_ENDOFNAMES(connection *connectionT, msg messageT) replyT {
- channel := msg.params[0]
- return replyT{
- command: "366",
- params: []string{
- connection.user.username,
- channel,
- "End of NAMES list",
- },
- }
-}
-
-const minERR_UNKNOWNCOMMAND = 0
-func _ERR_UNKNOWNCOMMAND(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "421",
- params: []string{
- connection.user.username,
- "Unknown command",
- },
- }
-}
-
-const minERR_FILEERROR = 0
-func _ERR_FILEERROR(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "424",
- params: []string{
- "File error doing query on database",
- },
- }
-}
-
-const minERR_NOTREGISTERED = 0
-func _ERR_NOTREGISTERED(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "451",
- params: []string{
- "You have not registered",
- },
- }
-}
-
-const minERR_NEEDMOREPARAMS = 0
-func _ERR_NEEDMOREPARAMS(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "461",
- params: []string{
- msg.command,
- "Not enough parameters",
- },
- }
-}
-
-
-func _CAP(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "CAP",
- params: []string {
- "*",
- "LS",
- },
- }
-}
-
-const minPONG = 0
-func _PONG(connection *connectionT, msg messageT) replyT {
- return replyT{
- command: "PONG",
- params: msg.params,
- }
-}
-
-
-const minUSER = 4
-func handleUSER(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{
- _RPL_WELCOME (connection, msg),
- _RPL_YOURHOST(connection, msg),
- _RPL_CREATED (connection, msg),
- _RPL_MYINFO (connection, msg),
- }, false, nil
-}
-
-const minNICK = 1
-func handleNICK(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- connection.user.username = msg.params[0]
- return []replyT{}, false, nil
-}
-
-const minPRIVMSG = 2
-func handlePRIVMSG(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- // FIXME: check if user is member of channel, and is authorized to post
- // FIXME: adapt to handle multiple targets
-
- go broadcastMessage(
- msg,
- msg.params[0],
- papod.state.Deref(),
- )
- return []replyT{}, false, nil
-}
-
-const minTOPIC = 2
-func handleTOPIC(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{
- _RPL_NOTOPIC(connection, msg),
- }, false, nil
-}
-
-const minJOIN = 1
-func handleJOIN(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- // FIXME: add to database
- // channels := strings.FieldsFunc(msg.params[0], splitCommas)
- // papod.stateMutable.subscribe(connection.user.username, channels)
-
- return []replyT{
- _RPL_NOTOPIC (connection, msg),
- _RPL_NAMREPLY (connection, msg),
- _RPL_ENDOFNAMES(connection, msg),
- }, false, nil
-}
-
-const minMODE = 1
-func handleMODE(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{
- _RPL_CHANNELMODEIS(connection, msg),
- }, false, nil
-}
-
-const minWHOIS = 1
-func handleWHOIS(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{
- _RPL_WHOISUSER (connection, msg),
- _RPL_WHOISSERVER (connection, msg),
- _RPL_WHOISCHANNELS(connection, msg),
- _RPL_ENDOFWHOIS (connection, msg),
- }, false, nil
-}
-
-const minAWAY = 0
-func handleAWAY(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- replyFn := _RPL_NOWAWAY
- if len(msg.params) == 0 {
- replyFn = _RPL_UNAWAY
- }
-
- return []replyT{
- replyFn(connection, msg),
- }, false, nil
-}
-
-const minPING = 0
-func handlePING(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{
- _PONG(connection, msg),
- }, false, nil
-}
-
-const minQUIT = 0
-func handleQUIT(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- return []replyT{}, true, nil
-}
-
-const minCAP = 1
-func handleCAP(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- if msg.params[0] == "END" {
- return nil, false, nil
- }
-
- return []replyT{
- _CAP(connection, msg),
- }, false, nil
-}
-
-
-func authRequired(
- fn func(
- papodT,
- *connectionT,
- messageT,
- ) ([]replyT, bool, error),
-) func(papodT, *connectionT, messageT) ([]replyT, bool, error) {
- return func(
- papod papodT,
- connection *connectionT,
- msg messageT,
- ) ([]replyT, bool, error) {
- if connection.user == nil {
- return []replyT{
- _ERR_NOTREGISTERED(connection, msg),
- }, false, nil
- }
-
- return fn(papod, connection, msg)
- }
-}
-
-func minArgs(
- count int,
- fn func(
- papodT,
- *connectionT,
- messageT,
- ) ([]replyT, bool, error),
-) func(papodT, *connectionT, messageT) ([]replyT, bool, error) {
- return func(
- papod papodT,
- connection *connectionT,
- msg messageT,
- ) ([]replyT, bool, error) {
- if len(msg.params) < count {
- return []replyT{
- _ERR_NEEDMOREPARAMS(connection, msg),
- }, false, nil
- }
-
- return fn(papod, connection, msg)
- }
-}
-
-var commands = map[string]func(
- papodT,
- *connectionT,
- messageT,
-) ([]replyT, bool, error) {
- "USER": minArgs(minUSER, handleUSER),
- "NICK": minArgs(minNICK, handleNICK),
- "QUIT": minArgs(minQUIT, handleQUIT),
- "CAP": minArgs(minCAP, handleCAP),
- "AWAY": authRequired(minArgs(minAWAY, handleAWAY)),
- "PRIVMSG": authRequired(minArgs(minPRIVMSG, handlePRIVMSG)),
- "PING": authRequired(minArgs(minPING, handlePING)),
- "JOIN": authRequired(minArgs(minJOIN, handleJOIN)),
- "MODE": authRequired(minArgs(minMODE, handleMODE)),
- "TOPIC": authRequired(minArgs(minTOPIC, handleTOPIC)),
- "WHOIS": authRequired(minArgs(minWHOIS, handleWHOIS)),
-}
-
-func handleUnknown(
- papod papodT,
- connection *connectionT,
- msg messageT,
-) ([]replyT, bool, error) {
- // FIXME: user doesn't exist when unauthenticated
- /*
- err := papod.queries.logMessage(userT{ }, msg)
- if err != nil {
- g.Warning(
- "Failed to log message", fmt.Sprintf("%#v", msg),
- "group-as", "db-write",
- "handler-action", "log-and-ignore",
- "connection", connection.uuid.String(),
- "err", err,
- )
- }
- */
-
- return []replyT{
- _ERR_UNKNOWNCOMMAND(connection, msg),
- }, false, nil
-}
-
-func actionFnFor(
- command string,
-) func(papodT, *connectionT, messageT) ([]replyT, bool, error) {
- fn := commands[command]
- if fn != nil {
- return fn
- }
-
- return handleUnknown
-}
-
-func addTrailingSeparator(strs []string) {
- if len(strs) == 0 {
- return
- }
-
- last := strs[len(strs) - 1]
- if strings.Contains(last, " ") && last[0] != ':' {
- strs[len(strs) - 1] = ":" + last
- }
-}
-
-func (r replyT) String() string {
- addTrailingSeparator(r.params)
- return fmt.Sprintf(
- "%s %s\r\n",
- r.command,
- strings.Join(r.params, " "),
- )
-}
-
-func (m messageT) logAttributes() slog.Attr {
- return slog.Group(
- "message",
- "prefix", m.prefix,
- "raw", m.raw,
- "params", m.params,
- )
-}
-
-func (r replyT) logAttributes() slog.Attr {
- return slog.Group(
- "reply",
- "command", r.command,
- "params", r.params,
- )
-}
-
-func processMessage(
- papod papodT,
- connection *connectionT,
- rawMessage string,
-) {
- msg, err := parseMessage(rawMessage)
- if err != nil {
- g.Info(
- "Error parsing message", "parse-message-error",
- slog.Group(
- "message",
- "text", rawMessage,
- ),
- "err", err,
- )
- return
- }
- papod.metrics.receivedMessage(msg.logAttributes())
-
- var replyErrors []error
- replies, shouldClose, actionErr := actionFnFor(msg.command)(
- papod,
- connection,
- msg,
- )
- for _, reply := range replies {
- _, err = io.WriteString(connection.conn, reply.String())
- if err != nil {
- replyErrors = append(replyErrors, err)
- }
-
- papod.metrics.sentReply(
- msg.logAttributes(),
- reply.logAttributes(),
- )
- }
-
- if actionErr != nil || len(replyErrors) != 0 {
- if actionErr != nil {
- g.Info(
- "Handler returned error", "handler-error",
- "from", "daemon",
- "err", err,
- )
- }
-
- if len(replyErrors) != 0 {
- g.Info(
- "Failed to send reply", "send-reply-error",
- "from", "daemon",
- "err", replyErrors,
- )
- }
-
- stm.Swap(papod.state, func(state stateT) stateT {
- return removeConnection(state, connection)
- })
- err := connection.conn.Close()
- if err != nil {
- g.Warning(
- "Failed to close the connection",
- "close-error",
- "from", "daemon",
- "err", err,
- )
- }
-
- return
- }
-
- if shouldClose {
- // FIXME
- // papod.stateMutable.disconnect(connection)
- }
-}
-
-func processTasks() // FIXME
-
-func handleConnection(papod papodT, conn net.Conn) {
- connection := connectionT{
- uuid: uuid.New(),
- user: &userT{}, // TODO: SASL shenanigan probably goes here
- conn: conn,
- }
- scanner := bufio.NewScanner(conn)
- scanner.Split(splitOnRawMessage)
- for scanner.Scan() {
- processMessage(papod, &connection, scanner.Text())
- }
-}
-
-func daemonLoop(papod papodT) {
- for {
- conn, err := papod.listeners.daemon.Accept()
- if err != nil {
- if errors.Is(err, net.ErrClosed) {
- break
- }
-
- g.Warning(
- "Error accepting daemon connection",
- "accept-connection",
- "from", "daemon",
- "err", err,
- )
- continue
- }
- go handleConnection(papod, conn)
- }
-}
-
-func commanderLoop(papod papodT) {
- for {
- conn, err := papod.listeners.commander.Accept()
- if err != nil {
- if errors.Is(err, net.ErrClosed) {
- break
- }
-
- g.Warning(
- "Error accepting commander connection",
- "accept-connection",
- "from", "commander",
- "err", err,
- )
- continue
- }
- go handleConnection(papod, conn)
- }
-}
-
-func mkbgrun() (func(func()), func()) {
- var wg sync.WaitGroup
- bgrun := func(f func()) {
- wg.Add(1)
- go func() {
- f()
- wg.Done()
- }()
- }
- return bgrun, wg.Wait
-}
-
-func (papod papodT) Start() error {
- g.Info("Starting service", "lifecycle-event",
- "event", "starting-server",
- slog.Group(
- "versions",
- "cracha", cracha.Version,
- "uuid", uuid.Version,
- "pds", pds.Version,
- "stm", stm.Version,
- "papod", Version,
- "gobang", g.Version,
- "gotext", gt.Version,
- ),
- )
-
- run, wait := mkbgrun()
- run(func() { daemonLoop(papod) })
- run(func() { commanderLoop(papod) })
- wait()
-
- return nil
-}
-
-func (papod papodT) Close() error {
- // FIXME: does this wait for current handlers to wait? Well, it should.
- /*
- return g.WrapErrors(
- papod.listeners.close(),
- // papod.connCloser.closeAll(),
- papod.auth.Close(),
- papod.queue.Close(),
- papod.queries.close(),
- )
- */
- return nil
-}
-
-func usage(argv0 string, w io.Writer) {
- fmt.Fprintf(
- w,
- gt.Gettext("Usage: %s [-t TAG] [BASEDIR]"),
- argv0,
- )
-}
-
-func getopt(allArgs []string, w io.Writer) (argsT, int) {
- argv0 := allArgs[0]
- argv := allArgs[1:]
- fs := flag.NewFlagSet("", flag.ContinueOnError)
- fs.Usage = func() {}
- fs.SetOutput(w)
-
- tag := fs.String(
- "t",
- "",
- "The specific instance tag for inclusion in the log",
- )
- if fs.Parse(argv) != nil {
- usage(argv0, w)
- return argsT{}, 2
- }
-
- subArgs := fs.Args()
- baseDir := "."
- if len(subArgs) != 0 {
- baseDir = subArgs[0]
- }
-
- return argsT{
- allArgs: allArgs,
- subArgs: subArgs,
- baseDir: baseDir,
- tag: *tag,
- }, 0
-}
-
-func run(env envT) int {
- papod, err := newPapod(env.args.baseDir, env.args.tag)
- if err != nil {
- fmt.Fprintln(env.err, err)
- return 1
- }
-
- err = papod.Start()
- if err != nil {
- fmt.Fprintln(env.err, err)
- return 1
- }
-
- return 0
-}
-
-
-
-func Main() {
- g.Init()
- gt.Init(Name, LOCALEDIR)
- args, rc := getopt(os.Args, os.Stderr)
- g.ExitIf(rc)
- os.Exit(run(envT{
- args: args,
- in: os.Stdin,
- out: os.Stdout,
- err: os.Stderr,
- }))
-}
diff --git a/tests/benchmarks/join-leave/main.go b/tests/benchmarks/join-leave/main.go
deleted file mode 120000
index f67563d..0000000
--- a/tests/benchmarks/join-leave/main.go
+++ /dev/null
@@ -1 +0,0 @@
-../../main.go \ No newline at end of file
diff --git a/tests/benchmarks/join-leave/papod.go b/tests/benchmarks/join-leave/papod.go
deleted file mode 100644
index 7bb69cc..0000000
--- a/tests/benchmarks/join-leave/papod.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package papod
-
-import (
- "flag"
- "time"
-)
-
-
-
-var nFlag = flag.Int(
- "n",
- 1_000,
- "The number of iterations to execute",
-)
-
-func MainTest() {
- flag.Parse()
- n := *nFlag
-
- for i := 0; i < n; i++ {
- time.Sleep(time.Millisecond * 1)
- }
-}
diff --git a/tests/functional/multiple-channels-and-users/main.go b/tests/functional/multiple-channels-and-users/main.go
deleted file mode 120000
index f67563d..0000000
--- a/tests/functional/multiple-channels-and-users/main.go
+++ /dev/null
@@ -1 +0,0 @@
-../../main.go \ No newline at end of file
diff --git a/tests/functional/multiple-channels-and-users/papod.go b/tests/functional/multiple-channels-and-users/papod.go
deleted file mode 100644
index 6f6a67b..0000000
--- a/tests/functional/multiple-channels-and-users/papod.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package papod
-
-import (
- g "gobang"
-)
-
-
-
-func MainTest() {
- g.Testing("multiple users can join a channel", func() {
- })
-}
diff --git a/tests/fuzz/api-check/main.go b/tests/fuzz/api-check/main.go
deleted file mode 120000
index f67563d..0000000
--- a/tests/fuzz/api-check/main.go
+++ /dev/null
@@ -1 +0,0 @@
-../../main.go \ No newline at end of file
diff --git a/tests/fuzz/api-check/papod.go b/tests/fuzz/api-check/papod.go
deleted file mode 100644
index edab81c..0000000
--- a/tests/fuzz/api-check/papod.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package papod
-
-import (
- "os"
- "testing"
- "testing/internal/testdeps"
-)
-
-
-
-func api(f *testing.F) {
- f.Fuzz(func(t *testing.T, n int) {
- if n > 1 {
- if n < 2 {
- t.Errorf("Failed n: %v\n", n)
- }
- }
- })
-}
-
-
-
-func MainTest() {
- fuzzTargets := []testing.InternalFuzzTarget{
- { "api", api },
- }
-
- deps := testdeps.TestDeps{}
- tests := []testing.InternalTest {}
- benchmarks := []testing.InternalBenchmark{}
- examples := []testing.InternalExample {}
- m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples)
- os.Exit(m.Run())
-}
diff --git a/tests/main.go b/tests/main.go
deleted file mode 100644
index f32854e..0000000
--- a/tests/main.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package main
-
-import "papod"
-
-func main() {
- papod.MainTest()
-}
diff --git a/tests/papod.go b/tests/papod.go
deleted file mode 100644
index 3f0e557..0000000
--- a/tests/papod.go
+++ /dev/null
@@ -1,382 +0,0 @@
-package papod
-
-import (
- "bufio"
- "errors"
- "strings"
-
- g "gobang"
-)
-
-
-
-func test_splitOnCRLF() {
- g.TestStart("splitOnCRLF()")
-
- g.Testing("we need an ending \\r\\n to get output", func() {
- type tableT struct{
- input string
- expected []string
- }
- table := []tableT{
- {
- "",
- nil,
- },
- {
- "\r\n",
- []string{ "" },
- },
- {
- "abc\r\n",
- []string{ "abc" },
- },
- {
- "abc\r\n ",
- []string{ "abc" },
- },
- {
- "abc\r\n This gets ignored.\n",
- []string{ "abc" },
- },
- {
- "abc\r\n \r\n",
- []string{ "abc", " " },
- },
- {
- " \r\n \r\n",
- []string{ " ", " " },
- },
- {
- "aaa\r\nbbb\r\nccc\r\n",
- []string{ "aaa", "bbb", "ccc" },
- },
- {
- "\r\nsplit \r \n CRLF\r\n\r\n",
- []string{ "", "split \r \n CRLF", "" },
- },
- }
-
- for _, entry := range table {
- var given []string
- scanner := bufio.NewScanner(
- strings.NewReader(entry.input),
- )
- scanner.Split(splitOnCRLF)
- for scanner.Scan() {
- given = append(given, scanner.Text())
- }
-
- err := scanner.Err()
- g.TErrorIf(err)
- g.TAssertEqual(given, entry.expected)
- }
- })
-}
-
-func test_splitOnRawMessage() {
- g.TestStart("splitOnRawMessage()")
-
- g.Testing("empty messages get dropped", func() {
- type tableT struct{
- input string
- expected []string
- }
- table := []tableT{
- /*
- FIXME
- {
- "\r\nfirst\r\n\r\nsecond\r\n \r\n",
- []string{ "first", "second", " " },
- },
- */
- {
- "first message\r\nsecond message\r\n",
- []string{ "first message", "second message" },
- },
- {
- "message 1\r\n\r\nmessage 2\r\n\r\nignored",
- []string{ "message 1", "message 2" },
- },
- }
-
-
- for _, entry := range table {
- var given []string
- scanner := bufio.NewScanner(strings.NewReader(
- entry.input,
- ))
- scanner.Split(splitOnRawMessage)
- for scanner.Scan() {
- given = append(given, scanner.Text())
- }
-
- err := scanner.Err()
- g.TErrorIf(err)
- g.TAssertEqual(given, entry.expected)
- }
- })
-}
-
-func test_parseMessageParams() {
- g.TestStart("parseMessageParams()")
-
- g.Testing("we can parse the string params", func() {
- type tableT struct{
- input string
- expected []string
- }
- table := []tableT{
- { "", []string{} },
- { " ", []string{} },
- { " :", []string{ "" } },
- { " : ", []string{ " " } },
- { ": ", []string{ ":" } },
- { ": ", []string{ ":" } },
- { " : ", []string{ " " } },
- { " :", []string{ "" } },
- { " :", []string{ "" } },
- { "a", []string{ "a" } },
- { "ab", []string{ "ab" } },
- { "a b", []string{ "a", "b" } },
- { "a b c", []string{ "a", "b", "c" } },
- { "a b:c", []string{ "a", "b:c" } },
- { "a b:c:", []string{ "a", "b:c:" } },
- { "a b :c", []string{ "a", "b", "c" } },
- { "a b :c:", []string{ "a", "b", "c:" } },
- { "a b :c ", []string{ "a", "b", "c " } },
- { "a b : c", []string{ "a", "b", " c" } },
- { "a b : c ", []string{ "a", "b", " c " } },
- { "a b : c :", []string{ "a", "b", " c :" } },
- { "a b : c : ", []string{ "a", "b", " c : " } },
- { "a b : c :d", []string{ "a", "b", " c :d" } },
- { "a b : c :d ", []string{ "a", "b", " c :d " } },
- { "a b : c : d ", []string{ "a", "b", " c : d " } },
- }
-
- for _, entry := range table {
- given := parseMessageParams(entry.input)
- g.TAssertEqual(given, entry.expected)
- }
- })
-}
-
-func test_parseMessage() {
- g.TestStart("parseMessage()")
-
- g.Testing("we can parse a full message", func() {
- type tableTOK struct{
- input string
- expected messageT
- }
- tableOK := []tableTOK {{
- "NICK joebloe ",
- messageT{
- prefix: "",
- command: "NICK",
- params: []string{ "joebloe" },
- raw: "NICK joebloe ",
- },
- }, {
- "USER joebloe 0.0.0.0 joe :Joe Bloe",
- messageT{
- prefix: "",
- command: "USER",
- params: []string{
- "joebloe",
- "0.0.0.0",
- "joe",
- "Joe Bloe",
- },
- raw: "USER joebloe 0.0.0.0 joe :Joe Bloe",
- },
- }, {
- ":pre USER joebloe 0.0.0.0 joe :Joe Bloe",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{
- "joebloe",
- "0.0.0.0",
- "joe",
- "Joe Bloe",
- },
- raw: ":pre USER joebloe 0.0.0.0 joe :Joe Bloe",
- },
- }, {
- ":pre USER joebloe 0.0.0.0 joe : Joe Bloe ",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{
- "joebloe",
- "0.0.0.0",
- "joe",
- " Joe Bloe ",
- },
- raw: ":pre USER joebloe 0.0.0.0 " +
- "joe : Joe Bloe ",
- },
- }, {
- ":pre USER jbloe: 0:0:0:1 joe::a: : Joe Bloe ",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{
- "jbloe:",
- "0:0:0:1",
- "joe::a:",
- " Joe Bloe ",
- },
- raw: ":pre USER jbloe: 0:0:0:1 " +
- "joe::a: : Joe Bloe ",
- },
- }, {
- ":pre USER :Joe Bloe",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{ "Joe Bloe" },
- raw: ":pre USER :Joe Bloe",
- },
- }, {
- ":pre USER : Joe Bloe",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{ " Joe Bloe" },
- raw: ":pre USER : Joe Bloe",
- },
- }, {
- ":pre USER : Joe Bloe",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{ " Joe Bloe" },
- raw: ":pre USER : Joe Bloe",
- },
- }, {
- ":pre USER : ",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{ " " },
- raw: ":pre USER : ",
- },
- }, {
- ":pre USER :",
- messageT{
- prefix: "pre",
- command: "USER",
- params: []string{},
- raw: ":pre USER :",
- },
- }}
-
- for _, entry := range tableOK {
- given, err := parseMessage(entry.input)
- g.TErrorIf(err)
- g.TAssertEqual(given, entry.expected)
- }
- })
-
-
- g.Testing("bad messages are rejected", func() {
- type tableErrorT struct{
- input string
- expected error
- }
- parseErr := errors.New("Can't parse message")
- tableError := []tableErrorT{
- {
- ":pre",
- parseErr,
- },
- {
- ": pre",
- parseErr,
- },
- {
- ":pre N1CK",
- parseErr,
- },
- }
-
- for _, entry := range tableError {
- _, given := parseMessage(entry.input)
- g.TAssertEqual(given, entry.expected)
- }
- })
-}
-
-func test_addTrailingSeparator() {
- g.TestStart("addTrailingSeparator()")
-
- g.Testing("noop on empty slice", func() {
- input := []string{}
- addTrailingSeparator(input)
- g.TAssertEqual(input, []string{})
- })
-
- g.Testing("noop if last doesn't have a space", func() {
- type tableT struct{
- input []string
- expected []string
- }
-
- entries := []tableT{
- { []string{ "" }, []string{ "" } },
- { []string{ "", "" }, []string{ "", "" } },
- { []string{ "a", "b" }, []string{ "a", "b" } },
- {
- []string{ "a", "b", "c-d" },
- []string{ "a", "b", "c-d" },
- },
- {
- []string{ "a ", "b", "cd" },
- []string{ "a ", "b", "cd" },
- },
- }
-
- for i, entry := range entries {
- addTrailingSeparator(entry.input)
- g.TAssertEqual(entry.input, entries[i].expected)
- }
- })
-
- g.Testing("add ':' to the last otherwise", func() {
- type tableT struct{
- input []string
- expected []string
- }
-
- entries := []tableT{
- { []string{ " " }, []string{ ": " } },
- { []string{ "a " }, []string{ ":a " } },
- { []string{ " a" }, []string{ ": a" } },
- { []string{ "a ", " b" }, []string{ "a ", ": b" } },
- { []string{ "a", " b" }, []string{ "a", ": b" } },
- {
- []string{ "a", "b", "c d" },
- []string{ "a", "b", ":c d" },
- },
- }
-
- for i, entry := range entries {
- addTrailingSeparator(entry.input)
- addTrailingSeparator(entry.input)
- g.TAssertEqual(entry.input, entries[i].expected)
- }
- })
-}
-
-
-
-func MainTest() {
- g.Init()
- test_splitOnCRLF()
- test_splitOnRawMessage()
- test_parseMessageParams()
- test_parseMessage()
- test_addTrailingSeparator()
-}
diff --git a/tests/queries.sql b/tests/queries.sql
deleted file mode 100644
index 992c8d2..0000000
--- a/tests/queries.sql
+++ /dev/null
@@ -1,1230 +0,0 @@
-
--- createTables.sql:
--- write:
- -- TODO: unconfirmed premise: statements within a trigger are
- -- part of the transaction that caused it, and so are
- -- atomic.
- -- See also:
- -- https://stackoverflow.com/questions/77441888/
- -- https://stackoverflow.com/questions/30511116/
-
- CREATE TABLE IF NOT EXISTS "papod_users" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- -- provided by cracha
- user_uuid BLOB NOT NULL UNIQUE,
- username TEXT NOT NULL,
- display_name TEXT NOT NULL,
- picture_uuid BLOB UNIQUE,
- deleted INT NOT NULL CHECK(deleted IN (0, 1))
- ) STRICT;
- CREATE TABLE IF NOT EXISTS "papod_user_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- user_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'username',
- 'display_name',
- 'picture_uuid',
- 'deleted'
- )
- ),
- value_text TEXT,
- value_blob BLOB,
- value_bool INT CHECK(value_bool IN (0, 1)),
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
- CREATE TRIGGER IF NOT EXISTS "papod_user_new"
- AFTER INSERT ON "papod_users"
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'username', NEW.username, true),
- (NEW.id, 'display_name', NEW.display_name, true)
- ;
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_bool, op
- ) VALUES
- (NEW.id, 'deleted', NEW.deleted, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_new_picture_uuid"
- AFTER INSERT ON "papod_users"
- WHEN NEW.picture_uuid IS NOT NULL
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_update_username"
- AFTER UPDATE ON "papod_users"
- WHEN OLD.username != NEW.username
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'username', OLD.username, false),
- (NEW.id, 'username', NEW.username, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_update_display_name"
- AFTER UPDATE ON "papod_users"
- WHEN OLD.display_name != NEW.display_name
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'display_name', OLD.display_name, false),
- (NEW.id, 'display_name', NEW.display_name, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_add_picture_uuid"
- AFTER UPDATE ON "papod_users"
- WHEN (
- OLD.picture_uuid IS NULL AND
- NEW.picture_uuid IS NOT NULL
- )
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_remove_picture_uuid"
- AFTER UPDATE ON "papod_users"
- WHEN (
- OLD.picture_uuid IS NOT NULL AND
- NEW.picture_uuid IS NULL
- )
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', OLD.picture_uuid, false)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_update_picture_uuid"
- AFTER UPDATE ON "papod_users"
- WHEN (
- OLD.picture_uuid IS NOT NULL AND
- NEW.picture_uuid IS NOT NULL AND
- OLD.picture_uuid != NEW.picture_uuid
- )
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', OLD.picture_uuid, false),
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_user_update_deleted"
- AFTER UPDATE ON "papod_users"
- WHEN OLD.deleted != NEW.deleted
- BEGIN
- INSERT INTO "papod_user_changes" (
- user_id, attribute, value_bool, op
- ) VALUES
- (NEW.id, 'deleted', OLD.deleted, false),
- (NEW.id, 'deleted', NEW.deleted, true)
- ;
- END;
-
- CREATE TABLE IF NOT EXISTS "papod_sessions" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- -- provided by cracha
- session_uuid BLOB NOT NULL UNIQUE,
- user_id INTEGER NOT NULL
- REFERENCES "papod_users"(id),
- finished_at TEXT
- );
- CREATE TABLE IF NOT EXISTS "papod_connections" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- uuid BLOB NOT NULL UNIQUE,
- finished_at TEXT
- );
- CREATE TABLE IF NOT EXISTS "papod_logons" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- session_id INTEGER NOT NULL
- REFERENCES "papod_sessions"(id),
- connection_id INTEGER NOT NULL
- REFERENCES "papod_connections"(id),
- UNIQUE (session_id, connection_id)
- ) STRICT;
-
- CREATE TABLE IF NOT EXISTS "papod_networks" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- uuid BLOB NOT NULL UNIQUE,
- name TEXT NOT NULL,
- description TEXT NOT NULL,
- type TEXT NOT NULL CHECK(
- type IN ('public', 'private', 'unlisted')
- ),
- deleted INT NOT NULL CHECK(deleted IN (0, 1))
- ) STRICT;
- CREATE INDEX IF NOT EXISTS "papod_networks_type"
- ON "papod_networks"(type);
- CREATE TABLE IF NOT EXISTS "papod_network_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- network_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'name',
- 'description',
- 'type',
- 'deleted',
- 'logon_id' -- FIXME
- )
- ),
- value TEXT NOT NULL,
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
- CREATE TRIGGER IF NOT EXISTS "papod_network_new"
- AFTER INSERT ON "papod_networks"
- BEGIN
- INSERT INTO "papod_network_changes" (
- network_id, attribute, value, op
- ) VALUES
- (NEW.id, 'name', NEW.name, true),
- (NEW.id, 'description', NEW.description, true),
- (NEW.id, 'type', NEW.type, true),
- (NEW.id, 'deleted', NEW.deleted, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_network_update_name"
- AFTER UPDATE ON "papod_networks"
- WHEN OLD.name != NEW.name
- BEGIN
- INSERT INTO "papod_network_changes" (
- network_id, attribute, value, op
- ) VALUES
- (NEW.id, 'name', OLD.name, false),
- (NEW.id, 'name', NEW.name, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_network_update_description"
- AFTER UPDATE ON "papod_networks"
- WHEN OLD.description != NEW.description
- BEGIN
- INSERT INTO "papod_network_changes" (
- network_id, attribute, value, op
- ) VALUES
- (NEW.id, 'description', OLD.description, false),
- (NEW.id, 'description', NEW.description, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_network_update_type"
- AFTER UPDATE ON "papod_networks"
- WHEN OLD.description != NEW.description
- BEGIN
- INSERT INTO "papod_network_changes" (
- network_id, attribute, value, op
- ) VALUES
- (NEW.id, 'type', OLD.type, false),
- (NEW.id, 'type', NEW.type, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_network_update_deleted"
- AFTER UPDATE ON "papod_networks"
- WHEN OLD.deleted != NEW.deleted
- BEGIN
- INSERT INTO "papod_network_changes" (
- network_id, attribute, value, op
- ) VALUES
- (NEW.id, 'deleted', OLD.deleted, false),
- (NEW.id, 'deleted', NEW.deleted, true)
- ;
- END;
-
- CREATE TABLE IF NOT EXISTS "papod_members" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- uuid BLOB NOT NULL UNIQUE,
- network_id INTEGER NOT NULL
- REFERENCES "papod_networks"(id),
- user_id INTEGER NOT NULL,
- username TEXT NOT NULL,
- display_name TEXT NOT NULL,
- picture_uuid BLOB UNIQUE,
- status TEXT NOT NULL CHECK(
- status IN ('active', 'inactive', 'removed')
- ),
- active_uniq TEXT CHECK(
- active_uniq IN ('active', NULL)
- ),
- UNIQUE (network_id, username, active_uniq),
- UNIQUE (network_id, user_id)
- ) STRICT;
- CREATE TABLE IF NOT EXISTS "papod_member_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- member_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'username',
- 'display_name',
- 'picture_uuid',
- 'status',
- 'logon_id' -- FIXME
- )
- ),
- value_text TEXT,
- value_blob BLOB,
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
- CREATE TRIGGER IF NOT EXISTS "papod_member_new"
- AFTER INSERT ON "papod_members"
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'username', NEW.username, true),
- (NEW.id, 'display_name', NEW.display_name, true),
- (NEW.id, 'status', NEW.status, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_new_picture_uuid"
- AFTER INSERT ON "papod_members"
- WHEN NEW.picture_uuid IS NOT NULL
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_update_username"
- AFTER UPDATE ON "papod_members"
- WHEN OLD.username != NEW.username
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'username', OLD.username, false),
- (NEW.id, 'username', NEW.username, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_update_display_name"
- AFTER UPDATE ON "papod_members"
- WHEN OLD.display_name != NEW.display_name
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'display_name', OLD.display_name, false),
- (NEW.id, 'display_name', NEW.display_name, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_update_status"
- AFTER UPDATE ON "papod_members"
- WHEN OLD.status != NEW.status
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'status', OLD.status, false),
- (NEW.id, 'status', NEW.status, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_add_picture_uuid"
- AFTER UPDATE ON "papod_members"
- WHEN (
- OLD.picture_uuid IS NULL AND
- NEW.picture_uuid IS NOT NULL
- )
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_remove_picture_uuid"
- AFTER UPDATE ON "papod_members"
- WHEN (
- OLD.picture_uuid IS NOT NULL AND
- NEW.picture_uuid IS NULL
- )
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', OLD.picture_uuid, false)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_update_picture_uuid"
- AFTER UPDATE ON "papod_members"
- WHEN (
- OLD.picture_uuid IS NOT NULL AND
- NEW.picture_uuid IS NOT NULL AND
- OLD.picture_uuid != NEW.picture_uuid
- )
- BEGIN
- INSERT INTO "papod_member_changes" (
- member_id, attribute, value_blob, op
- ) VALUES
- (NEW.id, 'picture_uuid', OLD.picture_uuid, false),
- (NEW.id, 'picture_uuid', NEW.picture_uuid, true)
- ;
- END;
-
- CREATE TABLE IF NOT EXISTS "papod_member_roles" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- member_id INTEGER NOT NULL
- REFERENCES "papod_members"(id),
- role TEXT NOT NULL,
- UNIQUE (member_id, role)
- ) STRICT;
- CREATE TABLE IF NOT EXISTS "papod_member_role_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- role_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'role',
- 'logon_id' -- FIXME
- )
- ),
- value TEXT NOT NULL,
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
- CREATE TRIGGER IF NOT EXISTS "papod_member_role_add"
- AFTER INSERT ON "papod_member_roles"
- BEGIN
- INSERT INTO "papod_member_role_changes" (
- role_id, attribute, value, op
- ) VALUES
- (NEW.id, 'role', NEW.role, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_member_role_remove"
- AFTER DELETE ON "papod_member_roles"
- BEGIN
- INSERT INTO "papod_member_role_changes" (
- role_id, attribute, value, op
- ) VALUES
- (OLD.id, 'role', OLD.role, false)
- ;
- END;
-
- CREATE TABLE IF NOT EXISTS "papod_channels" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- uuid BLOB NOT NULL UNIQUE,
- network_id INTEGER NOT NULL
- REFERENCES "papod_networks"(id),
- public_name TEXT,
- label TEXT NOT NULL,
- description TEXT NOT NULL,
- virtual INT NOT NULL CHECK(virtual IN (0, 1)),
- UNIQUE (network_id, public_name)
- ) STRICT;
- CREATE TABLE IF NOT EXISTS "papod_channel_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- channel_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'public_name',
- 'label',
- 'description',
- 'virtual',
- 'logon_id' -- FIXME
- )
- ),
- value_text TEXT,
- value_bool INT CHECK(value_bool IN (0, 1)),
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_new"
- AFTER INSERT ON "papod_channels"
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'label', NEW.label, true),
- (NEW.id, 'description', NEW.description, true)
- ;
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_bool, op
- ) VALUES
- (NEW.id, 'virtual', NEW.virtual, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_new_public_name"
- AFTER INSERT ON "papod_channels"
- WHEN NEW.public_name IS NOT NULL
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'public_name', NEW.public_name, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_update_label"
- AFTER UPDATE ON "papod_channels"
- WHEN OLD.label != NEW.label
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'label', OLD.label, false),
- (NEW.id, 'label', NEW.label, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_update_description"
- AFTER UPDATE ON "papod_channels"
- WHEN OLD.description != NEW.description
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'description', OLD.description, false),
- (NEW.id, 'description', NEW.description, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_update_virtual"
- AFTER UPDATE ON "papod_channels"
- WHEN OLD.virtual != NEW.virtual
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_bool, op
- ) VALUES
- (NEW.id, 'virtual', OLD.virtual, false),
- (NEW.id, 'virtual', NEW.virtual, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_add_public_name"
- AFTER UPDATE ON "papod_channels"
- WHEN (
- OLD.public_name IS NULL AND
- NEW.public_name IS NOT NULL
- )
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (NEW.id, 'public_name', NEW.public_name, true)
- ;
- END;
- CREATE TRIGGER IF NOT EXISTS "papod_channel_remove_public_name"
- AFTER UPDATE ON "papod_channels"
- WHEN (
- OLD.public_name IS NOT NULL AND
- NEW.public_name IS NULL
- )
- BEGIN
- INSERT INTO "papod_channel_changes" (
- channel_id, attribute, value_text, op
- ) VALUES
- (OLD.id, 'public_name', OLD.public_name, false)
- ;
- END;
-
- CREATE TABLE IF NOT EXISTS "papod_participants" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- channel_id INTEGER NOT NULL
- REFERENCES "papod_channels"(id),
- member_id INTEGER NOT NULL
- REFERENCES "papod_members"(id),
- UNIQUE (channel_id, member_id)
- ) STRICT;
- CREATE TABLE IF NOT EXISTS "papod_participant_changes" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- participant_id INTEGER NOT NULL,
- attribute TEXT NOT NULL CHECK(
- attribute IN (
- 'connection_id'
- )
- ),
- value TEXT NOT NULL,
- op INT NOT NULL CHECK(op IN (0, 1))
- ) STRICT;
-
- CREATE TABLE IF NOT EXISTS "papod_channel_events" (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT NOT NULL DEFAULT (
- strftime('%Y-%m-%dT%H:%M:%f000000Z', 'now')
- ),
- uuid BLOB NOT NULL UNIQUE,
- channel_id INTEGER NOT NULL
- REFERENCES "papod_channels"(id),
- source_uuid BLOB NOT NULL,
- source_type TEXT NOT NULL CHECK(
- source_type IN (
- 'logon'
- )
- ),
- source_metadata TEXT,
- type TEXT NOT NULL CHECK(
- type IN (
- 'user-join',
- 'user-message'
- )
- ),
- payload TEXT NOT NULL,
- metadata TEXT
- ) STRICT;
-
-
-
--- read:
-
--- memberRoles.sql:
--- write:
-
--- read:
- SELECT role FROM "papod_member_roles"
- JOIN "papod_members" ON
- "papod_member_roles".member_id = "papod_members".id
- WHERE "papod_members".uuid = ?
- ORDER BY "papod_member_roles".id;
-
-
--- createUser.sql:
--- write:
- INSERT INTO "papod_users" (
- user_uuid, username, display_name, picture_uuid, deleted
- ) VALUES (
- ?, ?, ?, NULL, false
- ) RETURNING id, timestamp;
-
-
--- read:
-
--- userByUUID.sql:
--- write:
-
--- read:
- SELECT
- id,
- timestamp,
- username,
- display_name,
- picture_uuid
- FROM "papod_users"
- WHERE
- user_uuid = ? AND
- deleted = false;
-
-
--- updateUser.sql:
--- write:
- UPDATE "papod_users"
- SET
- username = ?,
- display_name = ?,
- picture_uuid = ?
- WHERE
- id = ? AND
- deleted = false
- RETURNING id;
-
-
--- read:
-
--- deleteUser.sql:
--- write:
- UPDATE "papod_users"
- SET deleted = true
- WHERE
- user_uuid = ? AND
- deleted = false
- RETURNING id;
-
-
--- read:
-
--- addNetwork.sql:
--- write:
- INSERT INTO "papod_networks" (
- uuid, name, description, type, deleted
- )
- VALUES (
- ?,
- ?,
- ?,
- ?,
- false
- ) RETURNING id;
-
- WITH creator AS (
- SELECT username, display_name, picture_uuid
- FROM "papod_users"
- WHERE id = ? AND deleted = false
- ), new_network AS (
- SELECT id FROM "papod_networks" WHERE uuid = ?
- )
- INSERT INTO "papod_members" (
- uuid, network_id, user_id, username, display_name,
- picture_uuid, status, active_uniq
- ) VALUES (
- ?,
- (SELECT id FROM new_network),
- ?,
- (SELECT username FROM creator),
- (SELECT display_name FROM creator),
- (SELECT picture_uuid FROM creator),
- 'active',
- 'active'
- ) RETURNING id;
-
- WITH new_member AS (
- SELECT id FROM "papod_members" WHERE uuid = ?
- )
- INSERT INTO "papod_member_roles" (member_id, role)
- VALUES (
- (SELECT id FROM new_member),
- 'admin'
- ),
- (
- (SELECT id FROM new_member),
- 'creator'
- )
- RETURNING id;
-
-
--- read:
- SELECT id, timestamp FROM "papod_networks"
- WHERE uuid = ? AND deleted = false;
-
-
--- getNetwork.sql:
--- write:
-
--- read:
- WITH probing_user AS (
- SELECT id FROM "papod_users"
- WHERE id = ? AND deleted = false
- ), target_network AS (
- SELECT id FROM "papod_networks"
- WHERE uuid = ? AND deleted = false
- )
- SELECT
- id,
- timestamp,
- name,
- description,
- type
- FROM "papod_networks"
- WHERE
- uuid = ? AND
- deleted = false AND
- ? IN probing_user AND
- (
- type IN ('public', 'unlisted') OR
- ? IN (
- SELECT user_id FROM "papod_members"
- WHERE
- user_id = ? AND
- network_id IN target_network AND
- status != 'removed'
- )
- );
- %!(EXTRA string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod, string=papod)
-
--- networks.sql:
--- write:
-
--- read:
- WITH current_user AS (
- SELECT id, deleted FROM "papod_users" WHERE id = ?
- )
- SELECT
- "papod_networks".id,
- "papod_networks".timestamp,
- "papod_networks".uuid,
- "papod_networks".name,
- "papod_networks".description,
- "papod_networks".type,
- (SELECT deleted FROM current_user)
- FROM "papod_networks"
- JOIN "papod_members" ON
- "papod_networks".id = "papod_members".network_id
- WHERE (
- "papod_networks".type = 'public' OR
- "papod_networks".id IN (
- SELECT network_id FROM "papod_members"
- WHERE user_id IN (SELECT id FROM current_user)
- )
- ) AND "papod_networks".deleted = false
- ORDER BY "papod_networks".id;
-
-
--- setNetwork.sql:
--- write:
- UPDATE "papod_networks"
- SET
- name = ?,
- description = ?,
- type = ?
- WHERE id = ? AND deleted = false
- RETURNING (
- SELECT CASE WHEN EXISTS (
- SELECT role from "papod_member_roles"
- WHERE
- member_id = ? AND
- role IN (
- 'admin',
- 'network-settings-update'
- ) AND ? IN (
- SELECT network_id
- FROM "papod_members"
- WHERE
- id = ? AND
- status = 'active'
- )
- ) THEN true ELSE RAISE(
- ABORT,
- 'member not allowed to update network data'
- ) END
- );
-
-
-
--- read:
-
--- nipNetwork.sql:
--- write:
- WITH target_network AS (
- SELECT network_id AS id
- FROM "papod_members"
- WHERE
- id = ? AND
- status = 'active'
- )
- UPDATE "papod_networks"
- SET deleted = true
- WHERE id IN target_network AND deleted = false
- RETURNING (
- SELECT CASE WHEN EXISTS (
- SELECT role FROM "papod_member_roles"
- WHERE
- member_id = ? AND
- role IN (
- 'admin'
- )
- ) THEN true ELSE RAISE(
- ABORT,
- 'member not allowed to delete network'
- ) END
- );
-
-
--- read:
-
--- membership.sql:
--- write:
-
--- read:
- SELECT
- "papod_members".id,
- "papod_members".timestamp,
- "papod_members".uuid,
- "papod_members".username,
- "papod_members".display_name,
- "papod_members".picture_uuid,
- "papod_members".status
- FROM "papod_members"
- JOIN "papod_users" ON
- "papod_users".id = "papod_members".user_id
- JOIN "papod_networks" ON
- "papod_networks".id = "papod_members".network_id
- WHERE
- "papod_members".user_id = ? AND
- "papod_members".network_id = ? AND
- "papod_members".status = 'active' AND
- "papod_users".deleted = false AND
- "papod_networks".deleted = false;
-
-
--- addMember.sql:
--- write:
- WITH target_user AS (
- SELECT id, username, display_name, picture_uuid
- FROM "papod_users"
- WHERE user_uuid = ? AND deleted = false
- ), target_network AS (
- SELECT "papod_members".network_id AS id
- FROM "papod_members"
- JOIN "papod_networks" ON
- "papod_members".network_id = "papod_networks".id
- WHERE
- "papod_members".id = ? AND
- "papod_members".status = 'active' AND
- "papod_networks".deleted = false
- )
- INSERT INTO "papod_members" (
- uuid, network_id, user_id, username, display_name,
- picture_uuid, status, active_uniq
- ) VALUES (
- ?,
- (SELECT id FROM target_network),
- (SELECT id FROM target_user),
- ?,
- (SELECT display_name FROM target_user),
- (SELECT picture_uuid FROM target_user),
- 'active',
- 'active'
- ) RETURNING id, timestamp, display_name, picture_uuid, status, (
- SELECT CASE WHEN EXISTS (
- SELECT role from "papod_member_roles"
- WHERE
- member_id = ? AND
- role IN (
- 'admin',
- 'add-member'
- )
- ) THEN true ELSE RAISE(
- ABORT,
- 'member not allowed to add another member'
- ) END
- );
-
-
--- read:
-
--- addRole.sql:
--- write:
- INSERT INTO "papod_member_roles" (member_id, role)
- VALUES (?, ?);
-
-
--- read:
-
--- dropRole.sql:
--- write:
- DELETE FROM "papod_member_roles"
- WHERE
- member_id = ? AND
- role = ?
- RETURNING 1;
-
-
--- read:
-
--- showMember.sql:
--- write:
-
--- read:
- WITH current_network AS (
- SELECT network_id
- FROM "papod_members"
- WHERE id = ?
- )
- SELECT
- id,
- timestamp,
- username,
- display_name,
- picture_uuid,
- status
- FROM "papod_members"
- WHERE
- uuid = ? AND
- network_id IN current_network;
-
-
--- members.sql:
--- write:
-
--- read:
- WITH target_network AS (
- SELECT "papod_members".network_id
- FROM "papod_members"
- JOIN "papod_networks" ON
- "papod_members".network_id = "papod_networks".id
- WHERE
- "papod_members".id = ? AND
- "papod_networks".deleted = false
- )
- SELECT
- id,
- timestamp,
- uuid,
- username,
- display_name,
- picture_uuid,
- status
- FROM "papod_members"
- WHERE
- network_id IN target_network AND
- status = 'active';
-
-
--- editMember.sql:
--- write:
- UPDATE "papod_members"
- SET
- status = ?
- WHERE id = ?
- RETURNING id;
-
-
--- read:
-
--- dropMember.sql:
--- write:
- UPDATE "papod_members" SET status = 'removed'
- WHERE uuid = ? RETURNING id;
-
- DELETE FROM "papod_member_roles"
- WHERE
- role != 'creator' AND
- member_id IN (
- SELECT id FROM "papod_members"
- WHERE uuid = ?
- )
-
-
--- read:
-
--- addChannel.sql:
--- write:
- WITH target_network AS (
- SELECT network_id AS id
- FROM "papod_members"
- WHERE id = ?
- )
- INSERT INTO "papod_channels" (
- uuid,
- network_id,
- public_name,
- label,
- description,
- virtual
- ) VALUES (
- ?,
- (SELECT id FROM target_network),
- ?,
- ?,
- ?,
- ?
- ) RETURNING id, timestamp;
-
- WITH new_channel AS (
- SELECT id FROM "papod_channels" WHERE uuid = ?
- )
- INSERT INTO "papod_participants" (channel_id, member_id)
- VALUES (
- (SELECT id FROM new_channel),
- ?
- );
-
-
--- read:
- SELECT id, timestamp FROM "papod_channels"
- WHERE uuid = ?;
-
-
--- channels.sql:
--- write:
-
--- read:
- WITH current_network AS (
- SELECT network_id AS id
- FROM "papod_members"
- WHERE id = ?
- ), member_private_channels AS (
- SELECT channel_id AS id
- FROM "papod_participants"
- WHERE member_id = ?
- )
- SELECT
- id,
- timestamp,
- uuid,
- public_name,
- label,
- description,
- virtual
- FROM "papod_channels"
- WHERE
- network_id IN current_network AND
- (
- public_name IS NOT NULL OR
- id IN member_private_channels
- )
- ORDER BY id;
-
-
--- setChannel.sql:
--- write:
- WITH participant_channel AS (
- SELECT channel_id AS id
- FROM "papod_participants"
- WHERE
- member_id = ? AND
- channel_id = ?
- )
- UPDATE "papod_channels"
- SET
- description = ?,
- public_name = ?
- WHERE id IN participant_channel
- RETURNING id;
-
-
--- read:
- SELECT (
- SELECT network_id AS id
- FROM "papod_channels"
- WHERE id = ?
- ) AS channel_network_id, (
- SELECT network_id AS id
- FROM "papod_members"
- WHERE id = ?
- ) AS member_network_id;
-
-
--- endChannel.sql:
--- write:
- -- FIXME papod
-
-
--- read:
-
--- join.sql:
--- write:
- WITH target_channel AS (
- SELECT id
- FROM "papod_channels"
- WHERE
- uuid = ? AND
- public_name IS NOT NULL
- )
- INSERT INTO "papod_participants" (channel_id, member_id)
- VALUES (
- (SELECT id FROM target_channel),
- ?
- ) RETURNING id;
-
-
--- read:
- SELECT (
- SELECT network_id AS id
- FROM "papod_channels"
- WHERE
- uuid = ? AND
- public_name IS NOT NULL
- ) AS channel_network_id, (
- SELECT network_id AS id
- FROM "papod_members" WHERE id = ?
- ) AS member_network_id;
-
-
--- part.sql:
--- write:
- WITH target_channel AS (
- SELECT id
- FROM "papod_channels"
- WHERE
- id = ? AND
- virtual = false
- )
- DELETE FROM "papod_participants"
- WHERE
- member_id = ? AND
- channel_id IN target_channel
- RETURNING 1;
-
-
--- read:
-
--- names.sql:
--- write:
-
--- read:
- -- FIXME papod
-
-
--- addEvent.sql:
--- write:
- INSERT INTO "papod_channel_events" (
- uuid, channel_id, source_uuid, source_type,
- source_metadata, type, payload, metadata
- ) VALUES (
- ?,
- (SELECT id FROM "papod_channels" WHERE uuid = ?),
- ?,
- ?,
- ?,
- ?,
- ?,
- ?
- ) RETURNING id, timestamp;
-
-
--- read:
-
--- allAfter.sql:
--- write:
-
--- read:
- WITH landmark_event AS (
- SELECT id, channel_id
- FROM "papod_channel_events"
- WHERE uuid = ?
- )
- SELECT
- "papod_channel_events".id,
- "papod_channel_events".timestamp,
- "papod_channel_events".uuid,
- "papod_channels".uuid,
- -- "papod_channel_events".connection_uuid,
- "papod_channel_events".type,
- "papod_channel_events".payload
- FROM "papod_channel_events"
- JOIN "papod_channels" ON
- "papod_channel_events".channel_id = "papod_channels".id
- WHERE
- "papod_channel_events".id > (
- SELECT id FROM landmark_event
- ) AND channel_id = (
- SELECT channel_id FROM landmark_event
- );
-
-
--- logMessage.sql:
--- write:
- -- FIXME papod
-
-
--- read: