2017-09-03 04:50:31 +00:00
/ *
*
* Gosora MySQL Interface
2019-02-23 06:55:34 +00:00
* Copyright Azareal 2017 - 2020
2017-09-03 04:50:31 +00:00
*
* /
2017-10-14 07:39:22 +00:00
package install
2017-07-12 11:05:18 +00:00
import (
"bytes"
2017-09-03 04:50:31 +00:00
"database/sql"
"fmt"
2017-07-12 11:05:18 +00:00
"io/ioutil"
"path/filepath"
2017-09-03 04:50:31 +00:00
"strconv"
"strings"
2017-08-13 11:22:34 +00:00
2018-10-27 03:21:02 +00:00
"github.com/Azareal/Gosora/query_gen"
2017-07-12 11:05:18 +00:00
_ "github.com/go-sql-driver/mysql"
)
2017-09-03 04:50:31 +00:00
//var dbCollation string = "utf8mb4_general_ci"
2017-07-12 11:05:18 +00:00
2017-10-14 07:39:22 +00:00
func init ( ) {
adapters [ "mysql" ] = & MysqlInstaller { dbHost : "" }
2017-07-12 11:05:18 +00:00
}
2017-10-14 07:39:22 +00:00
type MysqlInstaller struct {
db * sql . DB
dbHost string
dbUsername string
dbPassword string
dbName string
dbPort string
}
func ( ins * MysqlInstaller ) SetConfig ( dbHost string , dbUsername string , dbPassword string , dbName string , dbPort string ) {
ins . dbHost = dbHost
ins . dbUsername = dbUsername
ins . dbPassword = dbPassword
ins . dbName = dbName
ins . dbPort = dbPort
}
func ( ins * MysqlInstaller ) Name ( ) string {
return "mysql"
}
func ( ins * MysqlInstaller ) DefaultPort ( ) string {
return "3306"
}
2017-11-13 05:22:37 +00:00
func ( ins * MysqlInstaller ) dbExists ( dbName string ) ( bool , error ) {
var waste string
err := ins . db . QueryRow ( "SHOW DATABASES LIKE '" + dbName + "'" ) . Scan ( & waste )
if err != nil && err != sql . ErrNoRows {
return false , err
} else if err == sql . ErrNoRows {
return false , nil
}
return true , nil
}
2017-10-14 07:39:22 +00:00
func ( ins * MysqlInstaller ) InitDatabase ( ) ( err error ) {
_dbPassword := ins . dbPassword
2017-09-03 04:50:31 +00:00
if _dbPassword != "" {
_dbPassword = ":" + _dbPassword
2017-07-12 11:05:18 +00:00
}
2017-10-14 07:39:22 +00:00
db , err := sql . Open ( "mysql" , ins . dbUsername + _dbPassword + "@tcp(" + ins . dbHost + ":" + ins . dbPort + ")/" )
2017-07-12 11:05:18 +00:00
if err != nil {
return err
}
// Make sure that the connection is alive..
err = db . Ping ( )
if err != nil {
return err
}
fmt . Println ( "Successfully connected to the database" )
2017-08-13 11:22:34 +00:00
2017-11-13 05:22:37 +00:00
ins . db = db
ok , err := ins . dbExists ( ins . dbName )
if err != nil {
2017-07-12 11:05:18 +00:00
return err
}
2017-11-13 05:22:37 +00:00
if ! ok {
2017-07-12 11:05:18 +00:00
fmt . Println ( "Unable to find the database. Attempting to create it" )
2017-10-14 07:39:22 +00:00
_ , err = db . Exec ( "CREATE DATABASE IF NOT EXISTS " + ins . dbName )
2017-07-12 11:05:18 +00:00
if err != nil {
return err
}
fmt . Println ( "The database was successfully created" )
}
2017-11-13 05:22:37 +00:00
fmt . Println ( "Switching to database " , ins . dbName )
2017-10-14 07:39:22 +00:00
_ , err = db . Exec ( "USE " + ins . dbName )
2017-07-12 11:05:18 +00:00
if err != nil {
return err
}
2017-08-13 11:22:34 +00:00
2017-07-12 11:05:18 +00:00
// Ready the query builder
qgen . Builder . SetConn ( db )
2017-11-13 05:22:37 +00:00
return qgen . Builder . SetAdapter ( "mysql" )
2017-07-12 11:05:18 +00:00
}
2017-10-21 00:27:47 +00:00
func ( ins * MysqlInstaller ) TableDefs ( ) ( err error ) {
2018-04-23 21:08:31 +00:00
fmt . Println ( "Creating the tables" )
2017-07-12 11:05:18 +00:00
files , _ := ioutil . ReadDir ( "./schema/mysql/" )
for _ , f := range files {
2017-09-03 04:50:31 +00:00
if ! strings . HasPrefix ( f . Name ( ) , "query_" ) {
2017-07-12 11:05:18 +00:00
continue
}
2017-08-13 11:22:34 +00:00
2017-09-22 05:36:15 +00:00
var table , ext string
2017-09-03 04:50:31 +00:00
table = strings . TrimPrefix ( f . Name ( ) , "query_" )
2017-07-12 11:05:18 +00:00
ext = filepath . Ext ( table )
if ext != ".sql" {
continue
}
2017-09-03 04:50:31 +00:00
table = strings . TrimSuffix ( table , ext )
2017-08-13 11:22:34 +00:00
2017-10-21 00:27:47 +00:00
// ? - This is mainly here for tests, although it might allow the installer to overwrite a production database, so we might want to proceed with caution
_ , err = ins . db . Exec ( "DROP TABLE IF EXISTS `" + table + "`;" )
if err != nil {
fmt . Println ( "Failed query:" , "DROP TABLE IF EXISTS `" + table + "`;" )
return err
}
2018-04-23 21:08:31 +00:00
fmt . Printf ( "Creating table '%s'\n" , table )
2017-07-12 11:05:18 +00:00
data , err := ioutil . ReadFile ( "./schema/mysql/" + f . Name ( ) )
if err != nil {
return err
}
data = bytes . TrimSpace ( data )
2017-08-13 11:22:34 +00:00
2017-10-14 07:39:22 +00:00
_ , err = ins . db . Exec ( string ( data ) )
2017-07-12 11:05:18 +00:00
if err != nil {
2017-09-03 04:50:31 +00:00
fmt . Println ( "Failed query:" , string ( data ) )
2019-02-23 06:55:34 +00:00
panic ( "Failed query:" , string ( data ) )
2017-07-12 11:05:18 +00:00
return err
}
}
return nil
}
2017-09-22 05:36:15 +00:00
// ? - Moved this here since it was breaking the installer, we need to add this at some point
/* TODO: Implement the html-attribute setting type before deploying this */
/*INSERT INTO settings(`name`,`content`,`type`) VALUES ('meta_desc','','html-attribute');*/
2017-10-14 07:39:22 +00:00
func ( ins * MysqlInstaller ) InitialData ( ) error {
2018-04-23 21:08:31 +00:00
fmt . Println ( "Seeding the tables" )
2017-07-12 11:05:18 +00:00
data , err := ioutil . ReadFile ( "./schema/mysql/inserts.sql" )
if err != nil {
return err
}
data = bytes . TrimSpace ( data )
2017-08-13 11:22:34 +00:00
2017-10-14 07:39:22 +00:00
statements := bytes . Split ( data , [ ] byte ( ";" ) )
2018-04-23 21:08:31 +00:00
for key , sBytes := range statements {
statement := string ( sBytes )
if statement == "" {
2017-07-12 11:05:18 +00:00
continue
}
2018-04-23 21:08:31 +00:00
statement += ";"
2017-07-12 11:05:18 +00:00
2018-04-23 21:08:31 +00:00
fmt . Println ( "Executing query #" + strconv . Itoa ( key ) + " " + statement )
_ , err = ins . db . Exec ( statement )
2017-07-12 11:05:18 +00:00
if err != nil {
return err
}
}
return nil
}
2017-10-14 07:39:22 +00:00
func ( ins * MysqlInstaller ) CreateAdmin ( ) error {
return createAdmin ( )
}
func ( ins * MysqlInstaller ) DBHost ( ) string {
return ins . dbHost
}
func ( ins * MysqlInstaller ) DBUsername ( ) string {
return ins . dbUsername
}
func ( ins * MysqlInstaller ) DBPassword ( ) string {
return ins . dbPassword
}
func ( ins * MysqlInstaller ) DBName ( ) string {
return ins . dbName
}
func ( ins * MysqlInstaller ) DBPort ( ) string {
return ins . dbPort
}