mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-25 09:36:24 -07:00
Refactor threads table, rename cyclical attribute to cyclic for consistency
This commit is contained in:
parent
d7f2995333
commit
305b557e41
24 changed files with 137 additions and 55 deletions
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *config.SQLConfig, errEv *zerolog.Event) (err error) {
|
||||
var query string
|
||||
var dataType string
|
||||
var cyclicalType string
|
||||
defer func() {
|
||||
if a := recover(); a != nil {
|
||||
errEv.Caller(4).Interface("panic", a).Send()
|
||||
|
@ -28,6 +28,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
// fix default collation
|
||||
query = `ALTER DATABASE ` + dbName + ` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci`
|
||||
if _, err = db.GetBaseDB().ExecContext(ctx, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
query = `SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'`
|
||||
rows, err = db.QueryContextSQL(ctx, nil, query, dbName)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
|
@ -44,10 +46,12 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
for rows.Next() {
|
||||
err = rows.Scan(&tableName)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
query = `ALTER TABLE ` + tableName + ` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -55,21 +59,23 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
return err
|
||||
}
|
||||
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXip_ban", sqlConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dataType != "" {
|
||||
if cyclicalType != "" {
|
||||
// add range_start and range_end columns
|
||||
query = `ALTER TABLE DBPREFIXip_ban
|
||||
ADD COLUMN IF NOT EXISTS range_start VARBINARY(16) NOT NULL,
|
||||
ADD COLUMN IF NOT EXISTS range_end VARBINARY(16) NOT NULL`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
// convert ban IP string to IP range
|
||||
if rows, err = db.QueryContextSQL(ctx, nil, "SELECT id, ip FROM DBPREFIXip_ban"); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
var rangeStart, rangeEnd string
|
||||
|
@ -77,6 +83,7 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
var id int
|
||||
var ipOrCIDR string
|
||||
if err = rows.Scan(&id, &ipOrCIDR); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if rangeStart, rangeEnd, err = gcutil.ParseIPRange(ipOrCIDR); err != nil {
|
||||
|
@ -85,122 +92,168 @@ func updateMysqlDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *confi
|
|||
query = `UPDATE DBPREFIXip_ban
|
||||
SET range_start = INET6_ATON(?), range_end = INET6_ATON(?) WHERE id = ?`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query, rangeStart, rangeEnd, id); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
query = `ALTER TABLE DBPREFIXip_ban DROP COLUMN IF EXISTS ip`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = rows.Close(); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Convert DBPREFIXposts.ip to from varchar to varbinary
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if common.IsStringType(dataType) {
|
||||
if common.IsStringType(cyclicalType) {
|
||||
// rename `ip` to a temporary column to then be removed
|
||||
query = "ALTER TABLE DBPREFIXposts CHANGE ip ip_str varchar(45)"
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
query = `ALTER TABLE DBPREFIXposts
|
||||
ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
// convert post IP VARCHAR(45) to VARBINARY(16)
|
||||
query = `UPDATE DBPREFIXposts SET ip = INET6_ATON(ip_str)`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
query = `ALTER TABLE DBPREFIXposts DROP COLUMN IF EXISTS ip_str`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Convert DBPREFIXreports.ip to from varchar to varbinary
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXreports", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "ip", "DBPREFIXreports", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if common.IsStringType(dataType) {
|
||||
if common.IsStringType(cyclicalType) {
|
||||
// rename `ip` to a temporary column to then be removed
|
||||
query = "ALTER TABLE DBPREFIXreports CHANGE ip ip_str varchar(45)"
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
query = `ALTER TABLE DBPREFIXreports
|
||||
ADD COLUMN IF NOT EXISTS ip VARBINARY(16) NOT NULL`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
// convert report IP VARCHAR(45) to VARBINARY(16)
|
||||
query = `UPDATE DBPREFIXreports SET ip = INET6_ATON(ip_str)`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
|
||||
query = `ALTER TABLE DBPREFIXreports DROP COLUMN IF EXISTS ip_str`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// add flag column to DBPREFIXposts
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "flag", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
if cyclicalType == "" {
|
||||
query = `ALTER TABLE DBPREFIXposts ADD COLUMN flag VARCHAR(45) NOT NULL DEFAULT ''`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// add country column to DBPREFIXposts
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "country", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
if cyclicalType == "" {
|
||||
query = `ALTER TABLE DBPREFIXposts ADD COLUMN country VARCHAR(80) NOT NULL DEFAULT ''`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// add is_secure_tripcode column to DBPREFIXposts
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "is_secure_tripcode", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
if cyclicalType == "" {
|
||||
query = `ALTER TABLE DBPREFIXposts ADD COLUMN is_secure_tripcode BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// add spoilered column to DBPREFIXthreads
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "is_spoilered", "DBPREFIXthreads", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
if cyclicalType == "" {
|
||||
query = `ALTER TABLE DBPREFIXthreads ADD COLUMN is_spoilered BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// rename DBPREFIXposts.cyclical to cyclic
|
||||
cyclicalType, err = common.ColumnType(ctx, db, nil, "cyclical", "DBPREFIXthreads", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
cyclicType, err := common.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXthreads", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if cyclicalType == "" && cyclicType == "" {
|
||||
query = `ALTER TABLE DBPREFIXthreads ADD COLUMN cyclic BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
} else if cyclicalType != "" {
|
||||
query = `ALTER TABLE DBPREFIXthreads CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,5 +117,19 @@ func updatePostgresDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *co
|
|||
}
|
||||
}
|
||||
|
||||
// rename DBPREFIXposts.cyclical to cyclic
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
query = `ALTER TABLE DBPREFIXposts CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -135,5 +135,19 @@ func updateSqliteDB(ctx context.Context, dbu *GCDatabaseUpdater, sqlConfig *conf
|
|||
}
|
||||
}
|
||||
|
||||
// rename DBPREFIXposts.cyclical to cyclic
|
||||
dataType, err = common.ColumnType(ctx, db, nil, "cyclic", "DBPREFIXposts", sqlConfig)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
if dataType == "" {
|
||||
query = `ALTER TABLE DBPREFIXposts CHANGE cyclical cyclic BOOL NOT NULL DEFAULT FALSE`
|
||||
if _, err = db.ExecContextSQL(ctx, nil, query); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func (*Pre2021Migrator) migratePost(tx *sql.Tx, post *migrationPost, errEv *zero
|
|||
Locked: post.locked,
|
||||
Stickied: post.stickied,
|
||||
Anchored: post.autosage,
|
||||
Cyclical: false,
|
||||
Cyclic: false,
|
||||
}
|
||||
if post.oldParentID == 0 {
|
||||
// migrating post was a thread OP, create the row in the threads table
|
||||
|
|
|
@ -83,7 +83,7 @@ func BuildBoardPages(board *gcsql.Board, errEv *zerolog.Event) error {
|
|||
Locked: boolToInt(thread.Locked),
|
||||
Stickied: boolToInt(thread.Stickied),
|
||||
IsSpoilered: boolToInt(thread.IsSpoilered),
|
||||
Cyclical: boolToInt(thread.Cyclical),
|
||||
Cyclic: boolToInt(thread.Cyclic),
|
||||
}
|
||||
errEv.Int("threadID", thread.ID)
|
||||
if catalogThread.Images, err = thread.GetReplyFileCount(); err != nil {
|
||||
|
|
|
@ -20,7 +20,7 @@ type catalogThreadData struct {
|
|||
OmittedImages int `json:"omitted_images"` // uploads in the thread but not shown on the board page
|
||||
Stickied int `json:"sticky"`
|
||||
IsSpoilered int `json:"spoilered"`
|
||||
Cyclical int `json:"cyclical"`
|
||||
Cyclic int `json:"cyclic"`
|
||||
Locked int `json:"closed"`
|
||||
Posts []*Post `json:"-"`
|
||||
uploads []gcsql.Upload
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
const (
|
||||
buildingPostsBaseQuery = `SELECT id, thread_id, ip, name, tripcode, is_secure_tripcode, email, subject, created_on,
|
||||
last_modified, parent_id, last_bump, message, message_raw, banned_message, board_id, dir, original_filename, filename,
|
||||
checksum, filesize, tw, th, width, height, spoiler_file, locked, stickied, cyclical, spoiler_thread, flag, country, is_deleted
|
||||
checksum, filesize, tw, th, width, height, spoiler_file, locked, stickied, cyclic, spoiler_thread, flag, country, is_deleted
|
||||
FROM DBPREFIXv_building_posts `
|
||||
)
|
||||
|
||||
|
@ -177,7 +177,7 @@ func (p *Post) Stickied() bool {
|
|||
}
|
||||
|
||||
func (p *Post) Cyclic() bool {
|
||||
return p.thread.Cyclical
|
||||
return p.thread.Cyclic
|
||||
}
|
||||
|
||||
func (p *Post) SpoilerThread() bool {
|
||||
|
@ -213,7 +213,7 @@ func QueryPosts(query string, params []any, cb func(*Post) error) error {
|
|||
&post.LastModified, &post.ParentID, &lastBump, &post.Message, &post.MessageRaw, &post.BannedMessage,
|
||||
&post.BoardID, &post.BoardDir, &post.OriginalFilename, &post.Filename, &post.Checksum, &post.Filesize,
|
||||
&post.ThumbnailWidth, &post.ThumbnailHeight, &post.UploadWidth, &post.UploadHeight, &spoilerFile,
|
||||
&post.thread.Locked, &post.thread.Stickied, &post.thread.Cyclical, &post.thread.IsSpoilered,
|
||||
&post.thread.Locked, &post.thread.Stickied, &post.thread.Cyclic, &post.thread.IsSpoilered,
|
||||
&post.Country.Flag, &post.Country.Name, &post.IsDeleted)
|
||||
|
||||
if err = rows.Scan(dest...); err != nil {
|
||||
|
|
|
@ -408,7 +408,7 @@ func (board *Board) GetThreads(onlyNotDeleted bool, orderLastByBump bool, sticki
|
|||
var thread Thread
|
||||
err = rows.Scan(
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored,
|
||||
&thread.Cyclical, &thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
&thread.Cyclic, &thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
)
|
||||
if err != nil {
|
||||
return threads, err
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
const (
|
||||
// GochanVersionKeyConstant is the key value used in the version table of the database to store and receive the (database) version of base gochan
|
||||
gochanVersionKeyConstant = "gochan"
|
||||
DatabaseVersion = 5
|
||||
DatabaseVersion = 6
|
||||
UnsupportedSQLVersionMsg = `syntax error in SQL query, confirm you are using a supported driver and SQL server (error text: %s)`
|
||||
mysqlConnStr = "%s:%s@tcp(%s)/%s?parseTime=true&collation=utf8mb4_unicode_ci"
|
||||
postgresConnStr = "postgres://%s:%s@%s/%s?sslmode=disable"
|
||||
|
|
|
@ -348,7 +348,7 @@ func (p *Post) UnlinkUploads(leaveDeletedBox bool, requestOpts ...*RequestOption
|
|||
// InCyclicThread returns true if the post is in a cyclic thread
|
||||
func (p *Post) InCyclicThread() (bool, error) {
|
||||
var cyclic bool
|
||||
err := QueryRowTimeoutSQL(nil, "SELECT cyclical FROM DBPREFIXthreads WHERE id = ?", []any{p.ThreadID}, []any{&cyclic})
|
||||
err := QueryRowTimeoutSQL(nil, "SELECT cyclic FROM DBPREFIXthreads WHERE id = ?", []any{p.ThreadID}, []any{&cyclic})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return false, ErrThreadDoesNotExist
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ func (p *Post) CyclicPostsToBePruned() ([]CyclicThreadPost, error) {
|
|||
defer cancel()
|
||||
|
||||
var cyclic bool
|
||||
err := QueryRowContextSQL(ctx, nil, "SELECT cyclical FROM DBPREFIXthreads WHERE id = ?", []any{p.ThreadID}, []any{&cyclic})
|
||||
err := QueryRowContextSQL(ctx, nil, "SELECT cyclic FROM DBPREFIXthreads WHERE id = ?", []any{p.ThreadID}, []any{&cyclic})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = ErrThreadDoesNotExist
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ func (p *Post) CyclicPostsToBePruned() ([]CyclicThreadPost, error) {
|
|||
}
|
||||
|
||||
rows, err := QueryContextSQL(ctx, nil, `SELECT post_id, thread_id, op_id, filename, dir
|
||||
FROM DBPREFIXv_posts_cyclical_check WHERE thread_id = ? AND post_id <> op_id ORDER BY post_id ASC`, p.ThreadID)
|
||||
FROM DBPREFIXv_posts_cyclic_check WHERE thread_id = ? AND post_id <> op_id ORDER BY post_id ASC`, p.ThreadID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
insertIntoThreadsBase = `INSERT INTO threads \(board_id, locked, stickied, anchored, cyclical, is_spoilered\) VALUES `
|
||||
insertIntoThreadsBase = `INSERT INTO threads \(board_id, locked, stickied, anchored, cyclic, is_spoilered\) VALUES `
|
||||
insertIntoThreadsMySQL = insertIntoThreadsBase + `\(\?,\?,\?,\?,\?,\?\)`
|
||||
insertIntoThreadsPostgres = insertIntoThreadsBase + `\(\$1,\$2,\$3,\$4,\$5,\$6\)`
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ var (
|
|||
`CREATE TABLE database_version\(\s+component VARCHAR\(40\) NOT NULL PRIMARY KEY,\s+version INT NOT NULL \)`,
|
||||
`CREATE TABLE sections\(\s+id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,\s+name TEXT NOT NULL,\s+abbreviation TEXT NOT NULL,\s+position SMALLINT NOT NULL,\s+hidden BOOL NOT NULL \)`,
|
||||
`CREATE TABLE boards\(\s*id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,\s+section_id BIGINT NOT NULL,\s+uri VARCHAR\(45\) NOT NULL,\s+dir VARCHAR\(45\) NOT NULL,\s+navbar_position SMALLINT NOT NULL,\s+title VARCHAR\(45\) NOT NULL,\s+subtitle VARCHAR\(64\) NOT NULL,\s+description VARCHAR\(64\) NOT NULL,\s+max_file_size INT NOT NULL,\s+max_threads SMALLINT NOT NULL, default_style VARCHAR\(45\) NOT NULL,\s+locked BOOL NOT NULL,\s+created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+anonymous_name VARCHAR\(45\) NOT NULL DEFAULT 'Anonymous',\s+force_anonymous BOOL NOT NULL,\s+autosage_after SMALLINT NOT NULL,\s+no_images_after SMALLINT NOT NULL,\s+max_message_length SMALLINT NOT NULL,\s+min_message_length SMALLINT NOT NULL,\s+allow_embeds BOOL NOT NULL,\s+redirect_to_thread BOOL NOT NULL,\s+require_file BOOL NOT NULL,\s+enable_catalog BOOL NOT NULL,\s+CONSTRAINT boards_section_id_fk\s+FOREIGN KEY\(section_id\) REFERENCES sections\(id\),\s+CONSTRAINT boards_dir_unique UNIQUE\(dir\),\s+CONSTRAINT boards_uri_unique UNIQUE\(uri\)\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclical BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclic BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE INDEX thread_deleted_index ON threads\(is_deleted\)`,
|
||||
`CREATE TABLE posts\(\s+id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,\s+thread_id BIGINT NOT NULL,\s+is_top_post BOOL NOT NULL DEFAULT FALSE,\s+ip VARBINARY\(16\) NOT NULL,\s+created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+name VARCHAR\(50\) NOT NULL DEFAULT '',\s+tripcode VARCHAR\(10\) NOT NULL DEFAULT '',\s+is_secure_tripcode BOOL NOT NULL DEFAULT FALSE,\s+is_role_signature BOOL NOT NULL DEFAULT FALSE, email VARCHAR\(50\) NOT NULL DEFAULT '',\s+subject VARCHAR\(100\) NOT NULL DEFAULT '',\s+message TEXT NOT NULL,\s+message_raw TEXT NOT NULL,\s+password TEXT NOT NULL,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+banned_message TEXT,\s+flag VARCHAR\(45\) NOT NULL DEFAULT '',\s+country VARCHAR\(80\) NOT NULL DEFAULT '',\s+CONSTRAINT posts_thread_id_fk\s+FOREIGN KEY\(thread_id\) REFERENCES threads\(id\) ON DELETE CASCADE \)`,
|
||||
`CREATE INDEX top_post_index ON posts\(is_top_post\)`,
|
||||
|
@ -40,7 +40,7 @@ var (
|
|||
`CREATE TABLE database_version\(\s+component VARCHAR\(40\) NOT NULL PRIMARY KEY,\s+version INT NOT NULL \)`,
|
||||
`CREATE TABLE sections\(\s+id BIGSERIAL PRIMARY KEY,\s+name TEXT NOT NULL,\s+abbreviation TEXT NOT NULL,\s+position SMALLINT NOT NULL,\s+hidden BOOL NOT NULL \)`,
|
||||
`CREATE TABLE boards\(\s*id BIGSERIAL PRIMARY KEY,\s+section_id BIGINT NOT NULL,\s+uri VARCHAR\(45\) NOT NULL,\s+dir VARCHAR\(45\) NOT NULL,\s+navbar_position SMALLINT NOT NULL,\s+title VARCHAR\(45\) NOT NULL,\s+subtitle VARCHAR\(64\) NOT NULL,\s+description VARCHAR\(64\) NOT NULL,\s+max_file_size INT NOT NULL,\s+max_threads SMALLINT NOT NULL, default_style VARCHAR\(45\) NOT NULL,\s+locked BOOL NOT NULL,\s+created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+anonymous_name VARCHAR\(45\) NOT NULL DEFAULT 'Anonymous',\s+force_anonymous BOOL NOT NULL,\s+autosage_after SMALLINT NOT NULL,\s+no_images_after SMALLINT NOT NULL,\s+max_message_length SMALLINT NOT NULL,\s+min_message_length SMALLINT NOT NULL,\s+allow_embeds BOOL NOT NULL,\s+redirect_to_thread BOOL NOT NULL,\s+require_file BOOL NOT NULL,\s+enable_catalog BOOL NOT NULL,\s+CONSTRAINT boards_section_id_fk\s+FOREIGN KEY\(section_id\) REFERENCES sections\(id\),\s+CONSTRAINT boards_dir_unique UNIQUE\(dir\),\s+CONSTRAINT boards_uri_unique UNIQUE\(uri\)\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id BIGSERIAL PRIMARY KEY,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclical BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id BIGSERIAL PRIMARY KEY,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclic BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE INDEX thread_deleted_index ON threads\(is_deleted\)`,
|
||||
`CREATE TABLE posts\(\s+id BIGSERIAL PRIMARY KEY,\s+thread_id BIGINT NOT NULL,\s+is_top_post BOOL NOT NULL DEFAULT FALSE,\s+ip INET NOT NULL,\s+created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+name VARCHAR\(50\) NOT NULL DEFAULT '',\s+tripcode VARCHAR\(10\) NOT NULL DEFAULT '',\s+is_secure_tripcode BOOL NOT NULL DEFAULT FALSE,\s+is_role_signature BOOL NOT NULL DEFAULT FALSE, email VARCHAR\(50\) NOT NULL DEFAULT '',\s+subject VARCHAR\(100\) NOT NULL DEFAULT '',\s+message TEXT NOT NULL,\s+message_raw TEXT NOT NULL,\s+password TEXT NOT NULL,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+banned_message TEXT,\s+flag VARCHAR\(45\) NOT NULL DEFAULT '',\s+country VARCHAR\(80\) NOT NULL DEFAULT '',\s+CONSTRAINT posts_thread_id_fk\s+FOREIGN KEY\(thread_id\) REFERENCES threads\(id\) ON DELETE CASCADE \)`,
|
||||
`CREATE INDEX top_post_index ON posts\(is_top_post\)`,
|
||||
|
@ -65,7 +65,7 @@ var (
|
|||
`CREATE TABLE database_version\(\s+component VARCHAR\(40\) NOT NULL PRIMARY KEY,\s+version INT NOT NULL \)`,
|
||||
`CREATE TABLE sections\(\s+id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\s+name TEXT NOT NULL,\s+abbreviation TEXT NOT NULL,\s+position SMALLINT NOT NULL,\s+hidden BOOL NOT NULL \)`,
|
||||
`CREATE TABLE boards\(\s*id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\s+section_id BIGINT NOT NULL,\s+uri VARCHAR\(45\) NOT NULL,\s+dir VARCHAR\(45\) NOT NULL,\s+navbar_position SMALLINT NOT NULL,\s+title VARCHAR\(45\) NOT NULL,\s+subtitle VARCHAR\(64\) NOT NULL,\s+description VARCHAR\(64\) NOT NULL,\s+max_file_size INT NOT NULL,\s+max_threads SMALLINT NOT NULL, default_style VARCHAR\(45\) NOT NULL,\s+locked BOOL NOT NULL,\s+created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+anonymous_name VARCHAR\(45\) NOT NULL DEFAULT 'Anonymous',\s+force_anonymous BOOL NOT NULL,\s+autosage_after SMALLINT NOT NULL,\s+no_images_after SMALLINT NOT NULL,\s+max_message_length SMALLINT NOT NULL,\s+min_message_length SMALLINT NOT NULL,\s+allow_embeds BOOL NOT NULL,\s+redirect_to_thread BOOL NOT NULL,\s+require_file BOOL NOT NULL,\s+enable_catalog BOOL NOT NULL,\s+CONSTRAINT boards_section_id_fk\s+FOREIGN KEY\(section_id\) REFERENCES sections\(id\),\s+CONSTRAINT boards_dir_unique UNIQUE\(dir\),\s+CONSTRAINT boards_uri_unique UNIQUE\(uri\)\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclical BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE TABLE threads\(\s*id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\s+board_id BIGINT NOT NULL,\s+locked BOOL NOT NULL DEFAULT FALSE,\s+stickied BOOL NOT NULL DEFAULT FALSE,\s+anchored BOOL NOT NULL DEFAULT FALSE,\s+cyclic BOOL NOT NULL DEFAULT FALSE,\s+is_spoilered BOOL NOT NULL DEFAULT FALSE,\s+last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+CONSTRAINT threads_board_id_fk\s+FOREIGN KEY\(board_id\) REFERENCES boards\(id\) ON DELETE CASCADE\s*\)`,
|
||||
`CREATE INDEX thread_deleted_index ON threads\(is_deleted\)`,
|
||||
`CREATE TABLE posts\(\s+id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\s+thread_id BIGINT NOT NULL,\s+is_top_post BOOL NOT NULL DEFAULT FALSE,\s+ip VARCHAR\(45\) NOT NULL,\s+created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+name VARCHAR\(50\) NOT NULL DEFAULT '',\s+tripcode VARCHAR\(10\) NOT NULL DEFAULT '',\s+is_secure_tripcode BOOL NOT NULL DEFAULT FALSE,\s+is_role_signature BOOL NOT NULL DEFAULT FALSE, email VARCHAR\(50\) NOT NULL DEFAULT '',\s+subject VARCHAR\(100\) NOT NULL DEFAULT '',\s+message TEXT NOT NULL,\s+message_raw TEXT NOT NULL,\s+password TEXT NOT NULL,\s+deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\s+is_deleted BOOL NOT NULL DEFAULT FALSE,\s+banned_message TEXT,\s+flag VARCHAR\(45\) NOT NULL DEFAULT '',\s+country VARCHAR\(80\) NOT NULL DEFAULT '',\s+CONSTRAINT posts_thread_id_fk\s+FOREIGN KEY\(thread_id\) REFERENCES threads\(id\) ON DELETE CASCADE \)`,
|
||||
`CREATE INDEX top_post_index ON posts\(is_top_post\)`,
|
||||
|
|
|
@ -280,7 +280,7 @@ type Thread struct {
|
|||
Locked bool // sql: locked
|
||||
Stickied bool // sql: stickied
|
||||
Anchored bool // sql: anchored
|
||||
Cyclical bool // sql: cyclical
|
||||
Cyclic bool // sql: cyclic
|
||||
IsSpoilered bool // sql: is_spoilered
|
||||
LastBump time.Time // sql: last_bump
|
||||
DeletedAt time.Time // sql: deleted_at
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
const (
|
||||
selectThreadsBaseSQL = `SELECT
|
||||
id, board_id, locked, stickied, anchored, cyclical, is_spoilered, last_bump, deleted_at, is_deleted
|
||||
id, board_id, locked, stickied, anchored, cyclic, is_spoilered, last_bump, deleted_at, is_deleted
|
||||
FROM DBPREFIXthreads `
|
||||
)
|
||||
|
||||
|
@ -22,7 +22,7 @@ var (
|
|||
// CreateThread creates a new thread in the database with the given board ID and statuses
|
||||
func CreateThread(requestOptions *RequestOptions, thread *Thread) (err error) {
|
||||
const lockedQuery = `SELECT locked FROM DBPREFIXboards WHERE id = ?`
|
||||
const insertQuery = `INSERT INTO DBPREFIXthreads (board_id, locked, stickied, anchored, cyclical, is_spoilered) VALUES (?,?,?,?,?,?)`
|
||||
const insertQuery = `INSERT INTO DBPREFIXthreads (board_id, locked, stickied, anchored, cyclic, is_spoilered) VALUES (?,?,?,?,?,?)`
|
||||
var boardIsLocked bool
|
||||
if err = QueryRow(requestOptions, lockedQuery, []any{&thread.BoardID}, []any{&boardIsLocked}); err != nil {
|
||||
return err
|
||||
|
@ -30,7 +30,7 @@ func CreateThread(requestOptions *RequestOptions, thread *Thread) (err error) {
|
|||
if boardIsLocked {
|
||||
return ErrBoardIsLocked
|
||||
}
|
||||
if _, err = Exec(requestOptions, insertQuery, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclical, &thread.IsSpoilered); err != nil {
|
||||
if _, err = Exec(requestOptions, insertQuery, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclic, &thread.IsSpoilered); err != nil {
|
||||
return err
|
||||
}
|
||||
return QueryRow(requestOptions, "SELECT MAX(id) FROM DBPREFIXthreads", nil, []any{&thread.ID})
|
||||
|
@ -41,7 +41,7 @@ func GetThread(threadID int) (*Thread, error) {
|
|||
const query = selectThreadsBaseSQL + `WHERE id = ?`
|
||||
thread := new(Thread)
|
||||
err := QueryRow(nil, query, []any{threadID}, []any{
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclical,
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclic,
|
||||
&thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
})
|
||||
return thread, err
|
||||
|
@ -52,7 +52,7 @@ func GetPostThread(opID int) (*Thread, error) {
|
|||
const query = selectThreadsBaseSQL + `WHERE id = (SELECT thread_id FROM DBPREFIXposts WHERE id = ? LIMIT 1)`
|
||||
thread := new(Thread)
|
||||
err := QueryRow(nil, query, []any{opID}, []any{
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclical,
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored, &thread.Cyclic,
|
||||
&thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
@ -90,7 +90,7 @@ func GetThreadsWithBoardID(boardID int, onlyNotDeleted bool) ([]Thread, error) {
|
|||
var thread Thread
|
||||
if err = rows.Scan(
|
||||
&thread.ID, &thread.BoardID, &thread.Locked, &thread.Stickied, &thread.Anchored,
|
||||
&thread.Cyclical, &thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
&thread.Cyclic, &thread.IsSpoilered, &thread.LastBump, &thread.DeletedAt, &thread.IsDeleted,
|
||||
); err != nil {
|
||||
return threads, err
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ func (t *Thread) UpdateAttribute(attribute string, value bool) error {
|
|||
case "anchored":
|
||||
t.Anchored = value
|
||||
case "cyclic":
|
||||
t.Cyclical = value
|
||||
t.Cyclic = value
|
||||
default:
|
||||
return fmt.Errorf("invalid thread attribute %q", attribute)
|
||||
}
|
||||
|
|
|
@ -446,11 +446,11 @@ func threadAttrsCallback(_ http.ResponseWriter, request *http.Request, _ *gcsql.
|
|||
} else if request.FormValue("uncyclic") != "" {
|
||||
attr = "cyclic"
|
||||
newVal = false
|
||||
doChange = thread.Cyclical != newVal
|
||||
doChange = thread.Cyclic != newVal
|
||||
} else if request.FormValue("cyclic") != "" {
|
||||
attr = "cyclic"
|
||||
newVal = true
|
||||
doChange = thread.Cyclical != newVal
|
||||
doChange = thread.Cyclic != newVal
|
||||
}
|
||||
|
||||
if attr != "" && doChange {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.9">
|
||||
<diagram id="TVQ4taKJlGjEfO4J5nL0" name="Page-1">
|
||||
<mxGraphModel dx="2754" dy="2167" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<mxGraphModel dx="1835" dy="1652" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
@ -771,10 +771,10 @@
|
|||
<mxCell id="PdcwpANUKP4F5l-W0EyN-188" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" parent="PdcwpANUKP4F5l-W0EyN-187" vertex="1" connectable="0">
|
||||
<mxGeometry width="56" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-3" value="is_role_signature" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=60;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" vertex="1" parent="PdcwpANUKP4F5l-W0EyN-132">
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-3" value="is_role_signature" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=60;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="PdcwpANUKP4F5l-W0EyN-132" vertex="1">
|
||||
<mxGeometry y="238" width="220" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-4" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" vertex="1" connectable="0" parent="tuHC6-spi_Zi7_7CJrgR-3">
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-4" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" parent="tuHC6-spi_Zi7_7CJrgR-3" vertex="1" connectable="0">
|
||||
<mxGeometry width="56" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="PdcwpANUKP4F5l-W0EyN-189" value="email" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=60;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="PdcwpANUKP4F5l-W0EyN-132" vertex="1">
|
||||
|
@ -958,16 +958,16 @@
|
|||
<mxCell id="g8VmcGA17cuox0www8EO-89" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" parent="g8VmcGA17cuox0www8EO-88" vertex="1" connectable="0">
|
||||
<mxGeometry width="30" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="g8VmcGA17cuox0www8EO-90" value="cyclical" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=34;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="g8VmcGA17cuox0www8EO-75" vertex="1">
|
||||
<mxCell id="g8VmcGA17cuox0www8EO-90" value="cyclic" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=34;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="g8VmcGA17cuox0www8EO-75" vertex="1">
|
||||
<mxGeometry y="160" width="160" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="g8VmcGA17cuox0www8EO-91" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" parent="g8VmcGA17cuox0www8EO-90" vertex="1" connectable="0">
|
||||
<mxGeometry width="30" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-1" value="spoilered" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=34;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" vertex="1" parent="g8VmcGA17cuox0www8EO-75">
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-1" value="is_spoilered" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=34;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="g8VmcGA17cuox0www8EO-75" vertex="1">
|
||||
<mxGeometry y="186" width="160" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-2" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" vertex="1" connectable="0" parent="tuHC6-spi_Zi7_7CJrgR-1">
|
||||
<mxCell id="tuHC6-spi_Zi7_7CJrgR-2" value="" style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[];portConstraint=eastwest;part=1;fontSize=12;" parent="tuHC6-spi_Zi7_7CJrgR-1" vertex="1" connectable="0">
|
||||
<mxGeometry width="30" height="26" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="g8VmcGA17cuox0www8EO-86" value="last_bump" style="shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;fillColor=none;spacingLeft=34;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;fontSize=12;" parent="g8VmcGA17cuox0www8EO-75" vertex="1">
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 589 KiB After Width: | Height: | Size: 589 KiB |
|
@ -54,7 +54,7 @@ CREATE TABLE DBPREFIXthreads(
|
|||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclic BOOL NOT NULL DEFAULT FALSE,
|
||||
is_spoilered BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -47,7 +47,7 @@ CREATE TABLE DBPREFIXthreads(
|
|||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclic BOOL NOT NULL DEFAULT FALSE,
|
||||
is_spoilered BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -47,7 +47,7 @@ CREATE TABLE DBPREFIXthreads(
|
|||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclic BOOL NOT NULL DEFAULT FALSE,
|
||||
is_spoilered BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -47,7 +47,7 @@ CREATE TABLE DBPREFIXthreads(
|
|||
locked BOOL NOT NULL DEFAULT FALSE,
|
||||
stickied BOOL NOT NULL DEFAULT FALSE,
|
||||
anchored BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclical BOOL NOT NULL DEFAULT FALSE,
|
||||
cyclic BOOL NOT NULL DEFAULT FALSE,
|
||||
is_spoilered BOOL NOT NULL DEFAULT FALSE,
|
||||
last_bump TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
|
|
@ -8,7 +8,7 @@ DROP VIEW IF EXISTS DBPREFIXv_upload_info;
|
|||
DROP VIEW IF EXISTS DBPREFIXv_front_page_posts_with_file;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_front_page_posts;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete_file_only;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_posts_cyclical_check;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_posts_cyclic_check;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_recent_posts;
|
||||
DROP VIEW IF EXISTS DBPREFIXv_building_posts;
|
||||
|
@ -37,7 +37,7 @@ COALESCE(f.thumbnail_height, 0) AS th,
|
|||
COALESCE(f.width, 0) AS width,
|
||||
COALESCE(f.height, 0) AS height,
|
||||
COALESCE(f.is_spoilered, FALSE) AS spoiler_file,
|
||||
t.locked, t.stickied, t.cyclical, t.is_spoilered as spoiler_thread, flag, country, p.is_deleted
|
||||
t.locked, t.stickied, t.cyclic, t.is_spoilered as spoiler_thread, flag, country, p.is_deleted
|
||||
FROM DBPREFIXposts p
|
||||
LEFT JOIN DBPREFIXfiles f ON f.post_id = p.id AND p.is_deleted = FALSE
|
||||
LEFT JOIN DBPREFIXthreads t ON t.id = p.thread_id
|
||||
|
@ -58,12 +58,12 @@ CREATE VIEW DBPREFIXv_posts_to_delete_file_only AS
|
|||
SELECT * FROM DBPREFIXv_posts_to_delete
|
||||
WHERE filename IS NOT NULL;
|
||||
|
||||
CREATE VIEW DBPREFIXv_posts_cyclical_check AS
|
||||
CREATE VIEW DBPREFIXv_posts_cyclic_check AS
|
||||
SELECT post_id, d.thread_id, op_id, d.is_top_post, filename, dir
|
||||
FROM DBPREFIXv_posts_to_delete d
|
||||
INNER JOIN DBPREFIXposts p ON p.id = post_id
|
||||
INNER JOIN DBPREFIXthreads t ON d.thread_id = t.id
|
||||
WHERE p.is_deleted = FALSE AND d.is_top_post = FALSE and t.cyclical = TRUE;
|
||||
WHERE p.is_deleted = FALSE AND d.is_top_post = FALSE and t.cyclic = TRUE;
|
||||
|
||||
CREATE VIEW DBPREFIXv_front_page_posts AS
|
||||
SELECT DBPREFIXposts.id, DBPREFIXposts.message_raw,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<span class="status-icons">
|
||||
{{- if $.thread.Locked}}<img src="{{webPath `/static/lock.png`}}" class="locked-icon" alt="Thread locked" title="Thread locked">{{end -}}
|
||||
{{- if $.thread.Stickied}}<img src="{{webPath `/static/sticky.png`}}" class="sticky-icon" alt="Sticky" title="Sticky">{{end -}}
|
||||
{{- if $.thread.Cyclical}}<img src="{{webPath `/static/cyclic.png`}}" class="cyclic-icon" alt="Cyclic thread" title="Cyclic thread">{{end -}}
|
||||
{{- if $.thread.Cyclic}}<img src="{{webPath `/static/cyclic.png`}}" class="cyclic-icon" alt="Cyclic thread" title="Cyclic thread">{{end -}}
|
||||
</span>
|
||||
{{if $.is_board_page -}}
|
||||
[<a href="{{.post.ThreadPath}}">View</a>]
|
||||
|
|
1
vagrant/Vagrantfile
vendored
1
vagrant/Vagrantfile
vendored
|
@ -19,6 +19,7 @@ Vagrant.configure("2") do |config|
|
|||
config.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
config.vm.network "forwarded_port", guest: 443, host: 4430
|
||||
config.vm.network "forwarded_port", guest: 4040, host: 4040
|
||||
config.vm.network "forwarded_port", guest: 3306, host: 3306
|
||||
|
||||
config.vm.network :private_network, ip: "192.168.56.3"
|
||||
config.vm.synced_folder "../", "/vagrant"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue