mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-24 08:46:24 -07:00
Upgrade Go version in vagrant and Docker, readd sqlite3 for real this time
requires intervention for vagrant to add the updated Go repo
This commit is contained in:
parent
3fa042167e
commit
9107269a39
21 changed files with 1464 additions and 592 deletions
3
build.py
3
build.py
|
@ -183,9 +183,6 @@ def set_vars(goos=""):
|
|||
|
||||
if goos != "":
|
||||
os.environ["GOOS"] = goos
|
||||
if os.getenv("CGO_ENABLED") is None:
|
||||
# CGO_ENABLED is not explicitly enabled, disable it
|
||||
os.environ["CGO_ENABLED"] = "0"
|
||||
|
||||
gcos, gcos_status = run_cmd("go env GOOS", print_output=False)
|
||||
exe, exe_status = run_cmd("go env GOEXE", print_output=False)
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -4,19 +4,21 @@ from os import path
|
|||
|
||||
class macro():
|
||||
""" Use a macro like this {exact macro name} """
|
||||
def __init__(self, macroname, postgres, mysql):
|
||||
def __init__(self, macroname, postgres, mysql, sqlite3):
|
||||
self.macroname = macroname
|
||||
self.postgres = postgres
|
||||
self.mysql = mysql
|
||||
self.sqlite3 = sqlite3
|
||||
|
||||
|
||||
# macros
|
||||
macros = [
|
||||
macro(
|
||||
"serial pk","BIGSERIAL PRIMARY KEY",
|
||||
"BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY"),
|
||||
macro("fk to serial", "BIGINT", "BIGINT"),
|
||||
macro("drop fk", "DROP CONSTRAINT", "DROP FOREIGN KEY")
|
||||
"BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY",
|
||||
"INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"),
|
||||
macro("fk to serial", "BIGINT", "BIGINT", "BIGINT"),
|
||||
macro("drop fk", "DROP CONSTRAINT", "DROP FOREIGN KEY", "DROP CONSTRAINT")
|
||||
]
|
||||
|
||||
|
||||
|
@ -48,11 +50,13 @@ def dofile(filestart):
|
|||
|
||||
postgresProcessed = compileOutIfs(masterfile, "POSTGRES")
|
||||
mysqlProcessed = compileOutIfs(masterfile, "MYSQL")
|
||||
sqlite3Processed = compileOutIfs(masterfile, "SQLITE3")
|
||||
|
||||
for item in macros:
|
||||
macroCode = "{" + item.macroname + "}"
|
||||
postgresProcessed = postgresProcessed.replace(macroCode, item.postgres)
|
||||
mysqlProcessed = mysqlProcessed.replace(macroCode, item.mysql)
|
||||
sqlite3Processed = sqlite3Processed.replace(macroCode, item.sqlite3)
|
||||
|
||||
error = hasError(postgresProcessed)
|
||||
error = error or hasError(mysqlProcessed)
|
||||
|
@ -60,6 +64,9 @@ def dofile(filestart):
|
|||
with open(filestart + "postgres.sql", 'w') as i:
|
||||
i.write(postgresProcessed)
|
||||
|
||||
with open(filestart + "sqlite3.sql", 'w') as i:
|
||||
i.write(sqlite3Processed)
|
||||
|
||||
with open(filestart + "mysql.sql", 'w') as i:
|
||||
i.write(mysqlProcessed)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.13.9-alpine3.11
|
||||
FROM golang:1.16-alpine3.15
|
||||
|
||||
RUN apk --no-cache add \
|
||||
postgresql-client \
|
||||
|
@ -13,7 +13,7 @@ RUN apk --no-cache add \
|
|||
bash
|
||||
|
||||
RUN mkdir -p /root/bin \
|
||||
&& ln -s /usr/lib/go-1.13/bin/* /root/bin/ \
|
||||
&& ln -s /usr/lib/go-1.16/bin/* /root/bin/ \
|
||||
&& export PATH=$PATH:/root/bin \
|
||||
&& echo "export PATH=$PATH:/root/bin" >> /root/.bashrc \
|
||||
&& rm -f /etc/nginx/sites-enabled/* /etc/nginx/sites-available/* \
|
||||
|
@ -27,8 +27,8 @@ WORKDIR /opt/gochan
|
|||
COPY build.py .
|
||||
RUN ./build.py dependencies
|
||||
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
COPY sample-configs/gochan-fastcgi.nginx /etc/nginx/conf.d/gochan.conf
|
||||
RUN rm -f /etc/nginx/http.d/default.conf
|
||||
COPY sample-configs/gochan-fastcgi.nginx /etc/nginx/http.d/gochan.conf
|
||||
COPY sample-configs/gochan.example.json /etc/gochan/gochan.json
|
||||
|
||||
# Get all
|
||||
|
@ -42,7 +42,6 @@ EXPOSE 9000
|
|||
CMD ls -la /opt/gochan && ls -la && ls -la .. && sed -i /etc/gochan/gochan.json \
|
||||
-e 's/"Port": 8080/"Port": 9000/' \
|
||||
-e 's/"UseFastCGI": false/"UseFastCGI": true/' \
|
||||
-e 's/"DomainRegex": ".*"/"DomainRegex": "(https|http):\\\/\\\/(.*)\\\/(.*)"/' \
|
||||
-e 's#"DocumentRoot": "html"#"DocumentRoot": "/srv/gochan"#' \
|
||||
-e 's#"TemplateDir": "templates"#"TemplateDir": "/usr/share/gochan/templates"#' \
|
||||
-e 's#"LogDir": "log"#"LogDir": "/var/log/gochan"#' \
|
||||
|
@ -52,6 +51,7 @@ CMD ls -la /opt/gochan && ls -la && ls -la .. && sed -i /etc/gochan/gochan.json
|
|||
-e "s/\"DBname\".*/\"DBname\": \"${DATABASE_NAME}\",/" \
|
||||
-e "s/\"DBusername\".*/\"DBusername\": \"${DATABASE_USER}\",/" \
|
||||
-e "s/\"DBpassword\".*/\"DBpassword\": \"${DATABASE_PASSWORD}\",/" \
|
||||
&& mkdir -p /etc/ssl/private \
|
||||
&& openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/CN=127.0.0.1" \
|
||||
&& ./build.py \
|
||||
&& ./build.py install \
|
||||
|
|
13
go.mod
13
go.mod
|
@ -1,6 +1,6 @@
|
|||
module github.com/gochan-org/gochan
|
||||
|
||||
go 1.13
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0
|
||||
|
@ -9,13 +9,14 @@ require (
|
|||
github.com/frustra/bbcode v0.0.0-20201127003707-6ef347fbe1c8
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/gochan-org/gzlog v1.0.2
|
||||
github.com/lib/pq v1.10.2
|
||||
github.com/mojocn/base64Captcha v1.3.4
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/mattn/go-sqlite3 v1.14.15
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/tdewolff/minify v2.3.6+incompatible
|
||||
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
||||
github.com/tdewolff/test v1.0.6 // indirect
|
||||
github.com/tdewolff/test v1.0.7 // indirect
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||
layeh.com/gopher-luar v1.0.10
|
||||
)
|
||||
|
|
20
go.sum
20
go.sum
|
@ -17,14 +17,22 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
|
|||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
||||
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mojocn/base64Captcha v1.3.4 h1:9+MZzjNSfBHniYOIpoP4xyDDPCXy14JIjsEFf89PlNw=
|
||||
github.com/mojocn/base64Captcha v1.3.4/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY=
|
||||
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
||||
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
|
||||
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
|
@ -32,21 +40,33 @@ gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/9
|
|||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
layeh.com/gopher-luar v1.0.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo=
|
||||
layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
|
||||
|
|
271
initdb_sqlite3.sql
Normal file
271
initdb_sqlite3.sql
Normal file
|
@ -0,0 +1,271 @@
|
|||
-- Gochan master template for new database script
|
||||
-- Contains macros in the form [curlybrace open]macro text[curlybrace close]
|
||||
-- Macros are substituted by build_initdb.py to the supported database files. Must not contain extra spaces
|
||||
-- Versioning numbering goes by whole numbers. Upgrade script migrate existing databases between versions
|
||||
-- Foreign and unique constraints must be named so they can be dropped.
|
||||
-- MYSQL requires constraint names to be unique globally, hence the long constraint names.
|
||||
-- Database version: 1
|
||||
|
||||
CREATE TABLE DBPREFIXdatabase_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXsections(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXboards(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES DBPREFIXsections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXthreads(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX thread_deleted_index ON DBPREFIXthreads(is_deleted);
|
||||
|
||||
CREATE TABLE DBPREFIXposts(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES DBPREFIXthreads(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX top_post_index ON DBPREFIXposts(is_top_post);
|
||||
|
||||
CREATE TABLE DBPREFIXfiles(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXstaff(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXsessions(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXboard_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXannouncements(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES DBPREFIXposts(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_appeals(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES DBPREFIXip_ban_appeals(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXreports(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXreports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXfilename_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXusername_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXfile_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXwordfilters(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
);
|
||||
|
||||
INSERT INTO DBPREFIXdatabase_version(component, version)
|
||||
VALUES('gochan', 1);
|
|
@ -2,7 +2,6 @@ package config
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"reflect"
|
||||
|
@ -66,7 +65,7 @@ var (
|
|||
}
|
||||
|
||||
boardConfigs = map[string]BoardConfig{}
|
||||
acceptedDrivers = []string{"mysql", "postgres"}
|
||||
acceptedDrivers = []string{"mysql", "postgres", "sqlite3"}
|
||||
)
|
||||
|
||||
type GochanConfig struct {
|
||||
|
@ -410,11 +409,7 @@ func GetBoardConfig(board string) *BoardConfig {
|
|||
}
|
||||
|
||||
func GetDebugMode() bool {
|
||||
if flag.Lookup("test.v") != nil {
|
||||
// running with go test
|
||||
return true
|
||||
}
|
||||
return cfg.SystemCriticalConfig.DebugMode
|
||||
return cfg.testing || cfg.SystemCriticalConfig.DebugMode
|
||||
}
|
||||
|
||||
func GetVersion() *GochanVersion {
|
||||
|
|
|
@ -2,6 +2,7 @@ package config
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -125,6 +126,92 @@ func ParseJSON(ba []byte) (*GochanConfig, []MissingField, error) {
|
|||
|
||||
// InitConfig loads and parses gochan.json on startup and verifies its contents
|
||||
func InitConfig(versionStr string) {
|
||||
if flag.Lookup("test.v") != nil {
|
||||
// create a dummy config for testing if we're using go test
|
||||
cfg = &GochanConfig{
|
||||
testing: true,
|
||||
SystemCriticalConfig: SystemCriticalConfig{
|
||||
ListenIP: "127.0.0.1",
|
||||
Port: 8080,
|
||||
UseFastCGI: true,
|
||||
DebugMode: true,
|
||||
DocumentRoot: "html",
|
||||
TemplateDir: "templates",
|
||||
LogDir: "",
|
||||
DBtype: "sqlmock",
|
||||
DBhost: "127.0.0.1:3306",
|
||||
DBname: "gochan",
|
||||
DBusername: "gochan",
|
||||
DBpassword: "",
|
||||
DBprefix: "gc_",
|
||||
SiteDomain: "127.0.0.1",
|
||||
WebRoot: "/",
|
||||
RandomSeed: "abcd",
|
||||
Version: ParseVersion(versionStr),
|
||||
},
|
||||
SiteConfig: SiteConfig{
|
||||
Username: "gochan",
|
||||
FirstPage: []string{"index.html", "firstrun.html", "1.html"},
|
||||
Lockdown: false,
|
||||
LockdownMessage: "This imageboard has temporarily disabled posting. We apologize for the inconvenience",
|
||||
SiteName: "Gochan",
|
||||
SiteSlogan: "Gochan testing",
|
||||
MinifyHTML: true,
|
||||
MinifyJS: true,
|
||||
EnableAppeals: true,
|
||||
MaxLogDays: 14,
|
||||
Verbosity: 1,
|
||||
|
||||
MaxRecentPosts: 3,
|
||||
RecentPostsWithNoFile: false,
|
||||
},
|
||||
BoardConfig: BoardConfig{
|
||||
Sillytags: []string{"Admin", "Mod", "Janitor", "Dweeb", "Kick me", "Troll", "worst pony"},
|
||||
UseSillytags: false,
|
||||
Styles: []Style{
|
||||
{Name: "Pipes", Filename: "pipes.css"},
|
||||
{Name: "BunkerChan", Filename: "bunkerchan.css"},
|
||||
{Name: "Burichan", Filename: "burichan.css"},
|
||||
{Name: "Clear", Filename: "clear.css"},
|
||||
{Name: "Dark", Filename: "dark.css"},
|
||||
{Name: "Photon", Filename: "photon.css"},
|
||||
{Name: "Yotsuba", Filename: "yotsuba.css"},
|
||||
{Name: "Yotsuba B", Filename: "yotsubab.css"},
|
||||
{Name: "Windows 9x", Filename: "win9x.css"},
|
||||
},
|
||||
DefaultStyle: "pipes.css",
|
||||
|
||||
PostConfig: PostConfig{
|
||||
NewThreadDelay: 30,
|
||||
ReplyDelay: 7,
|
||||
ThreadsPerPage: 15,
|
||||
PostsPerThreadPage: 50,
|
||||
RepliesOnBoardPage: 3,
|
||||
StickyRepliesOnBoardPage: 1,
|
||||
BanColors: []string{
|
||||
"admin:#0000A0",
|
||||
"somemod:blue",
|
||||
},
|
||||
BanMessage: "USER WAS BANNED FOR THIS POST",
|
||||
EnableEmbeds: true,
|
||||
EmbedWidth: 200,
|
||||
EmbedHeight: 164,
|
||||
ImagesOpenNewTab: true,
|
||||
NewTabOnOutlinks: true,
|
||||
},
|
||||
UploadConfig: UploadConfig{
|
||||
ThumbWidth: 200,
|
||||
ThumbHeight: 200,
|
||||
ThumbWidthReply: 125,
|
||||
ThumbHeightReply: 125,
|
||||
ThumbWidthCatalog: 50,
|
||||
ThumbHeightCatalog: 50,
|
||||
},
|
||||
DateTimeFormat: "Mon, January 02, 2006 3:04 PM",
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
cfgPath = gcutil.FindResource(
|
||||
"gochan.json",
|
||||
"/usr/local/etc/gochan/gochan.json",
|
||||
|
|
47
pkg/gcsql/boards_test.go
Normal file
47
pkg/gcsql/boards_test.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
)
|
||||
|
||||
func TestCreateBoard(t *testing.T) {
|
||||
// set up boards
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT id FROM gc_sections WHERE name = 'Main'`,
|
||||
)).ExpectQuery().WillReturnError(sql.ErrNoRows)
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT COALESCE(MAX(position) + 1, 0) FROM gc_sections`,
|
||||
)).ExpectQuery().WillReturnRows(sqlmock.NewRows([]string{"a"}).AddRow(0))
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`INSERT INTO gc_sections (name, abbreviation, hidden, position) VALUES (?,?,?,?)`,
|
||||
)).ExpectExec().WithArgs("Main", "Main", false, 0).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT id FROM gc_sections WHERE position = ?`,
|
||||
)).ExpectQuery().WithArgs(0).WillReturnRows(
|
||||
sqlmock.NewRows([]string{"id"}).AddRow(1),
|
||||
)
|
||||
sqm.ExpectPrepare(prepTestQueryString(`INSERT INTO gc_boards (
|
||||
navbar_position, dir, uri, title, subtitle, description, max_file_size, max_threads, default_style, locked, anonymous_name, force_anonymous, autosage_after, no_images_after, max_message_length, min_message_length, allow_embeds, redirect_to_thread, require_file, enable_catalog, section_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)).ExpectExec().WithArgs(
|
||||
0, "test", "test", "Testing board", "Board for testing stuff", "/test/ board description",
|
||||
10000, 300, config.GetBoardConfig("").DefaultStyle, false, "Anonymous", false, 200, 500,
|
||||
8192, 1, false, false, false, true, 1,
|
||||
).WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT id FROM gc_boards WHERE dir = ?`,
|
||||
)).ExpectQuery().WithArgs("test").WillReturnRows(
|
||||
sqlmock.NewRows([]string{"id"}).AddRow(1),
|
||||
)
|
||||
|
||||
err := CreateDefaultBoardIfNoneExist()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed creating default board if none exists: %s", err.Error())
|
||||
}
|
||||
if err = sqm.ExpectationsWereMet(); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
|
@ -67,12 +67,13 @@ func RunSQLFile(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO: get gocha-migration working so this doesn't have to sit here
|
||||
// TODO: get gochan-migration working so this doesn't have to sit here
|
||||
func tmpSqlAdjust() error {
|
||||
// first update the crappy wordfilter table structure
|
||||
var err error
|
||||
var query string
|
||||
if gcdb.driver == "mysql" {
|
||||
switch gcdb.driver {
|
||||
case "mysql":
|
||||
query = `SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE CONSTRAINT_NAME = 'wordfilters_staff_id_fk'
|
||||
AND TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'DBPREFIXwordfilters'`
|
||||
|
@ -85,8 +86,10 @@ func tmpSqlAdjust() error {
|
|||
if numConstraints > 0 {
|
||||
query = `ALTER TABLE DBPREFIXwordfilters DROP FOREIGN KEY IF EXISTS wordfilters_board_id_fk`
|
||||
}
|
||||
} else {
|
||||
case "postgres":
|
||||
query = `ALTER TABLE DBPREFIXwordfilters DROP CONSTRAINT IF EXISTS board_id_fk`
|
||||
case "sqlite3":
|
||||
return nil
|
||||
}
|
||||
if _, err = gcdb.ExecSQL(query); err != nil {
|
||||
return err
|
||||
|
|
|
@ -16,6 +16,7 @@ const (
|
|||
Error text: %s`
|
||||
mysqlConnStr = "%s:%s@tcp(%s)/%s?parseTime=true&collation=utf8mb4_unicode_ci"
|
||||
postgresConnStr = "postgres://%s:%s@%s/%s?sslmode=disable"
|
||||
sqlite3ConnStr = "file:%s?_auth&_auth_user=%s&_auth_pass=%s&_auth_crypt=sha1"
|
||||
)
|
||||
|
||||
type GCDB struct {
|
||||
|
@ -70,6 +71,7 @@ func (db *GCDB) PrepareSQL(query string, tx *sql.Tx) (*sql.Stmt, error) {
|
|||
/*
|
||||
ExecSQL automatically escapes the given values and caches the statement
|
||||
Example:
|
||||
|
||||
var intVal int
|
||||
var stringVal string
|
||||
result, err := db.ExecSQL("INSERT INTO tablename (intval,stringval) VALUES(?,?)", intVal, stringVal)
|
||||
|
@ -105,6 +107,7 @@ func (db *GCDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, erro
|
|||
QueryRowSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
|
||||
Automatically escapes the given values and caches the query
|
||||
Example:
|
||||
|
||||
id := 32
|
||||
var intVal int
|
||||
var stringVal string
|
||||
|
@ -125,6 +128,7 @@ func (db *GCDB) QueryRowSQL(query string, values, out []interface{}) error {
|
|||
QuerySQL gets all rows from the db with the values in values[] and fills the respective pointers in out[]
|
||||
Automatically escapes the given values and caches the query
|
||||
Example:
|
||||
|
||||
rows, err := db.QuerySQL("SELECT * FROM table")
|
||||
if err == nil {
|
||||
for rows.Next() {
|
||||
|
@ -153,22 +157,26 @@ func Open(host, dbDriver, dbName, username, password, prefix string) (db *GCDB,
|
|||
"\n", " "),
|
||||
}
|
||||
|
||||
addrMatches := tcpHostIsolator.FindAllStringSubmatch(host, -1)
|
||||
if len(addrMatches) > 0 && len(addrMatches[0]) > 2 {
|
||||
host = addrMatches[0][2]
|
||||
if dbDriver != "sqlite3" {
|
||||
addrMatches := tcpHostIsolator.FindAllStringSubmatch(host, -1)
|
||||
if len(addrMatches) > 0 && len(addrMatches[0]) > 2 {
|
||||
host = addrMatches[0][2]
|
||||
}
|
||||
}
|
||||
|
||||
switch dbDriver {
|
||||
case "mysql":
|
||||
db.connStr = fmt.Sprintf(mysqlConnStr, username, password, host, dbName)
|
||||
// db.nilTimestamp = "0000-00-00 00:00:00"
|
||||
case "sqlite3":
|
||||
db.connStr = fmt.Sprintf(sqlite3ConnStr, host, username, password)
|
||||
case "postgres":
|
||||
db.connStr = fmt.Sprintf(postgresConnStr, username, password, host, dbName)
|
||||
// db.nilTimestamp = "0001-01-01 00:00:00"
|
||||
default:
|
||||
return nil, ErrUnsupportedDB
|
||||
}
|
||||
|
||||
fmt.Printf("connStr: %q\nhost: %q\n", db.connStr, host)
|
||||
db.db, err = sql.Open(db.driver, db.connStr)
|
||||
return db, err
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ func GetCompleteDatabaseVersion() (dbVersion, dbFlag int, err error) {
|
|||
return 0, DBClean, nil
|
||||
}
|
||||
|
||||
//CheckAndInitializeDatabase checks the validity of the database and initialises it if it is empty
|
||||
// CheckAndInitializeDatabase checks the validity of the database and initialises it if it is empty
|
||||
func CheckAndInitializeDatabase(dbType string) {
|
||||
dbVersion, versionFlag, err := GetCompleteDatabaseVersion()
|
||||
if err != nil {
|
||||
|
|
|
@ -8,13 +8,14 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
)
|
||||
|
||||
var (
|
||||
sqm sqlmock.Sqlmock
|
||||
)
|
||||
|
||||
func connectTest() error {
|
||||
func connectTest() (err error) {
|
||||
gcdb = &GCDB{
|
||||
driver: "sqlmock",
|
||||
replacer: strings.NewReplacer(
|
||||
|
@ -22,7 +23,7 @@ func connectTest() error {
|
|||
"DBPREFIX", "gc_",
|
||||
"\n", " "),
|
||||
}
|
||||
var err error
|
||||
|
||||
gcdb.db, sqm, err = sqlmock.New()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -34,556 +35,10 @@ func prepTestQueryString(str string) string {
|
|||
return regexp.QuoteMeta(strings.Replace(str, "\n", " ", -1))
|
||||
}
|
||||
|
||||
func createTablesTest() error {
|
||||
if gcdb == nil {
|
||||
return ErrNotConnected
|
||||
}
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_database_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
|
||||
sqm.ExpectPrepare(regexp.QuoteMeta(`CREATE TABLE gc_sections(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(2, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_boards(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES gc_sections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(3, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_threads(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(4, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE INDEX thread_deleted_index ON gc_threads(is_deleted);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(5, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_posts(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES gc_threads(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(5, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_files(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES gc_posts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(6, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_staff(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(7, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_sessions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_board_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_announcements(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES gc_posts(id) ON DELETE SET NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES gc_ip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_appeals(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES gc_ip_ban(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES gc_ip_ban_appeals(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_reports(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES gc_posts(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_reports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES gc_reports(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_filename_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_username_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_file_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_wordfilters(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
func populateTestSchema() error {
|
||||
var err error
|
||||
sqm.ExpectPrepare(prepTestQueryString(`INSERT INTO gc_database_version(component, version)
|
||||
VALUES('gochan', 1);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
// start fulfilling the expected execs
|
||||
|
||||
var err error
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXdatabase_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXsections(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXboards(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES DBPREFIXsections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXthreads(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE INDEX thread_deleted_index ON DBPREFIXthreads(is_deleted);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXposts(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES DBPREFIXthreads(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfiles(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXstaff(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXsessions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXboard_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXannouncements(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES DBPREFIXposts(id) ON DELETE SET NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_appeals(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES DBPREFIXip_ban_appeals(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXreports(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXreports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfilename_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXusername_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfile_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXwordfilters(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`INSERT INTO DBPREFIXdatabase_version(component, version)
|
||||
VALUES('gochan', 1);`); err != nil {
|
||||
return err
|
||||
|
@ -592,8 +47,32 @@ VALUES('gochan', 1);`); err != nil {
|
|||
return sqm.ExpectationsWereMet()
|
||||
}
|
||||
|
||||
func TestDatabaseVersion(t *testing.T) {
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT component,version FROM gc_database_version WHERE component = ?;`,
|
||||
)).ExpectQuery().WithArgs("gochan").WillReturnRows(
|
||||
sqlmock.NewRows([]string{"component", "version"}).AddRow("gochan", 1),
|
||||
)
|
||||
|
||||
var component string
|
||||
var version int
|
||||
err := QueryRowSQL(`SELECT component,version FROM DBPREFIXdatabase_version WHERE component = ?;`,
|
||||
interfaceSlice("gochan"),
|
||||
interfaceSlice(&component, &version))
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
if err = sqm.ExpectationsWereMet(); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
if version < 1 {
|
||||
t.Fatalf("Component %q has version: %d", component, version)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
log.SetFlags(0)
|
||||
config.InitConfig("3.2.0")
|
||||
|
||||
err := connectTest()
|
||||
if err != nil {
|
||||
|
@ -601,9 +80,14 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
defer gcdb.Close()
|
||||
|
||||
if err = createTablesTest(); err != nil {
|
||||
if err = createMockSchema(); err != nil {
|
||||
log.Fatalln("Failed setting up sqlmock db tables:", err.Error())
|
||||
}
|
||||
|
||||
if err = populateTestSchema(); err != nil {
|
||||
log.Fatalln("Failed populating test schema:", err.Error())
|
||||
}
|
||||
|
||||
exitCode := m.Run()
|
||||
|
||||
os.Exit(exitCode)
|
||||
|
|
|
@ -1,12 +1,49 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
_ "github.com/DATA-DOG/go-sqlmock"
|
||||
)
|
||||
|
||||
func TestInsertPost(t *testing.T) {
|
||||
log.Println("Inserting post")
|
||||
func makeTestPost(post *Post, bump bool) (err error) {
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT COALESCE(MAX(id), 0) + 1 FROM gc_threads`,
|
||||
)).ExpectQuery().WillReturnRows(
|
||||
sqm.NewRows([]string{"a"}).AddRow(1),
|
||||
)
|
||||
|
||||
err = InsertPost(post, bump)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqm.ExpectationsWereMet()
|
||||
}
|
||||
|
||||
func TestInsertPosts(t *testing.T) {
|
||||
err := makeTestPost(&Post{
|
||||
ParentID: 0,
|
||||
BoardID: 1,
|
||||
Name: "Joe Poster",
|
||||
Tripcode: "Blah",
|
||||
Email: "any@example.com",
|
||||
Subject: "First thread",
|
||||
MessageHTML: "First post best post",
|
||||
MessageText: "First post best post",
|
||||
Password: "12345",
|
||||
Filename: "12345.png",
|
||||
FilenameOriginal: "somefile.png",
|
||||
FileChecksum: "abcd1234",
|
||||
FileExt: ".png",
|
||||
Filesize: 1000,
|
||||
ImageW: 2000,
|
||||
ImageH: 2000,
|
||||
ThumbW: 250,
|
||||
ThumbH: 250,
|
||||
IP: "192.168.56.1",
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
|
557
pkg/gcsql/schema_test.go
Normal file
557
pkg/gcsql/schema_test.go
Normal file
|
@ -0,0 +1,557 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
)
|
||||
|
||||
func createMockSchema() (err error) {
|
||||
if gcdb == nil {
|
||||
return ErrNotConnected
|
||||
}
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_database_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
|
||||
sqm.ExpectPrepare(regexp.QuoteMeta(`CREATE TABLE gc_sections(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(2, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_boards(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES gc_sections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(3, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_threads(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(4, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE INDEX thread_deleted_index ON gc_threads(is_deleted);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(5, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_posts(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES gc_threads(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(5, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_files(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES gc_posts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(6, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_staff(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(7, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_sessions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_board_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_announcements(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES gc_posts(id) ON DELETE SET NULL
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES gc_ip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_appeals(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES gc_ip_ban(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_ip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES gc_ip_ban_appeals(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_reports(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES gc_posts(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_reports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES gc_reports(id) ON DELETE CASCADE
|
||||
);`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_filename_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_username_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_file_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES gc_boards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id)
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(`CREATE TABLE gc_wordfilters(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES gc_staff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
)`)).ExpectExec().WillReturnResult(sqlmock.NewResult(8, 1))
|
||||
|
||||
// start fulfilling the expected execs
|
||||
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXdatabase_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXsections(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXboards(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES DBPREFIXsections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXthreads(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE INDEX thread_deleted_index ON DBPREFIXthreads(is_deleted);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXposts(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES DBPREFIXthreads(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfiles(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXstaff(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXsessions(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXboard_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXannouncements(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES DBPREFIXposts(id) ON DELETE SET NULL
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_appeals(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES DBPREFIXip_ban_appeals(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXreports(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXreports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfilename_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXusername_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXfile_ban(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(`CREATE TABLE DBPREFIXwordfilters(
|
||||
id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
);`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sqm.ExpectationsWereMet()
|
||||
}
|
81
pkg/gcsql/sections_test.go
Normal file
81
pkg/gcsql/sections_test.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
)
|
||||
|
||||
func testCreateSection(section *BoardSection, lastInsertID int) error {
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`INSERT INTO gc_sections (name, abbreviation, hidden, position) VALUES (?,?,?,?)`,
|
||||
)).ExpectExec().WithArgs(
|
||||
section.Name, section.Abbreviation, section.Hidden, section.ListOrder,
|
||||
).WillReturnResult(sqlmock.NewResult(int64(lastInsertID), 1))
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT id FROM gc_sections WHERE position = ?`,
|
||||
)).ExpectQuery().WithArgs(section.ListOrder).WillReturnRows(
|
||||
sqlmock.NewRows([]string{"id"}).AddRow(section.ID),
|
||||
)
|
||||
|
||||
err := CreateSection(section)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqm.ExpectationsWereMet()
|
||||
}
|
||||
|
||||
func TestSectionCreation(t *testing.T) {
|
||||
section := &BoardSection{
|
||||
ID: 2,
|
||||
Name: "Staff",
|
||||
Abbreviation: "hidden1",
|
||||
Hidden: true,
|
||||
ListOrder: 2,
|
||||
}
|
||||
err := testCreateSection(section, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed creating section 'Staff': %s", err.Error())
|
||||
}
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`UPDATE gc_sections SET name = ?, abbreviation = ?, position = ?, hidden = ? where id = ?`,
|
||||
)).ExpectExec().WithArgs("Staff", "hidden1", 2, true, 2).WillReturnResult(sqlmock.NewResult(2, 1))
|
||||
|
||||
if err = section.UpdateValues(); err != nil {
|
||||
t.Fatalf("Error updating section: %s", err.Error())
|
||||
}
|
||||
|
||||
if err = sqm.ExpectationsWereMet(); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteSections(t *testing.T) {
|
||||
section := &BoardSection{
|
||||
Name: "Temp",
|
||||
Abbreviation: "temp",
|
||||
Hidden: false,
|
||||
ListOrder: 3,
|
||||
}
|
||||
err := testCreateSection(section, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed creating temporary section for deletion testing: %s", err.Error())
|
||||
}
|
||||
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`SELECT COUNT(*) FROM gc_sections`,
|
||||
)).ExpectQuery().WillReturnRows(
|
||||
sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(2),
|
||||
)
|
||||
sqm.ExpectPrepare(prepTestQueryString(
|
||||
`DELETE FROM gc_sections WHERE id = ?`,
|
||||
)).ExpectExec().WithArgs(3).WillReturnResult(sqlmock.NewResult(3, 1))
|
||||
if err = DeleteSection(3); err != nil {
|
||||
t.Fatalf("Error deleting section #2: %s", err.Error())
|
||||
}
|
||||
|
||||
if err = sqm.ExpectationsWereMet(); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}
|
|
@ -38,6 +38,8 @@ func SetupSQLString(query string, dbConn *GCDB) (string, error) {
|
|||
switch dbConn.driver {
|
||||
case "mysql":
|
||||
prepared = query
|
||||
case "sqlite3":
|
||||
fallthrough
|
||||
case "postgres":
|
||||
arr := strings.Split(query, "?")
|
||||
for i := range arr {
|
||||
|
|
|
@ -36,9 +36,9 @@ func InitCaptcha() {
|
|||
return
|
||||
}
|
||||
driver = base64Captcha.NewDriverString(
|
||||
boardConfig.CaptchaHeight, boardConfig.CaptchaWidth, 0, 0, 6,
|
||||
boardConfig.CaptchaHeight, boardConfig.CaptchaWidth, int(0), int(0), int(6),
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
&color.RGBA{0, 0, 0, 0}, nil).ConvertFonts()
|
||||
&color.RGBA{0, 0, 0, 0}, nil, nil).ConvertFonts()
|
||||
}
|
||||
|
||||
// ServeCaptcha handles requests to /captcha if UseCaptcha is enabled in gochan.json
|
||||
|
|
271
sql/preapril2020migration/initdb_sqlite3.sql
Normal file
271
sql/preapril2020migration/initdb_sqlite3.sql
Normal file
|
@ -0,0 +1,271 @@
|
|||
-- Gochan master template for new database script
|
||||
-- Contains macros in the form [curlybrace open]macro text[curlybrace close]
|
||||
-- Macros are substituted by build_initdb.py to the supported database files. Must not contain extra spaces
|
||||
-- Versioning numbering goes by whole numbers. Upgrade script migrate existing databases between versions
|
||||
-- Foreign and unique constraints must be named so they can be dropped.
|
||||
-- MYSQL requires constraint names to be unique globally, hence the long constraint names.
|
||||
-- Database version: 1
|
||||
|
||||
CREATE TABLE DBPREFIXdatabase_version(
|
||||
component VARCHAR(40) NOT NULL PRIMARY KEY,
|
||||
version INT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXsections(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
abbreviation TEXT NOT NULL,
|
||||
position SMALLINT NOT NULL,
|
||||
hidden BOOL NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXboards(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
section_id BIGINT NOT NULL,
|
||||
uri VARCHAR(45) NOT NULL,
|
||||
dir VARCHAR(45) NOT NULL,
|
||||
navbar_position SMALLINT NOT NULL,
|
||||
title VARCHAR(45) NOT NULL,
|
||||
subtitle VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(64) NOT NULL,
|
||||
max_file_size INT NOT NULL,
|
||||
max_threads SMALLINT NOT NULL,
|
||||
default_style VARCHAR(45) NOT NULL,
|
||||
locked BOOL NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
anonymous_name VARCHAR(45) NOT NULL DEFAULT 'Anonymous',
|
||||
force_anonymous BOOL NOT NULL,
|
||||
autosage_after SMALLINT NOT NULL,
|
||||
no_images_after SMALLINT NOT NULL,
|
||||
max_message_length SMALLINT NOT NULL,
|
||||
min_message_length SMALLINT NOT NULL,
|
||||
allow_embeds BOOL NOT NULL,
|
||||
redirect_to_thread BOOL NOT NULL,
|
||||
require_file BOOL NOT NULL,
|
||||
enable_catalog BOOL NOT NULL,
|
||||
CONSTRAINT boards_section_id_fk FOREIGN KEY(section_id) REFERENCES DBPREFIXsections(id),
|
||||
CONSTRAINT boards_dir_unique UNIQUE(dir),
|
||||
CONSTRAINT boards_uri_unique UNIQUE(uri)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXthreads(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT NOT NULL,
|
||||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT threads_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX thread_deleted_index ON DBPREFIXthreads(is_deleted);
|
||||
|
||||
CREATE TABLE DBPREFIXposts(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
thread_id BIGINT NOT NULL,
|
||||
is_top_post BOOL NOT NULL DEFAULT FALSE,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
tripcode VARCHAR(10) NOT NULL DEFAULT '',
|
||||
is_role_signature BOOL NOT NULL DEFAULT FALSE,
|
||||
email VARCHAR(50) NOT NULL DEFAULT '',
|
||||
subject VARCHAR(100) NOT NULL DEFAULT '',
|
||||
message TEXT NOT NULL,
|
||||
message_raw TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_deleted BOOL NOT NULL DEFAULT FALSE,
|
||||
banned_message TEXT,
|
||||
CONSTRAINT posts_thread_id_fk FOREIGN KEY(thread_id) REFERENCES DBPREFIXthreads(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX top_post_index ON DBPREFIXposts(is_top_post);
|
||||
|
||||
CREATE TABLE DBPREFIXfiles(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
post_id BIGINT NOT NULL,
|
||||
file_order INT NOT NULL,
|
||||
original_filename VARCHAR(255) NOT NULL,
|
||||
filename VARCHAR(45) NOT NULL,
|
||||
checksum TEXT NOT NULL,
|
||||
file_size INT NOT NULL,
|
||||
is_spoilered BOOL NOT NULL,
|
||||
thumbnail_width INT NOT NULL,
|
||||
thumbnail_height INT NOT NULL,
|
||||
width INT NOT NULL,
|
||||
height INT NOT NULL,
|
||||
CONSTRAINT files_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE,
|
||||
CONSTRAINT files_post_id_file_order_unique UNIQUE(post_id, file_order)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXstaff(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
username VARCHAR(45) NOT NULL,
|
||||
password_checksum VARCHAR(120) NOT NULL,
|
||||
global_rank INT,
|
||||
added_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOL NOT NULL DEFAULT TRUE,
|
||||
CONSTRAINT staff_username_unique UNIQUE(username)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXsessions(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
expires TIMESTAMP NOT NULL,
|
||||
data VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT sessions_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXboard_staff(
|
||||
board_id BIGINT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
CONSTRAINT board_staff_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id) ON DELETE CASCADE,
|
||||
CONSTRAINT board_staff_pk PRIMARY KEY (board_id,staff_id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXannouncements(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
subject VARCHAR(45) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT announcements_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT NOT NULL,
|
||||
board_id BIGINT,
|
||||
banned_for_post_id BIGINT,
|
||||
copy_post_text TEXT NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_banned_for_post_id_fk FOREIGN KEY(banned_for_post_id) REFERENCES DBPREFIXposts(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_audit(
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT NOT NULL,
|
||||
is_active BOOL NOT NULL,
|
||||
is_thread_ban BOOL NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
appeal_at TIMESTAMP NOT NULL,
|
||||
permanent BOOL NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
can_appeal BOOL NOT NULL,
|
||||
PRIMARY KEY(ip_ban_id, timestamp),
|
||||
CONSTRAINT ip_ban_audit_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE,
|
||||
CONSTRAINT ip_ban_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_appeals(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
staff_id BIGINT,
|
||||
ip_ban_id BIGINT NOT NULL,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
CONSTRAINT ip_ban_appeals_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_ip_ban_id_fk FOREIGN KEY(ip_ban_id) REFERENCES DBPREFIXip_ban(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXip_ban_appeals_audit(
|
||||
appeal_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
staff_id BIGINT,
|
||||
appeal_text TEXT NOT NULL,
|
||||
staff_response TEXT,
|
||||
is_denied BOOL NOT NULL,
|
||||
PRIMARY KEY(appeal_id, timestamp),
|
||||
CONSTRAINT ip_ban_appeals_audit_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT ip_ban_appeals_audit_appeal_id_fk FOREIGN KEY(appeal_id) REFERENCES DBPREFIXip_ban_appeals(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXreports(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
handled_by_staff_id BIGINT,
|
||||
post_id BIGINT NOT NULL,
|
||||
ip VARCHAR(45) NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_post_id_fk FOREIGN KEY(post_id) REFERENCES DBPREFIXposts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXreports_audit(
|
||||
report_id BIGINT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
handled_by_staff_id BIGINT,
|
||||
is_cleared BOOL NOT NULL,
|
||||
CONSTRAINT reports_audit_handled_by_staff_id_fk FOREIGN KEY(handled_by_staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT reports_audit_report_id_fk FOREIGN KEY(report_id) REFERENCES DBPREFIXreports(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXfilename_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT filename_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT filename_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXusername_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
CONSTRAINT username_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT username_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXfile_ban(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_id BIGINT,
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
checksum TEXT NOT NULL,
|
||||
CONSTRAINT file_ban_board_id_fk FOREIGN KEY(board_id) REFERENCES DBPREFIXboards(id) ON DELETE CASCADE,
|
||||
CONSTRAINT file_ban_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id)
|
||||
);
|
||||
|
||||
CREATE TABLE DBPREFIXwordfilters(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
board_dirs VARCHAR(255) DEFAULT '*',
|
||||
staff_id BIGINT NOT NULL,
|
||||
staff_note VARCHAR(255) NOT NULL,
|
||||
issued_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
search VARCHAR(75) NOT NULL,
|
||||
is_regex BOOL NOT NULL,
|
||||
change_to VARCHAR(75) NOT NULL,
|
||||
CONSTRAINT wordfilters_staff_id_fk FOREIGN KEY(staff_id) REFERENCES DBPREFIXstaff(id),
|
||||
CONSTRAINT wordfilters_search_check CHECK (search <> '')
|
||||
);
|
||||
|
||||
INSERT INTO DBPREFIXdatabase_version(component, version)
|
||||
VALUES('gochan', 1);
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export GO_VERSION=1.16
|
||||
|
||||
if [ -z "$DBTYPE" ]; then
|
||||
echo "DBTYPE environment variable not set, must be 'mysql' or 'postgresql'."
|
||||
|
@ -11,7 +12,7 @@ if [ -z "$DBTYPE" ]; then
|
|||
fi
|
||||
echo "Using DBTYPE $DBTYPE"
|
||||
|
||||
add-apt-repository -y ppa:gophers/archive
|
||||
add-apt-repository -y ppa:longsleep/golang-backports
|
||||
apt-get -y update && apt-get -y upgrade
|
||||
|
||||
if [ "$DBTYPE" == "mysql" ]; then
|
||||
|
@ -54,6 +55,8 @@ elif [ "$DBTYPE" == "postgresql" ]; then
|
|||
systemctl daemon-reload
|
||||
systemctl enable gochan.service
|
||||
fi
|
||||
elif [ "$DBTYPE" == "sqlite3" ]; then
|
||||
apt install sqlite3
|
||||
elif [ "$DBTYPE" == "mssql" ]; then
|
||||
# using Microsoft SQL Server (currently unsupported)
|
||||
echo "Microsoft SQL Server not supported yet";
|
||||
|
@ -63,9 +66,9 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
apt-get -y install git subversion mercurial nginx ffmpeg golang-1.11
|
||||
apt-get -y install git subversion mercurial nginx ffmpeg golang-${GO_VERSION}
|
||||
|
||||
ln -s /usr/lib/go-1.11/bin/* /usr/local/bin/
|
||||
ln -sf /usr/lib/go-${GO_VERSION}/bin/* /usr/local/bin/
|
||||
|
||||
rm -f /etc/nginx/sites-enabled/* /etc/nginx/sites-available/*
|
||||
ln -sf /vagrant/sample-configs/gochan-fastcgi.nginx /etc/nginx/sites-available/gochan.nginx
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue