1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-23 07:09:43 +02:00

restructure directories

This commit is contained in:
Elliott Stoneham 2016-07-20 15:58:37 +01:00
parent 7e4ed6545b
commit a2ce777762
159 changed files with 320 additions and 323 deletions

150
core/database/check.go Normal file
View file

@ -0,0 +1,150 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package database
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/documize/community/core/web"
"github.com/documize/community/core/log"
"github.com/documize/community/core/utility"
"github.com/jmoiron/sqlx"
)
var dbCheckOK bool // default false
// dbPtr is a pointer to the central connection to the database, used by all database requests.
var dbPtr **sqlx.DB
// Check that the database is configured correctly and that all the required tables exist.
// It must be the first function called in this package.
func Check(Db *sqlx.DB, connectionString string) bool {
dbPtr = &Db
log.Info("Running database checks, this may take a while...")
csBits := strings.Split(connectionString, "/")
if len(csBits) > 1 {
web.SiteInfo.DBname = strings.Split(csBits[len(csBits)-1], "?")[0]
}
rows, err := Db.Query("SELECT VERSION() AS version, @@character_set_database AS charset, @@collation_database AS collation;")
if err != nil {
log.Error("Can't get MySQL configuration", err)
web.SiteInfo.Issue = "Can't get MySQL configuration: " + err.Error()
web.SiteMode = web.SiteModeBadDB
return false
}
defer utility.Close(rows)
var version, charset, collation string
if rows.Next() {
err = rows.Scan(&version, &charset, &collation)
}
if err == nil {
err = rows.Err() // get any error encountered during iteration
}
if err != nil {
log.Error("no MySQL configuration returned", err)
web.SiteInfo.Issue = "no MySQL configuration return issue: " + err.Error()
web.SiteMode = web.SiteModeBadDB
return false
}
// See http://dba.stackexchange.com/questions/63763/is-there-any-difference-between-these-two-version-of-mysql-5-1-73-community-lo
version = strings.Replace(version, "-log", "", 1)
version = strings.Replace(version, "-debug", "", 1)
version = strings.Replace(version, "-demo", "", 1)
{ // check minimum MySQL version as we need JSON column type. 5.7.10
vParts := strings.Split(version, ".")
if len(vParts) < 3 {
log.Error("MySQL version not of the form a.b.c:", errors.New(version))
web.SiteInfo.Issue = "MySQL version in the wrong format: " + version
web.SiteMode = web.SiteModeBadDB
return false
}
verInts := []int{5, 7, 10} // Minimum MySQL version
for k, v := range verInts {
i, err := strconv.Atoi(vParts[k])
if err != nil {
log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not an integer:", err)
web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not an integer: " + err.Error()
web.SiteMode = web.SiteModeBadDB
return false
}
if i < v {
want := fmt.Sprintf("%d.%d.%d", verInts[0], verInts[1], verInts[2])
log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not high enough, need at least version "+want, errors.New("bad MySQL version"))
web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not high enough, need at least version " + want
web.SiteMode = web.SiteModeBadDB
return false
}
}
}
{ // check the MySQL character set and collation
if charset != "utf8" {
log.Error("MySQL character set not utf8:", errors.New(charset))
web.SiteInfo.Issue = "MySQL character set not utf8: " + charset
web.SiteMode = web.SiteModeBadDB
return false
}
if !strings.HasPrefix(collation, "utf8") {
log.Error("MySQL collation sequence not utf8...:", errors.New(collation))
web.SiteInfo.Issue = "MySQL collation sequence not utf8...: " + collation
web.SiteMode = web.SiteModeBadDB
return false
}
}
{ // if there are no rows in the database, enter set-up mode
var flds []string
if err := Db.Select(&flds,
`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '`+web.SiteInfo.DBname+
`' and TABLE_TYPE='BASE TABLE'`); err != nil {
log.Error("Can't get MySQL number of tables", err)
web.SiteInfo.Issue = "Can't get MySQL number of tables: " + err.Error()
web.SiteMode = web.SiteModeBadDB
return false
}
if strings.TrimSpace(flds[0]) == "0" {
log.Error("Entering database set-up mode because the database is empty.", errors.New("no tables"))
web.SiteMode = web.SiteModeSetup
return false
}
}
{ // check all the required tables exist
var tables = []string{`account`,
`attachment`, `audit`, `document`,
`label`, `labelrole`, `organization`,
`page`, `revision`, `search`, `user`}
for _, table := range tables {
var dummy []string
if err := Db.Select(&dummy, "SELECT 1 FROM "+table+" LIMIT 1;"); err != nil {
log.Error("Entering bad database mode because: SELECT 1 FROM "+table+" LIMIT 1;", err)
web.SiteInfo.Issue = "MySQL database is not empty, but does not contain table: " + table
web.SiteMode = web.SiteModeBadDB
return false
}
}
}
web.SiteMode = web.SiteModeNormal // actually no need to do this (as already ""), this for documentation
web.SiteInfo.DBname = "" // do not give this info when not in set-up mode
dbCheckOK = true
return true
}

204
core/database/create.go Normal file
View file

@ -0,0 +1,204 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package database
import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/documize/community/core/api/util"
"github.com/documize/community/core/web"
"github.com/documize/community/core/log"
"github.com/documize/community/core/utility"
)
// runSQL creates a transaction per call
func runSQL(sql string) (id uint64, err error) {
if strings.TrimSpace(sql) == "" {
return 0, nil
}
tx, err := (*dbPtr).Beginx()
if err != nil {
log.Error("runSql - failed to get transaction", err)
return
}
result, err := tx.Exec(sql)
if err != nil {
log.IfErr(tx.Rollback())
log.Error("runSql - unable to run sql", err)
return
}
if err = tx.Commit(); err != nil {
log.Error("runSql - unable to commit sql", err)
return
}
tempID, _ := result.LastInsertId()
id = uint64(tempID)
return
}
// Create the tables in a blank database
func Create(w http.ResponseWriter, r *http.Request) {
defer func() {
target := "/setup"
status := http.StatusBadRequest
if web.SiteMode == web.SiteModeNormal {
target = "/"
status = http.StatusOK
}
req, err := http.NewRequest("GET", target, nil)
if err != nil {
log.Error("database.Create()'s error in defer ", err)
}
http.Redirect(w, req, target, status)
}()
err := r.ParseForm()
if err != nil {
log.Error("database.Create()'s r.ParseForm()", err)
return
}
dbname := r.Form.Get("dbname")
dbhash := r.Form.Get("dbhash")
if dbname != web.SiteInfo.DBname || dbhash != web.SiteInfo.DBhash {
log.Error("database.Create()'s security credentials error ", errors.New("bad db name or validation code"))
return
}
details := onboardRequest{
URL: "",
Company: r.Form.Get("title"),
CompanyLong: r.Form.Get("title"),
Message: r.Form.Get("message"),
Email: r.Form.Get("email"),
Password: r.Form.Get("password"),
Firstname: r.Form.Get("firstname"),
Lastname: r.Form.Get("lastname"),
Revised: time.Now(),
}
if details.Company == "" ||
details.CompanyLong == "" ||
details.Message == "" ||
details.Email == "" ||
details.Password == "" ||
details.Firstname == "" ||
details.Lastname == "" {
log.Error("database.Create() error ",
errors.New("required field in database set-up form blank"))
return
}
if err = Migrate(false /* no tables exist yet */); err != nil {
log.Error("database.Create()", err)
return
}
err = setupAccount(details, util.GenerateSalt())
if err != nil {
log.Error("database.Create()", err)
return
}
web.SiteMode = web.SiteModeNormal
}
// The result of completing the onboarding process.
type onboardRequest struct {
URL string
Company string
CompanyLong string
Message string
Email string
Password string
Firstname string
Lastname string
Revised time.Time
}
// setupAccount prepares the database for a newly onboard customer.
// Once done, they can then login and use Documize.
func setupAccount(completion onboardRequest, serial string) (err error) {
//accountTitle := "This is where you will find documentation for your all projects. You can customize this message from the settings screen."
salt := util.GenerateSalt()
password := util.GeneratePassword(completion.Password, salt)
// Allocate organization to the user.
orgID := util.UniqueID()
sql := fmt.Sprintf("insert into organization (refid, company, title, message, domain, email, serial) values (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")",
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial)
_, err = runSQL(sql)
if err != nil {
log.Error("Failed to insert into organization", err)
return
}
userID := util.UniqueID()
sql = fmt.Sprintf("insert into user (refid, firstname, lastname, email, initials, salt, password) values (\"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")",
userID, completion.Firstname, completion.Lastname, completion.Email, utility.MakeInitials(completion.Firstname, completion.Lastname), salt, password)
_, err = runSQL(sql)
if err != nil {
log.Error("Failed with error", err)
return err
}
// Link user to organization.
accountID := util.UniqueID()
sql = fmt.Sprintf("insert into account (refid, userid, orgid, admin, editor) values (\"%s\", \"%s\", \"%s\",1, 1)", accountID, userID, orgID)
_, err = runSQL(sql)
if err != nil {
log.Error("Failed with error", err)
return err
}
// Set up default labels for main collection.
labelID := util.UniqueID()
sql = fmt.Sprintf("insert into label (refid, orgid, label, type, userid) values (\"%s\", \"%s\", \"My Project\", 2, \"%s\")", labelID, orgID, userID)
_, err = runSQL(sql)
if err != nil {
log.Error("insert into label failed", err)
}
labelRoleID := util.UniqueID()
sql = fmt.Sprintf("insert into labelrole (refid, labelid, orgid, userid, canview, canedit) values (\"%s\", \"%s\", \"%s\", \"%s\", 1, 1)", labelRoleID, labelID, orgID, userID)
_, err = runSQL(sql)
if err != nil {
log.Error("insert into labelrole failed", err)
}
return
}

View file

@ -0,0 +1,13 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package database

195
core/database/migrate.go Normal file
View file

@ -0,0 +1,195 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
package database
import (
"bytes"
"database/sql"
"regexp"
"sort"
"strings"
"github.com/jmoiron/sqlx"
"github.com/documize/community/core/web"
"github.com/documize/community/core/log"
"github.com/documize/community/core/utility"
)
const migrationsDir = "bindata/scripts"
// migrationsT holds a list of migration sql files to run.
type migrationsT []string
// migrations returns a list of the migrations to update the database as required for this version of the code.
func migrations(lastMigration string) (migrationsT, error) {
lastMigration = strings.TrimPrefix(strings.TrimSuffix(lastMigration, `"`), `"`)
//fmt.Println(`DEBUG Migrations("`+lastMigration+`")`)
files, err := web.AssetDir(migrationsDir)
if err != nil {
return nil, err
}
sort.Strings(files)
ret := make(migrationsT, 0, len(files))
hadLast := false
if len(lastMigration) == 0 {
hadLast = true
}
for _, v := range files {
if v == lastMigration {
hadLast = true
} else {
if hadLast {
ret = append(ret, v)
}
}
}
//fmt.Println(`DEBUG Migrations("`+lastMigration+`")=`,ret)
return ret, nil
}
// migrate the database as required, by applying the migrations.
func (m migrationsT) migrate(tx *sqlx.Tx) error {
for _, v := range m {
log.Info("Processing migration file: " + v)
buf, err := web.Asset(migrationsDir + "/" + v)
if err != nil {
return err
}
//fmt.Println("DEBUG database.Migrate() ", v, ":\n", string(buf)) // TODO actually run the SQL
err = processSQLfile(tx, buf)
if err != nil {
return err
}
json := `{"database":"` + v + `"}`
sql := "INSERT INTO `config` (`key`,`config`) " +
"VALUES ('META','" + json +
"') ON DUPLICATE KEY UPDATE `config`='" + json + "';"
_, err = tx.Exec(sql)
if err != nil {
return err
}
//fmt.Println("DEBUG insert 10s wait for testing")
//time.Sleep(10 * time.Second)
}
return nil
}
func migrateEnd(tx *sqlx.Tx, err error) error {
if tx != nil {
_, ulerr := tx.Exec("UNLOCK TABLES;")
log.IfErr(ulerr)
if err == nil {
log.IfErr(tx.Commit())
log.Info("Database checks: completed")
return nil
}
log.IfErr(tx.Rollback())
}
log.Error("Database checks: failed: ", err)
return err
}
// Migrate the database as required, consolidated action.
func Migrate(ConfigTableExists bool) error {
lastMigration := ""
tx, err := (*dbPtr).Beginx()
if err != nil {
return migrateEnd(tx, err)
}
if ConfigTableExists {
_, err = tx.Exec("LOCK TABLE `config` WRITE;")
if err != nil {
return migrateEnd(tx, err)
}
log.Info("Database checks: lock taken")
var stmt *sql.Stmt
stmt, err = tx.Prepare("SELECT JSON_EXTRACT(`config`,'$.database') FROM `config` WHERE `key` = 'META';")
if err == nil {
defer utility.Close(stmt)
var item = make([]uint8, 0)
row := stmt.QueryRow()
err = row.Scan(&item)
if err != nil {
return migrateEnd(tx, err)
}
if len(item) > 1 {
q := []byte(`"`)
lastMigration = string(bytes.TrimPrefix(bytes.TrimSuffix(item, q), q))
}
}
log.Info("Database checks: last previously applied file was " + lastMigration)
}
mig, err := migrations(lastMigration)
if err != nil {
return migrateEnd(tx, err)
}
if len(mig) == 0 {
log.Info("Database checks: no updates to perform")
return migrateEnd(tx, nil) // no migrations to perform
}
log.Info("Database checks: will execute the following update files: " + strings.Join([]string(mig), ", "))
return migrateEnd(tx, mig.migrate(tx))
}
func processSQLfile(tx *sqlx.Tx, buf []byte) error {
stmts := getStatements(buf)
for _, stmt := range stmts {
_, err := tx.Exec(stmt)
if err != nil {
return err
}
}
return nil
}
// getStatement strips out the comments and returns all the individual SQL commands (apart from "USE") as a []string.
func getStatements(bytes []byte) []string {
/* Strip comments of the form '-- comment' or like this one */
stripped := regexp.MustCompile("(?s)--.*?\n|/\\*.*?\\*/").ReplaceAll(bytes, []byte("\n"))
sqls := strings.Split(string(stripped), ";")
ret := make([]string, 0, len(sqls))
for _, v := range sqls {
trimmed := strings.TrimSpace(v)
if len(trimmed) > 0 &&
!strings.HasPrefix(strings.ToUpper(trimmed), "USE ") { // make sure we don't USE the wrong database
ret = append(ret, trimmed+";")
}
}
return ret
}

