~evanj/cms

4aa45cc85249c542c4d80aed47e25c86145bcc3c — Evan M Jones 8 months ago f5488e0
Feat(mysql): Moving to mysql. Getting ready for alpha release (just for
me!).
7 files changed, 130 insertions(+), 58 deletions(-)

M cms.go
M go.mod
M go.sum
M internal/c/user/user.go
M internal/s/db/content.go
M internal/s/db/db.go
M internal/s/db/space.go
M cms.go => cms.go +1 -1
@@ 107,13 107,13 @@ func init() {
		user: user.New(
			log.New(w, "[cms:user] ", 0),
			db,
			os.Getenv("SIGNUP_ENABLE") == "true",
		),
		ping: ping.New(
			log.New(w, "[cms:ping] ", 0),
			db,
		),
	}

}

func main() {

M go.mod => go.mod +1 -1
@@ 5,5 5,5 @@ go 1.12
require (
	git.sr.ht/~evanj/security v0.0.0-20200228044358-9b9bc6682997
	github.com/go-playground/assert/v2 v2.0.1
	github.com/mattn/go-sqlite3 v2.0.3+incompatible
	github.com/go-sql-driver/mysql v1.5.0
)

M go.sum => go.sum +2 -2
@@ 6,8 6,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=

M internal/c/user/user.go => internal/c/user/user.go +10 -3
@@ 17,8 17,9 @@ var (

type User struct {
	*c.Controller
	log *log.Logger
	db  dber
	log           *log.Logger
	db            dber
	signupEnabled bool
}

type dber interface {


@@ 28,11 29,12 @@ type dber interface {
	SpacesPerUser(user user.User, page int) ([]space.Space, error)
}

func New(log *log.Logger, db dber) *User {
func New(log *log.Logger, db dber, signupEnabled bool) *User {
	return &User{
		c.New(log, db),
		log,
		db,
		signupEnabled,
	}
}



@@ 56,6 58,11 @@ func (l *User) login(w http.ResponseWriter, r *http.Request) {
}

func (l *User) signup(w http.ResponseWriter, r *http.Request) {
	if !l.signupEnabled {
		l.Error(w, r, http.StatusForbidden, "signups are forbidden at this time")
		return
	}

	username := r.FormValue("username")
	password := r.FormValue("password")
	verify := r.FormValue("verify")

M internal/s/db/content.go => internal/s/db/content.go +1 -1
@@ 183,7 183,7 @@ const (
				OR cms_valuetype.VALUE = 'InputMarkdown'
			)

		)
		) AS A

		ORDER BY ORDER_ID ASC;
	`

M internal/s/db/db.go => internal/s/db/db.go +112 -47
@@ 3,10 3,11 @@ package db
import (
	"database/sql"
	"log"
	"strings"

	"git.sr.ht/~evanj/cms/internal/m/valuetype"
	"git.sr.ht/~evanj/security"
	_ "github.com/mattn/go-sqlite3"
	_ "github.com/go-sql-driver/mysql"
)

const (


@@ 41,124 42,188 @@ func New(log *log.Logger, typ, creds string, sec securer) (*DB, error) {
	return db, nil
}

func (db *DB) EnsureSetup() error {
func (db *DB) CreateTables() error {
	var _ interface{}
	var err error

	// user
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_user (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT UNIQUE NOT NULL,
			HASH TEXT NOT NULL
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			NAME varchar(256) UNIQUE NOT NULL,
			HASH varchar(256) NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// space
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_space (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT NOT NULL,
			DESC TEXT NOT NULL
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			NAME varchar(256) NOT NULL,
			DESCRIPTION varchar(256) NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// user to space
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_user_to_space (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			USER_ID INTEGER NOT NULL,
			SPACE_ID INTEGER NOT NULL,
			FOREIGN KEY(USER_ID) REFERENCES cms_user(ID),
			FOREIGN KEY(SPACE_ID) REFERENCES cms_space(ID)
		);
	`)
	if err != nil {
		return err
	}

	// contenttype
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_contenttype (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT NOT NULL,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			NAME varchar(256) NOT NULL,
			SPACE_ID INTEGER NOT NULL,
			CONSTRAINT FG FOREIGN KEY(SPACE_ID) REFERENCES cms_space(ID),
			CONSTRAINT UNIQUEPERCONN UNIQUE(SPACE_ID, NAME)
		);
	`)
	if err != nil {
		return err
	}

	// valuetype
	// This will never be created by users.
	_, err = db.Exec(`
		CREATE TABLE cms_valuetype (
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			VALUE varchar(256) UNIQUE NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// contenttype to valuetype
	// TODO: Make name + contenttype_id unique.
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_contenttype_to_valuetype (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT NOT NULL,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			NAME varchar(256) NOT NULL,
			CONTENTTYPE_ID INTEGER NOT NULL,
			VALUETYPE_ID INTEGER NOT NULL,
			FOREIGN KEY(CONTENTTYPE_ID) REFERENCES cms_contenttype(ID)
			FOREIGN KEY(CONTENTTYPE_ID) REFERENCES cms_contenttype(ID),
			FOREIGN KEY(VALUETYPE_ID) REFERENCES cms_valuetype(ID)
		);
	`)

	// valuetype
	// This will never be created by users.
	_, _ = db.Exec(`
		CREATE TABLE cms_valuetype (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			VALUE TEXT UNIQUE NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// content
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_content (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			CONTENTTYPE_ID INTEGER NOT NULL,
			FOREIGN KEY(CONTENTTYPE_ID) REFERENCES cms_contenttype(ID)
		);
	`)
	if err != nil {
		return err
	}

	// content_to_value
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_value (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			CONTENT_ID INTEGER NOT NULL,
			CONTENTTYPE_TO_VALUETYPE_ID INTEGER NOT NULL,
			VALUE_ID INTEGER NOT NULL, -- Should be a foreign key but impossible to make it from three tables.
			FOREIGN KEY(CONTENT_ID) REFERENCES cms_content(ID)
			FOREIGN KEY(CONTENT_ID) REFERENCES cms_content(ID),
			FOREIGN KEY(CONTENTTYPE_TO_VALUETYPE_ID) REFERENCES cms_contenttype_to_valuetype(ID)
		);
	`)
	if err != nil {
		return err
	}

	// value StringSmall, File
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_value_string_small ( 
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			VALUE VARCHAR(256) NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// value StringBig, InputHTML, InputMarkdown
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_value_string_big (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			VALUE TEXT NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// value Date
	_, _ = db.Exec(`
	_, err = db.Exec(`
		CREATE TABLE cms_value_date (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			VALUE DATETIME NOT NULL
			ID INTEGER PRIMARY KEY AUTO_INCREMENT,
			VALUE DATE NOT NULL
		);
	`)
	if err != nil {
		return err
	}

	// Only valuetypes cms supports.
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.StringSmall)
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.StringBig)
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.InputHTML)
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.InputMarkdown)
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.File)
	_, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.Date)
	// _, _ = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.Reference)
	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.StringSmall)
	if err != nil {
		return err
	}

	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.StringBig)
	if err != nil {
		return err
	}

	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.InputHTML)
	if err != nil {
		return err
	}

	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.InputMarkdown)
	if err != nil {
		return err
	}

	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.File)
	if err != nil {
		return err
	}

	_, err = db.Exec(`INSERT INTO cms_valuetype (VALUE) values (?);`, valuetype.Date)
	if err != nil {
		return err
	}

	return nil
}

func (db *DB) EnsureSetup() error {
	err := db.CreateTables()
	if strings.Contains(err.Error(), "Table ") && strings.Contains(err.Error(), "already exists") {
		err = nil
	}
	return err
}

M internal/s/db/space.go => internal/s/db/space.go +3 -3
@@ 15,12 15,12 @@ type Space struct {
}

var (
	queryCreateNewSpace       = `INSERT INTO cms_space (NAME, DESC) VALUES (?, ?);`
	queryFindSpaceByID        = `SELECT ID, NAME, DESC FROM cms_space WHERE ID = ?;`
	queryCreateNewSpace       = `INSERT INTO cms_space (NAME, DESCRIPTION) VALUES (?, ?);`
	queryFindSpaceByID        = `SELECT ID, NAME, DESCRIPTION FROM cms_space WHERE ID = ?;`
	queryDeleteSpaceByID      = `DELETE FROM cms_space WHERE ID = ?;`
	queryCreateNewUserToSpace = `INSERT INTO cms_user_to_space (USER_ID, SPACE_ID) VALUES (?, ?);`
	queryFindUserToSpace      = `SELECT SPACE_ID FROM cms_user_to_space WHERE USER_ID = ? AND SPACE_ID = ?;`
	queryFindSpacesByUser     = `SELECT DISTINCT cms_space.ID, NAME, DESC FROM cms_space JOIN cms_user_to_space ON cms_space.ID = cms_user_to_space.SPACE_ID WHERE USER_ID = ? LIMIT ? OFFSET ?;`
	queryFindSpacesByUser     = `SELECT DISTINCT cms_space.ID, NAME, DESCRIPTION FROM cms_space JOIN cms_user_to_space ON cms_space.ID = cms_user_to_space.SPACE_ID WHERE USER_ID = ? LIMIT ? OFFSET ?;`
)

func (db *DB) SpaceNew(user user.User, name, desc string) (space.Space, error) {