PostgreSQL compatibility #5
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/niklasfasching/go-org/org"
|
||||
"github.com/russross/blackfriday"
|
||||
_ "modernc.org/sqlite"
|
||||
_ "github.com/lib/pq"
|
||||
"tailscale.com/client/tailscale"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
|
@ -40,6 +41,7 @@ var (
|
|||
tsnetLogVerbose = flag.Bool("tsnet-verbose", hasEnv("TSNET_VERBOSE"), "if set, have tsnet log verbosely to standard error")
|
||||
useFunnel = flag.Bool("use-funnel", hasEnv("USE_FUNNEL"), "if set, expose individual pastes to the public internet with Funnel, USE_FUNNEL in the environment")
|
||||
hidePasteUserInfo = flag.Bool("hide-funnel-users", hasEnv("HIDE_FUNNEL_USERS"), "if set, display the username and profile picture of the user who created the paste in funneled pastes")
|
||||
databaseUrl = flag.String("database-url", envOr("DATABASE_URL", ""), "optional database url if you'd rather use Postgres instead of sqlite")
|
||||
|
||||
//go:embed schema.sql
|
||||
sqlSchema string
|
||||
|
@ -105,7 +107,7 @@ SELECT p.id
|
|||
FROM pastes p
|
||||
INNER JOIN users u
|
||||
ON p.user_id = u.id
|
||||
ORDER BY p.rowid DESC
|
||||
ORDER BY p.created_at DESC
|
||||
LIMIT 5
|
||||
`
|
||||
|
||||
|
@ -239,11 +241,11 @@ INSERT INTO pastes
|
|||
, data
|
||||
)
|
||||
VALUES
|
||||
( ?1
|
||||
, ?2
|
||||
, ?3
|
||||
, ?4
|
||||
, ?5
|
||||
( $1
|
||||
, $2
|
||||
, $3
|
||||
, $4
|
||||
, $5
|
||||
)`
|
||||
|
||||
_, err = s.db.ExecContext(
|
||||
|
@ -296,9 +298,9 @@ SELECT p.id
|
|||
FROM pastes p
|
||||
INNER JOIN users u
|
||||
ON p.user_id = u.id
|
||||
ORDER BY p.rowid DESC
|
||||
ORDER BY p.created_at DESC
|
||||
LIMIT 25
|
||||
OFFSET ?1
|
||||
OFFSET $1
|
||||
`
|
||||
|
||||
uq := r.URL.Query()
|
||||
|
@ -434,7 +436,7 @@ func (s *Server) TailnetDeletePost(w http.ResponseWriter, r *http.Request) {
|
|||
q := `
|
||||
SELECT p.user_id
|
||||
FROM pastes p
|
||||
WHERE p.id = ?1`
|
||||
WHERE p.id = $1`
|
||||
|
||||
row := s.db.QueryRowContext(r.Context(), q, id)
|
||||
var userIDOfPaste int64
|
||||
|
@ -450,7 +452,7 @@ WHERE p.id = ?1`
|
|||
|
||||
q = `
|
||||
DELETE FROM pastes
|
||||
WHERE id = ?1 AND user_id = ?2
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
if _, err := s.db.ExecContext(r.Context(), q, id, ui.UserProfile.ID); err != nil {
|
||||
|
@ -502,7 +504,7 @@ SELECT p.filename
|
|||
FROM pastes p
|
||||
INNER JOIN users u
|
||||
ON p.user_id = u.id
|
||||
WHERE p.id = ?1`
|
||||
WHERE p.id = $1`
|
||||
|
||||
row := s.db.QueryRowContext(r.Context(), q, id)
|
||||
var fname, data, userLoginName, userDisplayName, userProfilePicURL string
|
||||
|
@ -684,7 +686,7 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
db, err := openDB(*dataDir)
|
||||
db, err := openDB(*dataDir, *databaseUrl)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -822,8 +824,15 @@ func (mch MixedCriticalityHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
|
|||
panic("unknown security level")
|
||||
}
|
||||
|
||||
func openDB(dir string) (*sql.DB, error) {
|
||||
db, err := sql.Open("sqlite", "file:"+filepath.Join(dir, "data.db"))
|
||||
func openDB(dir string, databaseUrl string) (*sql.DB, error) {
|
||||
dbtype := "sqlite"
|
||||
dbpath := "file:"+filepath.Join(dir, "data.db")
|
||||
if databaseUrl != "" {
|
||||
dbtype = "postgres"
|
||||
dbpath = databaseUrl
|
||||
}
|
||||
|
||||
db, err := sql.Open(dbtype, dbpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -833,6 +842,14 @@ func openDB(dir string) (*sql.DB, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Enable WAL for SQLite + Litestream
|
||||
if dbtype == "sqlite" {
|
||||
_, err := db.Exec("PRAGMA journal_mode=WAL;")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := db.Exec(sqlSchema); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -866,16 +883,16 @@ INSERT INTO users
|
|||
, profile_pic_url
|
||||
)
|
||||
VALUES
|
||||
( ?1
|
||||
, ?2
|
||||
, ?3
|
||||
, ?4
|
||||
( $1
|
||||
, $2
|
||||
, $3
|
||||
, $4
|
||||
)
|
||||
ON CONFLICT DO
|
||||
ON CONFLICT (id) DO
|
||||
UPDATE SET
|
||||
login_name = ?2
|
||||
, display_name = ?3
|
||||
, profile_pic_url = ?4
|
||||
login_name = $2
|
||||
, display_name = $3
|
||||
, profile_pic_url = $4
|
||||
`
|
||||
|
||||
_, err = db.ExecContext(
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
-- Enable WAL mode to make backups easier with Litestream
|
||||
PRAGMA journal_mode=WAL;
|
||||
-- Correlates to tailcfg.UserProfile
|
||||
CREATE TABLE IF NOT EXISTS users
|
||||
( id TEXT PRIMARY KEY NOT NULL
|
||||
, login_name TEXT NOT NULL
|
||||
, display_name TEXT NOT NULL
|
||||
, profile_pic_url TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Paste data
|
||||
CREATE TABLE IF NOT EXISTS pastes
|
||||
|
@ -10,11 +15,3 @@ CREATE TABLE IF NOT EXISTS pastes
|
|||
, data TEXT NOT NULL
|
||||
, FOREIGN KEY(user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Correlates to tailcfg.UserProfile
|
||||
CREATE TABLE IF NOT EXISTS users
|
||||
( id TEXT PRIMARY KEY NOT NULL
|
||||
, login_name TEXT NOT NULL
|
||||
, display_name TEXT NOT NULL
|
||||
, profile_pic_url TEXT NOT NULL
|
||||
);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1711703276,
|
||||
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
|
||||
"lastModified": 1714253743,
|
||||
"narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
|
||||
"rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
go = pkgs.go;
|
||||
src = ./.;
|
||||
subPackages = "cmd/tclipd";
|
||||
vendorHash = "sha256-7iOEp0NrcmvBNrxl5kjrJOAhVfKYPNpI4ssNxaf6g3M=";
|
||||
vendorHash = "sha256-Ho39aNWTbygA46/9lkXRVLV6FLkWenAJKxOE3MJUb2M=";
|
||||
};
|
||||
|
||||
tclip = pkgs.buildGo122Module {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -7,6 +7,7 @@ toolchain go1.22.1
|
|||
require (
|
||||
github.com/go-enry/go-enry/v2 v2.8.7
|
||||
github.com/google/uuid v1.5.0
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/microcosm-cc/bluemonday v1.0.26
|
||||
github.com/niklasfasching/go-org v1.7.0
|
||||
github.com/russross/blackfriday v1.6.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -125,6 +125,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
|
|
Loading…
Reference in a new issue