View file

@ -0,0 +1,280 @@
-- SQL to set up the Documize database
DROP TABLE IF EXISTS `user`;
CREATE TABLE IF NOT EXISTS `user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`firstname` NVARCHAR(500) NOT NULL,
`lastname` NVARCHAR(500) NOT NULL,
`email` NVARCHAR(250) NOT NULL UNIQUE,
`initials` NVARCHAR(10) NOT NULL DEFAULT "",
`password` NVARCHAR(500) NOT NULL DEFAULT "",
`salt` NVARCHAR(100) NOT NULL DEFAULT "",
`reset` NVARCHAR(100) NOT NULL DEFAULT "",
`active` BOOL NOT NULL DEFAULT 1,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_user_id` (`id` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `audit`;
CREATE TABLE IF NOT EXISTS `audit` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL DEFAULT "" COLLATE utf8_bin,
`pageid` CHAR(16) NOT NULL DEFAULT "" COLLATE utf8_bin,
`action` NVARCHAR(200) NOT NULL DEFAULT "",
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `idx_audit_id` (`id` ASC),
INDEX `idx_orgid_url` (`orgid`))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `organization`;
CREATE TABLE IF NOT EXISTS `organization` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`company` NVARCHAR(500) NOT NULL,
`title` NVARCHAR(500) NOT NULL,
`message` NVARCHAR(500) NOT NULL,
`url` NVARCHAR(200) NOT NULL DEFAULT "",
`domain` NVARCHAR(200) NOT NULL DEFAULT "",
`email` NVARCHAR(500) NOT NULL DEFAULT "",
`allowanonymousaccess` BOOL NOT NULL DEFAULT 0,
`verified` BOOL NOT NULL DEFAULT 0,
`serial` NVARCHAR(50) NOT NULL DEFAULT "",
`active` BOOL NOT NULL DEFAULT 1,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_organization_id` (`id` ASC),
INDEX `idx_organization_url` (`url`),
INDEX `idx_organization_domain` (`domain`))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `account`;
CREATE TABLE IF NOT EXISTS `account` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`editor` BOOL NOT NULL DEFAULT 0,
`admin` BOOL NOT NULL DEFAULT 0,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_account_id` (`id` ASC),
INDEX `idx_account_userid` (`userid` ASC),
INDEX `idx_account_orgid` (`orgid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `label`;
CREATE TABLE IF NOT EXISTS `label` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`label` NVARCHAR(255) NOT NULL,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL DEFAULT "" COLLATE utf8_bin,
`type` INT NOT NULL DEFAULT 1,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_label_id` (`id` ASC),
INDEX `idx_label_userid` (`userid` ASC),
INDEX `idx_label_orgid` (`orgid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `labelrole`;
CREATE TABLE IF NOT EXISTS `labelrole` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`labelid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`canview` BOOL NOT NULL DEFAULT 0,
`canedit` BOOL NOT NULL DEFAULT 0,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_labelrole_id` (`id` ASC),
INDEX `idx_labelrole_userid` (`userid` ASC),
INDEX `idx_labelrole_labelid` (`labelid` ASC),
INDEX `idx_labelrole_orgid` (`orgid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `document`;
CREATE TABLE IF NOT EXISTS `document` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`labelid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`job` CHAR(36) NOT NULL,
`location` NVARCHAR(2000) NOT NULL,
`title` NVARCHAR(2000) NOT NULL,
`excerpt` NVARCHAR(2000) NOT NULL,
`slug` NVARCHAR(2000) NOT NULL,
`tags` NVARCHAR(1000) NOT NULL DEFAULT '',
`template` BOOL NOT NULL DEFAULT 0,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_document_id` (`id` ASC),
INDEX `idx_document_orgid` (`orgid` ASC),
INDEX `idx_document_labelid` (`labelid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `page`;
CREATE TABLE IF NOT EXISTS `page` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
`contenttype` CHAR(20) NOT NULL DEFAULT 'wysiwyg',
`level` INT UNSIGNED NOT NULL,
`sequence` DOUBLE NOT NULL,
`title` NVARCHAR(2000) NOT NULL,
`body` LONGTEXT,
`revisions` INT UNSIGNED NOT NULL,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_page_id` (`id` ASC),
INDEX `idx_page_orgid` (`orgid` ASC),
INDEX `idx_page_documentid` (`documentid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `pagemeta`;
CREATE TABLE IF NOT EXISTS `pagemeta` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`pageid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
`rawbody` LONGBLOB,
`config` JSON,
`externalsource` BOOL DEFAULT 0,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_pageid PRIMARY KEY (pageid),
UNIQUE INDEX `idx_pagemeta_id` (`id` ASC),
INDEX `idx_pagemeta_pageid` (`pageid` ASC),
INDEX `idx_pagemeta_orgid` (`orgid` ASC),
INDEX `idx_pagemeta_documentid` (`documentid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `attachment`;
CREATE TABLE IF NOT EXISTS `attachment` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
`job` CHAR(36) NOT NULL,
`fileid` CHAR(10) NOT NULL,
`filename` NVARCHAR(255) NOT NULL,
`data` LONGBLOB,
`extension` CHAR(6) NOT NULL,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_attachment_id` (`id` ASC),
INDEX `idx_attachment_orgid` (`orgid` ASC),
INDEX `idx_attachment_documentid` (`documentid` ASC),
INDEX `idx_attachment_job_and_fileid` (`job`,`fileid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `search`;
CREATE TABLE IF NOT EXISTS `search` (
`id` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
`level` INT UNSIGNED NOT NULL,
`sequence` DOUBLE NOT NULL,
`documenttitle` NVARCHAR(2000) NOT NULL,
`pagetitle` NVARCHAR(2000) NOT NULL,
`slug` NVARCHAR(2000) NOT NULL,
`body` LONGTEXT,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `idx_search_id` (`id` ASC),
INDEX `idx_search_orgid` (`orgid` ASC),
INDEX `idx_search_documentid` (`documentid` ASC),
INDEX `idx_search_sequence` (`sequence` ASC),
FULLTEXT(`pagetitle`,`body`))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = MyISAM;
DROP TABLE IF EXISTS `revision`;
CREATE TABLE IF NOT EXISTS `revision` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
`ownerid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
`pageid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`contenttype` CHAR(20) NOT NULL DEFAULT 'wysiwyg',
`title` NVARCHAR(2000) NOT NULL,
`body` LONGTEXT,
`rawbody` LONGBLOB,
`config` JSON,
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_refid PRIMARY KEY (refid),
UNIQUE INDEX `idx_revision_id` (`id` ASC),
INDEX `idx_revision_orgid` (`orgid` ASC),
INDEX `idx_revision_documentid` (`documentid` ASC),
INDEX `idx_revision_pageid` (`pageid` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;
DROP TABLE IF EXISTS `config`;
CREATE TABLE IF NOT EXISTS `config` (
`key` CHAR(255) NOT NULL,
`config` JSON,
UNIQUE INDEX `idx_config_area` (`key` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO `config` VALUES ('SMTP','{\"userid\": \"\",\"password\": \"\",\"host\": \"\",\"port\": \"\",\"sender\": \"\"}');
INSERT INTO `config` VALUES ('FILEPLUGINS',
'[{\"Comment\": \"Disable (or not) built-in html import (NOTE: no Plugin name)\",\"Disabled\": false,\"API\": \"Convert\",\"Actions\": [\"htm\",\"html\"]},{\"Comment\": \"Disable (or not) built-in Documize API import used from SDK (NOTE: no Plugin name)\",\"Disabled\": false,\"API\": \"Convert\",\"Actions\": [\"documizeapi\"]}]');
INSERT INTO `config` VALUES ('LICENSE','{\"token\": \"\",\"endpoint\": \"https://api.documize.com\"}');
INSERT INTO `config` VALUES ('META','{\"database\": \"db_00000.sql\"}');
INSERT INTO `config` VALUES ('SECTION-GITHUB', '{\"clientID\": \"\", \"clientSecret\": \"\", \"authorizationCallbackURL\": \"https://localhost:5001/api/public/validate?section=github\"}');
INSERT INTO `config` VALUES ('SECTION-TRELLO','{\"appKey\": \"\"}');
DROP TABLE IF EXISTS `userconfig`;
CREATE TABLE IF NOT EXISTS `userconfig` (
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
`key` CHAR(255) NOT NULL,
`config` JSON,
UNIQUE INDEX `idx_userconfig_orguserkey` (`orgid`, `userid`, `key` ASC))
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
ENGINE = InnoDB;

View file

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,300' rel='stylesheet' type='text/css'>
<title>Documize - Issue using the given MySQL database</title>
<style>
html {
-webkit-font-smoothing: antialiased;
}
body {
font-family: 'Open Sans', sans-serif;
background-color: #1b75bb;
font-size: 16px;
color: #ffffff;
padding-top: 50px;
}
.container {
max-width: 1200px;
margin: 0 auto;
text-align: center;
}
.logo {
margin: 0 15px;
}
.content {
margin: 0 15px;
}
.content > div {
margin: 50px 0;
}
.content h1 {
font-size: 24px;
font-weight: 400;
text-transform: uppercase;
margin: 0 0 30px;
}
.content p {
font-size: 18px;
line-height: 28px;
margin: 30px 0 0 0;
}
.content .image {
text-align: center;
}
.clearfix {
overflow: auto;
zoom: 1;
}
.btn-main {
border: 1px solid #ffffff;
padding: 12px 20px;
border-radius: 5px;
margin-left: 25px;
}
@media (min-width: 768px) {
body {
margin-top: 100px;
}
.container {
text-align: left;
}
.content {
margin: 50px 15px 0;
}
.content > div {
width: 50%;
float: left;
margin: 0;
}
.content h1 {
font-size: 28px;
line-height: 72px;
}
.content .image {
float: right;
}
.content .text {
max-width: 430px;
}
}
</style>
</head>
<body>
<div id="wrapper">
<div class="container">
<div class="logo">
<img src="/assets/img/setup/logo.png" alt="Documize">
</div>
<div class="content clearfix">
<div class="image">
<img style="-webkit-user-select: none;" src="/assets/img/setup/error.png" width="184" height="159" alt="Database error">
</div>
<div class="text">
<h1>Database Error</h1>
<p>There seems to be a problem with the Documize database: <strong>{{.DBname}}</strong></p>
<p><em>{{.Issue}}</em></p>
</div>
</div>
</div>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long