Merge pull request 'Implemented database scripting for installation, conversion, and migration' (#4) from database-scripting into main
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
Vendored
+11
-1
@@ -11,6 +11,16 @@
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Blank Test",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}",
|
||||
"env": {
|
||||
"AMSTERDAM_DATABASE_NAME": "blank"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "EMinds Reborn",
|
||||
"type": "go",
|
||||
@@ -18,7 +28,7 @@
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}",
|
||||
"env": {
|
||||
"AMSTERDAM_CONFIG": "/u01/home/amy/Erbosoft/emreborn/amsterdam.yaml"
|
||||
"AMSTERDAM_CONFIG": "${env:HOME}/Erbosoft/emreborn/amsterdam.yaml"
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
+187
-5
@@ -13,35 +13,217 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.erbosoft.com/amy/amsterdam/config"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/jmoiron/sqlx"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Error classifications
|
||||
const (
|
||||
classUnspecified = 0
|
||||
classNeedInstall = 1
|
||||
classNeedConvert = 2
|
||||
)
|
||||
|
||||
// MySQL Errors
|
||||
var errMySQLNoTable = &mysql.MySQLError{Number: 1146}
|
||||
var errMySQLNoColumn = &mysql.MySQLError{Number: 1054}
|
||||
|
||||
//go:embed mysql-install.sql
|
||||
var installScriptMySQL string
|
||||
|
||||
//go:embed mysql-convert.sql
|
||||
var convertScriptMySQL string
|
||||
|
||||
//go:embed mysql-migrate/*
|
||||
var migrationsMySQL embed.FS
|
||||
|
||||
// amdb is the reference to the Amsterdam database.
|
||||
var amdb *sqlx.DB
|
||||
|
||||
// buildMysqlDSN builds the MySQL DSN for the driver.
|
||||
func buildMysqlDSN() string {
|
||||
return fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true&loc=UTC",
|
||||
func buildMysqlDSN(multiStatement bool) string {
|
||||
rc := fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true&loc=UTC",
|
||||
config.GlobalComputedConfig.DatabaseUser,
|
||||
config.GlobalComputedConfig.DatabasePassword,
|
||||
config.GlobalComputedConfig.DatabaseHost,
|
||||
config.GlobalComputedConfig.DatabaseName)
|
||||
if multiStatement {
|
||||
rc += "&multiStatements=true"
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// classifyGetError classifies errors returns from the original get of the version number.
|
||||
func classifyGetError(err error) int {
|
||||
if errors.Is(err, errMySQLNoTable) {
|
||||
return classNeedInstall
|
||||
}
|
||||
if errors.Is(err, errMySQLNoColumn) {
|
||||
return classNeedConvert
|
||||
}
|
||||
return classUnspecified
|
||||
}
|
||||
|
||||
// databaseVersionNumber reads the version number from the database.
|
||||
func databaseVersionNumber(db *sqlx.DB) (string, error) {
|
||||
ver := ""
|
||||
err := db.Get(&ver, "SELECT version FROM globals")
|
||||
return ver, err
|
||||
}
|
||||
|
||||
// setDatabaseVersionNumber resets the version number in the database.
|
||||
func setDatabaseVersionNumber(db *sqlx.DB, version string) error {
|
||||
_, err := db.Exec("UPDATE globals SET version = ?", version)
|
||||
return err
|
||||
}
|
||||
|
||||
// databaseInstallScript returns the install script for the database.
|
||||
func databaseInstallScript() (string, error) {
|
||||
switch config.GlobalComputedConfig.DatabaseDriver {
|
||||
case "mysql":
|
||||
return installScriptMySQL, nil
|
||||
default:
|
||||
return "", fmt.Errorf("No install script for database driver: %s", config.GlobalComputedConfig.DatabaseDriver)
|
||||
}
|
||||
}
|
||||
|
||||
// databaseConvertScript returns the script to convert a Venice database to Amsterdam.
|
||||
func databaseConvertScript() (string, error) {
|
||||
switch config.GlobalComputedConfig.DatabaseDriver {
|
||||
case "mysql":
|
||||
return convertScriptMySQL, nil
|
||||
default: // N.B.: Not to be implemented for any database type besides MySQL!
|
||||
return "", fmt.Errorf("No conversion script for database driver: %s", config.GlobalComputedConfig.DatabaseDriver)
|
||||
}
|
||||
}
|
||||
|
||||
// databaseMigrationScripts returns the migration scripts to apply to the database.
|
||||
func databaseMigrationScripts(version string) (fs.FS, string, []string, error) {
|
||||
var myfs fs.FS
|
||||
var dirname string = ""
|
||||
var err error = nil
|
||||
switch config.GlobalComputedConfig.DatabaseDriver {
|
||||
case "mysql":
|
||||
myfs = migrationsMySQL
|
||||
dirname = "mysql-migrate"
|
||||
default:
|
||||
err = fmt.Errorf("No migration scripts for database driver: %s", config.GlobalComputedConfig.DatabaseDriver)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", make([]string, 0), err
|
||||
}
|
||||
rdfs := myfs.(fs.ReadDirFS)
|
||||
dents, err := rdfs.ReadDir(dirname)
|
||||
if err != nil {
|
||||
return nil, "", make([]string, 0), err
|
||||
}
|
||||
rc := make([]string, 0, len(dents))
|
||||
for _, d := range dents {
|
||||
s := strings.TrimSuffix(d.Name(), ".sql")
|
||||
m, err := regexp.Match(`\d{10}`, []byte(s))
|
||||
if err != nil {
|
||||
return nil, "", make([]string, 0), err
|
||||
}
|
||||
if m && s > version {
|
||||
rc = append(rc, d.Name())
|
||||
}
|
||||
}
|
||||
if len(rc) > 1 {
|
||||
slices.Sort(rc)
|
||||
}
|
||||
return myfs, dirname, rc, nil
|
||||
}
|
||||
|
||||
// prepareDB prepares the database if it's not yet been loaded.
|
||||
func prepareDB() (string, error) {
|
||||
dsn := buildMysqlDSN(true)
|
||||
log.Debugf("dsn=%s", dsn)
|
||||
db, err := sqlx.Connect(config.GlobalComputedConfig.DatabaseDriver, dsn)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer db.Close()
|
||||
version, err := databaseVersionNumber(db)
|
||||
if err != nil {
|
||||
switch classifyGetError(err) {
|
||||
case classUnspecified:
|
||||
log.Errorf("*** cannot get version number: %v (%T)", err, err)
|
||||
return version, err
|
||||
case classNeedInstall:
|
||||
installScript, err := databaseInstallScript()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = db.Exec(installScript)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failure of install script: %w", err)
|
||||
}
|
||||
case classNeedConvert:
|
||||
convertScript, err := databaseConvertScript()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = db.Exec(convertScript)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failure of conversion script: %w", err)
|
||||
}
|
||||
}
|
||||
version, err = databaseVersionNumber(db)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
scriptfs, dirname, scripts, err := databaseMigrationScripts(version)
|
||||
if err == nil {
|
||||
log.Infof("%d migration script(s) to be applied", len(scripts))
|
||||
rffs := scriptfs.(fs.ReadFileFS)
|
||||
for _, script := range scripts {
|
||||
log.Infof("applying migration script: %s", script)
|
||||
var data []byte
|
||||
data, err = rffs.ReadFile(fmt.Sprintf("%s/%s", dirname, script))
|
||||
if err != nil {
|
||||
return version, fmt.Errorf("Unable to read migration script %s: %w", script, err)
|
||||
}
|
||||
_, err = db.Exec(string(data))
|
||||
if err != nil {
|
||||
return version, fmt.Errorf("Unable to apply migration script %s: %w", script, err)
|
||||
}
|
||||
nv := strings.TrimSuffix(script, ".sql")
|
||||
err = setDatabaseVersionNumber(db, nv)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
version = nv
|
||||
}
|
||||
}
|
||||
return version, err
|
||||
}
|
||||
|
||||
// SetupDb sets up the database and associated items.
|
||||
func SetupDb() (func(), error) {
|
||||
exitfns := make([]func(), 0, 2)
|
||||
db, err := sqlx.Connect(config.GlobalComputedConfig.DatabaseDriver, buildMysqlDSN())
|
||||
version, err := prepareDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db, err := sqlx.Connect(config.GlobalComputedConfig.DatabaseDriver, buildMysqlDSN(false))
|
||||
if err == nil {
|
||||
amdb = db
|
||||
g, err := AmGlobals(context.Background())
|
||||
if err == nil {
|
||||
if g.Version != version {
|
||||
log.Warnf("!! database version %s does not match prepared version %s", g.Version, version)
|
||||
}
|
||||
setupAdCache()
|
||||
setupUserCache()
|
||||
setupContactsCache()
|
||||
@@ -53,8 +235,8 @@ func SetupDb() (func(), error) {
|
||||
log.Infof("SetupDb(): database version %s", g.Version)
|
||||
}
|
||||
}
|
||||
slices.Reverse(exitfns)
|
||||
return func() {
|
||||
slices.Reverse(exitfns)
|
||||
for _, f := range exitfns {
|
||||
f()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# MySQL script for migrating a Venice database to the Amsterdam schema.
|
||||
# Written by Amy Bowersox <amy@erbosoft.com>
|
||||
#---------------------------------------------------------------------------
|
||||
# Amsterdam Web Communities System
|
||||
# Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||
#
|
||||
@@ -10,7 +7,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
|
||||
ALTER TABLE globals RENAME COLUMN max_sig_mbr_page TO max_comm_mbr_page;
|
||||
ALTER TABLE globals RENAME COLUMN sig_create_lvl TO comm_create_lvl;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# MySQL script for initializing the Amsterdam database (contents only).
|
||||
# Written by Amy Bowersox <amy@erbosoft.com>
|
||||
#---------------------------------------------------------------------------
|
||||
# Amsterdam Web Communities System
|
||||
# Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||
# Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -10,14 +7,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
# Table Creation
|
||||
##############################################################################
|
||||
|
||||
# The global parameters table. This is used for stuff that a Venice admin would be
|
||||
# likely to edit "on the fly." Stuff that can only be updated with a shutdown should go
|
||||
# in the XML config file. This table has ONLY ONE ROW!
|
||||
CREATE TABLE globals (
|
||||
version CHAR(10) NOT NULL,
|
||||
posts_per_page INT NOT NULL,
|
||||
@@ -30,14 +19,11 @@ CREATE TABLE globals (
|
||||
comm_create_lvl INT NOT NULL
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The global properties table. The "ndx" parameter is used to indicate what
|
||||
# element is being loaded, and then the "data" element is parsed.
|
||||
CREATE TABLE propglobal (
|
||||
ndx INT NOT NULL PRIMARY KEY,
|
||||
data VARCHAR(255)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The audit records table. Most "major" events add a record to this table.
|
||||
CREATE TABLE audit (
|
||||
record BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
on_date DATETIME NOT NULL,
|
||||
@@ -53,7 +39,6 @@ CREATE TABLE audit (
|
||||
INDEX comm_view (commid, on_date)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The user information table.
|
||||
CREATE TABLE users (
|
||||
uid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
username VARCHAR(64) NOT NULL,
|
||||
@@ -74,15 +59,12 @@ CREATE TABLE users (
|
||||
UNIQUE INDEX username_x (username)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# User preferences table.
|
||||
CREATE TABLE userprefs (
|
||||
uid INT NOT NULL PRIMARY KEY,
|
||||
tzid VARCHAR(64) DEFAULT 'UTC',
|
||||
localeid VARCHAR(64) DEFAULT 'en_US'
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The per-user properties table. The "ndx" parameter is used to indicate what
|
||||
# element is being loaded, and then the "data" element is parsed.
|
||||
CREATE TABLE propuser (
|
||||
uid INT NOT NULL,
|
||||
ndx INT NOT NULL,
|
||||
@@ -90,7 +72,6 @@ CREATE TABLE propuser (
|
||||
PRIMARY KEY (uid, ndx)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Indicates what the top-level "sidebox" configuration is for any given user.
|
||||
CREATE TABLE sideboxes (
|
||||
uid INT NOT NULL,
|
||||
boxid INT NOT NULL,
|
||||
@@ -100,7 +81,6 @@ CREATE TABLE sideboxes (
|
||||
INDEX inorder (uid, sequence)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The contact information table. This is used for both users and communities.
|
||||
CREATE TABLE contacts (
|
||||
contactid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
given_name VARCHAR(64),
|
||||
@@ -130,14 +110,12 @@ CREATE TABLE contacts (
|
||||
lastupdate DATETIME
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# A table listing email addresses which are barred from registering.
|
||||
CREATE TABLE emailban (
|
||||
address VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||
by_uid INT,
|
||||
on_date DATETIME
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The community table.
|
||||
CREATE TABLE communities (
|
||||
commid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
createdate DATETIME NOT NULL,
|
||||
@@ -168,7 +146,6 @@ CREATE TABLE communities (
|
||||
INDEX list_alpha (catid, commname)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table mapping category IDs to category names.
|
||||
CREATE TABLE refcategory (
|
||||
catid INT NOT NULL PRIMARY KEY,
|
||||
parent INT NOT NULL,
|
||||
@@ -179,14 +156,12 @@ CREATE TABLE refcategory (
|
||||
UNIQUE INDEX display (parent, name)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table mapping communities and their associated features.
|
||||
CREATE TABLE commftrs (
|
||||
commid INT NOT NULL,
|
||||
ftr_code SMALLINT NOT NULL,
|
||||
PRIMARY KEY (commid, ftr_code)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table mapping members of a community and their access levels.
|
||||
CREATE TABLE commmember (
|
||||
commid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -196,7 +171,6 @@ CREATE TABLE commmember (
|
||||
PRIMARY KEY (commid, uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# A table listing users which have been banned from joining a community.
|
||||
CREATE TABLE commban (
|
||||
commid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -205,8 +179,6 @@ CREATE TABLE commban (
|
||||
PRIMARY KEY (commid, uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The community properties table. The "index" parameter is used to indicate what
|
||||
# element is being loaded, and then the "data" element is parsed.
|
||||
CREATE TABLE propcomm (
|
||||
cid INT NOT NULL,
|
||||
ndx INT NOT NULL,
|
||||
@@ -214,8 +186,6 @@ CREATE TABLE propcomm (
|
||||
PRIMARY KEY (cid, ndx)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table describing conferences. Like original CW, confs may be linked to more
|
||||
# than one community.
|
||||
CREATE TABLE confs (
|
||||
confid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
createdate DATETIME NOT NULL,
|
||||
@@ -235,7 +205,6 @@ CREATE TABLE confs (
|
||||
INDEX name_x (name)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table that links communities to conferences.
|
||||
CREATE TABLE commtoconf (
|
||||
commid INT NOT NULL,
|
||||
confid INT NOT NULL,
|
||||
@@ -246,15 +215,12 @@ CREATE TABLE commtoconf (
|
||||
INDEX display_ord (commid, sequence)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table listing "aliases" to a conference for post-linking purposes.
|
||||
CREATE TABLE confalias (
|
||||
confid INT NOT NULL,
|
||||
alias VARCHAR(64) NOT NULL PRIMARY KEY,
|
||||
INDEX confid_x (confid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# A "membership" table for conferences used to control access to private conferences
|
||||
# and grant conference hosting powers.
|
||||
CREATE TABLE confmember (
|
||||
confid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -262,7 +228,6 @@ CREATE TABLE confmember (
|
||||
PRIMARY KEY (confid, uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Holds "saved settings" for a user with respect to a conference.
|
||||
CREATE TABLE confsettings (
|
||||
confid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -272,7 +237,6 @@ CREATE TABLE confsettings (
|
||||
PRIMARY KEY (confid, uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The "hot list" of conferences for a given user.
|
||||
CREATE TABLE confhotlist (
|
||||
uid INT NOT NULL,
|
||||
sequence SMALLINT NOT NULL,
|
||||
@@ -282,8 +246,6 @@ CREATE TABLE confhotlist (
|
||||
INDEX inorder (uid, sequence)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The conference properties table. The "index" parameter is used to indicate what
|
||||
# element is being loaded, and then the "data" element is parsed.
|
||||
CREATE TABLE propconf (
|
||||
confid INT NOT NULL,
|
||||
ndx INT NOT NULL,
|
||||
@@ -291,15 +253,12 @@ CREATE TABLE propconf (
|
||||
PRIMARY KEY (confid, ndx)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The conference custom HTML block table. There are two custom blocks, one at the
|
||||
# top of the page, one at the bottom, each a maximum of 64K in length.
|
||||
CREATE TABLE confcustom (
|
||||
confid INT NOT NULL PRIMARY KEY,
|
||||
htmltop TEXT,
|
||||
htmlbottom TEXT
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The table describing topics within a conference.
|
||||
CREATE TABLE topics (
|
||||
topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
confid INT NOT NULL,
|
||||
@@ -317,7 +276,6 @@ CREATE TABLE topics (
|
||||
INDEX by_date (confid, lastupdate)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Holds "saved settings" for a user with respect to a topic.
|
||||
CREATE TABLE topicsettings (
|
||||
topicid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -329,8 +287,6 @@ CREATE TABLE topicsettings (
|
||||
PRIMARY KEY (topicid, uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The "bozo filter" list for a topic, for use by users in filtering out
|
||||
# the rantings of other users who are bozos.
|
||||
CREATE TABLE topicbozo (
|
||||
topicid INT NOT NULL,
|
||||
uid INT NOT NULL,
|
||||
@@ -338,7 +294,6 @@ CREATE TABLE topicbozo (
|
||||
PRIMARY KEY (topicid, uid, bozo_uid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The "header" for a posted message.
|
||||
CREATE TABLE posts (
|
||||
postid BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
parent BIGINT NOT NULL DEFAULT 0,
|
||||
@@ -356,14 +311,12 @@ CREATE TABLE posts (
|
||||
INDEX child_order (parent, num)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# The actual message text.
|
||||
CREATE TABLE postdata (
|
||||
postid BIGINT NOT NULL PRIMARY KEY,
|
||||
data MEDIUMTEXT,
|
||||
FULLTEXT INDEX searchpost (data)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Message attachment.
|
||||
CREATE TABLE postattach (
|
||||
postid BIGINT NOT NULL PRIMARY KEY,
|
||||
datalen INT,
|
||||
@@ -376,14 +329,12 @@ CREATE TABLE postattach (
|
||||
data MEDIUMBLOB
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# "Bookmark" table for posts we like.
|
||||
CREATE TABLE postdogear (
|
||||
uid INT NOT NULL,
|
||||
postid BIGINT NOT NULL,
|
||||
PRIMARY KEY (uid, postid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# "Front page" publishing table.
|
||||
CREATE TABLE postpublish (
|
||||
commid INT NOT NULL,
|
||||
postid BIGINT NOT NULL PRIMARY KEY,
|
||||
@@ -392,7 +343,6 @@ CREATE TABLE postpublish (
|
||||
INDEX display_order (on_date, postid)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Advertisement (actually quote, for now) banners
|
||||
CREATE TABLE adverts (
|
||||
adid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
imagepath VARCHAR(255) NOT NULL,
|
||||
@@ -401,7 +351,6 @@ CREATE TABLE adverts (
|
||||
linkurl VARCHAR(255)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Storage space for uploaded images.
|
||||
CREATE TABLE imagestore (
|
||||
imgid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
typecode SMALLINT DEFAULT 0,
|
||||
@@ -411,7 +360,6 @@ CREATE TABLE imagestore (
|
||||
data MEDIUMBLOB
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
# Table listing IP addresses that are banned from logging in or registering.
|
||||
CREATE TABLE ipban (
|
||||
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
address_lo BIGINT UNSIGNED NOT NULL,
|
||||
@@ -427,13 +375,7 @@ CREATE TABLE ipban (
|
||||
INDEX by_date (block_on)
|
||||
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
##############################################################################
|
||||
# Constant Data Population
|
||||
##############################################################################
|
||||
|
||||
# Populate the Category table.
|
||||
# Source: Mozilla Open Directory Project categorization system <http://dmoz.org>;
|
||||
# additional categorization from WebbMe categories
|
||||
INSERT INTO refcategory (catid, parent, symlink, name) VALUES
|
||||
(0, -1, -1, 'Unclassified'),
|
||||
(1, -1, -1, 'Arts'),
|
||||
@@ -801,10 +743,8 @@ INSERT INTO refcategory (catid, parent, symlink, name) VALUES
|
||||
(15, -1, -1, 'System');
|
||||
### -- LAST IS 363 -- ###
|
||||
|
||||
# Make sure the special "System" category is hidden.
|
||||
UPDATE refcategory SET hide_dir = 1, hide_search = 1 WHERE catid = 15;
|
||||
|
||||
# Create the initial advertisements (quotes).
|
||||
INSERT INTO adverts (imagepath) VALUES
|
||||
('images/ads/Brown.gif'),
|
||||
('images/ads/Caine.gif'),
|
||||
@@ -831,22 +771,14 @@ INSERT INTO adverts (imagepath) VALUES
|
||||
('images/ads/wonka.gif'),
|
||||
('images/ads/worf.gif');
|
||||
|
||||
##############################################################################
|
||||
# Database Initialization
|
||||
##############################################################################
|
||||
|
||||
# Initialize the system globals table.
|
||||
INSERT INTO globals (version, posts_per_page, old_posts_at_top, max_search_page, max_comm_mbr_page, max_conf_mbr_page,
|
||||
fp_posts, num_audit_page, comm_create_lvl)
|
||||
VALUES ('2026030501', 20, 2, 20, 50, 50, 10, 100, 1000);
|
||||
|
||||
# Initialize the global properies table.
|
||||
INSERT INTO propglobal (ndx, data)
|
||||
VALUES (0, '');
|
||||
|
||||
# Add the 'Anonymous Honyak' user to the users table.
|
||||
# (Do 'SELECT * FROM users WHERE is_anon = 1' to retrieve the AC user details.)
|
||||
# (UID = 1, CONTACTID = 1)
|
||||
INSERT INTO users (uid, username, passhash, contactid, is_anon, verify_email, base_lvl, created)
|
||||
VALUES (1, 'Anonymous_Honyak', '', 1, 1, 1, 100, '2000-12-01 00:00:00');
|
||||
INSERT INTO userprefs (uid) VALUES (1);
|
||||
@@ -854,15 +786,11 @@ INSERT INTO propuser (uid, ndx, data) VALUES (1, 0, '');
|
||||
INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcode, country, email, owner_uid)
|
||||
VALUES (1, 'Anonymous', 'User', 'Anywhere', '', '', 'US', 'nobody@example.com', 1);
|
||||
|
||||
# Provide the default view for Anonymous Honyak. This view will be copied to all
|
||||
# new users.
|
||||
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
||||
VALUES (1, 1, 100, NULL), (1, 2, 200, NULL), (1, 3, 300, NULL);
|
||||
INSERT INTO confhotlist (uid, sequence, commid, confid)
|
||||
VALUES (1, 100, 2, 2);
|
||||
|
||||
# Add the 'Administrator' user to the users table.
|
||||
# (UID = 2, CONTACTID = 2)
|
||||
INSERT INTO users (uid, username, passhash, contactid, verify_email, base_lvl, created)
|
||||
VALUES (2, 'Administrator', '', 2, 1, 64999, '2000-12-01 00:00:00');
|
||||
INSERT INTO userprefs (uid) VALUES (2);
|
||||
@@ -870,35 +798,27 @@ INSERT INTO propuser (uid, ndx, data) VALUES (2, 0, '');
|
||||
INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcode, country, email, owner_uid)
|
||||
VALUES (2, 'System', 'Administrator', 'Anywhere', '', '', 'US', 'root@your.box.com', 2);
|
||||
|
||||
# Create the default view for Administrator.
|
||||
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
||||
VALUES (2, 1, 100, NULL), (2, 2, 200, NULL), (2, 3, 300, NULL);
|
||||
INSERT INTO confhotlist (uid, sequence, commid, confid)
|
||||
VALUES (2, 100, 2, 2);
|
||||
|
||||
# Add the administration community to the communities table.
|
||||
# (COMMID = 1, CONTACTID = 3)
|
||||
INSERT INTO communities (commid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl, join_lvl, contactid,
|
||||
host_uid, catid, hide_dir, hide_search, membersonly, is_admin, init_ftr,
|
||||
commname, language, synopsis, rules, joinkey, alias)
|
||||
VALUES (1, '2000-12-01 00:00:00', 63000, 63000, 63000, 65500, 63000, 3, 2, 15, 1, 1, 1, 1, 0,
|
||||
'Administration', 'en-US', 'Administrative Community', 'Administrators only!', '',
|
||||
'Admin');
|
||||
'Admin');
|
||||
INSERT INTO contacts (contactid, locality, country, owner_uid, owner_commid)
|
||||
VALUES (3, 'Anywhere', 'US', 2, 1);
|
||||
INSERT INTO propcomm (cid, ndx, data) VALUES (1, 0, '');
|
||||
|
||||
# Insert the desired features for the 'Administration' community.
|
||||
INSERT INTO commftrs (commid, ftr_code)
|
||||
VALUES (1, 0), (1, 1), (1, 2), (1, 3), (1, 4);
|
||||
|
||||
# Make the 'Administrator' user the host of the 'Administration' community. Also, the Administrator
|
||||
# cannot unjoin the community.
|
||||
INSERT INTO commmember (commid, uid, granted_lvl, locked)
|
||||
VALUES (1, 2, 58500, 1);
|
||||
|
||||
# Insert the "Administrative Notes" conference into the Administration community.
|
||||
# (CONFID = 1)
|
||||
INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl, nuke_lvl, change_lvl,
|
||||
delete_lvl, top_topic, name, descr)
|
||||
VALUES (1, '2000-12-01 00:00:00', 63000, 63000, 63000, 63000, 64999, 64999, 65500, 0,
|
||||
@@ -907,12 +827,8 @@ INSERT INTO commtoconf (commid, confid, sequence) VALUES (1, 1, 10);
|
||||
INSERT INTO confalias (confid, alias) VALUES (1, 'Admin_Notes');
|
||||
INSERT INTO propconf (confid, ndx, data) VALUES (1, 0, '');
|
||||
|
||||
# Make the Administrator the host-of-record of the "Administrative Notes" conference.
|
||||
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (1, 2, 52500);
|
||||
|
||||
# Add the 'Coffeehouse' community. This is the equivalent of the old CommunityWare
|
||||
# 'Universal Community.'
|
||||
# (COMMID = 2, CONTACTID = 4)
|
||||
INSERT INTO communities (commid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl, join_lvl, contactid,
|
||||
host_uid, catid, membersonly, init_ftr, commname, language, synopsis, rules, alias)
|
||||
VALUES (2, '2000-12-01 00:00:00', 100, 58000, 58000, 65500, 500, 4, 2, 0, 1, 0, 'Coffeehouse', 'en-US',
|
||||
@@ -922,22 +838,15 @@ INSERT INTO contacts (contactid, locality, country, owner_uid, owner_commid)
|
||||
VALUES (4, 'Anywhere', 'US', 2, 2);
|
||||
INSERT INTO propcomm (cid, ndx, data) VALUES (2, 0, '');
|
||||
|
||||
# Insert the desired features for Coffeehouse.
|
||||
INSERT INTO commftrs (commid, ftr_code)
|
||||
VALUES (2, 0), (2, 1), (2, 3), (2, 4);
|
||||
|
||||
# Make 'Anonymous Honyak' a member of Coffeehouse. This is important because new users will
|
||||
# have the membership list of Anonymous Honyak copied to their account on signup (but with
|
||||
# the 'member' access level).
|
||||
INSERT INTO commmember (commid, uid, granted_lvl, locked, hidden)
|
||||
VALUES (2, 1, 100, 1, 1);
|
||||
|
||||
# Make the 'Administrator' user the host of Coffeehouse.
|
||||
INSERT INTO commmember (commid, uid, granted_lvl, locked)
|
||||
VALUES (2, 2, 58500, 1);
|
||||
|
||||
# Insert the "General Discussion" conference into Coffeehouse.
|
||||
# (CONFID = 2)
|
||||
INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl, nuke_lvl, change_lvl,
|
||||
delete_lvl, top_topic, name, descr)
|
||||
VALUES (2, '2000-12-01 00:00:00', 6500, 6500, 6500, 52500, 52500, 52500, 58000, 0, 'General Discussion',
|
||||
@@ -946,11 +855,8 @@ INSERT INTO commtoconf (commid, confid, sequence) VALUES (2, 2, 10);
|
||||
INSERT INTO confalias (confid, alias) VALUES (2, 'General');
|
||||
INSERT INTO propconf (confid, ndx, data) VALUES (2, 0, '');
|
||||
|
||||
# Make the Administrator the host-of-record of the "General Discussion" conference.
|
||||
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (2, 2, 52500);
|
||||
|
||||
# Insert the "Test Postings" conference into Coffeehouse.
|
||||
# (CONFID = 3)
|
||||
INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl, nuke_lvl, change_lvl,
|
||||
delete_lvl, top_topic, name, descr)
|
||||
VALUES (3, '2000-12-01 00:00:00', 6500, 6500, 6500, 52500, 52500, 52500, 58000, 0, 'Test Postings',
|
||||
@@ -959,5 +865,4 @@ INSERT INTO commtoconf (commid, confid, sequence) VALUES (2, 3, 20);
|
||||
INSERT INTO confalias (confid, alias) VALUES (3, 'Test');
|
||||
INSERT INTO propconf (confid, ndx, data) VALUES (3, 0, '');
|
||||
|
||||
# Make the Administrator the host-of-record of the "Test Postings" conference.
|
||||
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (3, 2, 52500);
|
||||
@@ -0,0 +1,2 @@
|
||||
Migration scripts for MySQL go in this directory. Name them as YYYYMMDDNN.sql, where YYYYMMDD is the
|
||||
current date and NN is a two-digit sequence number beginning at 01.
|
||||
Reference in New Issue
Block a user