2019-11-04 15:00:46 +01:00
|
|
|
package orm
|
|
|
|
|
|
|
|
import (
|
2020-01-15 11:27:00 +01:00
|
|
|
"errors"
|
2019-11-04 15:00:46 +01:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"path"
|
2020-01-17 07:59:57 +01:00
|
|
|
|
2019-11-04 15:00:46 +01:00
|
|
|
"strings"
|
|
|
|
|
2019-12-03 11:14:29 +01:00
|
|
|
"git.andreafazzi.eu/andrea/oef/config"
|
2020-01-17 07:59:57 +01:00
|
|
|
"git.andreafazzi.eu/andrea/oef/reflect"
|
|
|
|
|
2019-11-04 15:00:46 +01:00
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
|
|
|
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
|
|
)
|
|
|
|
|
|
|
|
type IDer interface {
|
|
|
|
GetID() uint
|
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
type GetFn func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error)
|
2019-11-04 15:00:46 +01:00
|
|
|
|
2020-01-14 16:28:27 +01:00
|
|
|
type Database struct {
|
|
|
|
Config *config.ConfigT
|
2019-11-04 15:00:46 +01:00
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
models []interface{}
|
|
|
|
_db *gorm.DB
|
|
|
|
fns map[string]func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error)
|
2019-11-04 15:00:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func NewDatabase(config *config.ConfigT, models []interface{}) (*Database, error) {
|
|
|
|
var err error
|
|
|
|
|
2020-01-14 16:28:27 +01:00
|
|
|
db := new(Database)
|
|
|
|
|
2020-01-15 13:40:35 +01:00
|
|
|
db.Config = config
|
2020-01-20 12:07:02 +01:00
|
|
|
db.models = models
|
2020-01-15 13:40:35 +01:00
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
db.fns = make(map[string]func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error), 0)
|
|
|
|
db.mapHandlers(models)
|
|
|
|
|
|
|
|
db._db, err = gorm.Open("mysql", fmt.Sprintf("%s?%s", config.Orm.Connection, config.Orm.Options))
|
2019-11-04 15:00:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-01-15 11:27:00 +01:00
|
|
|
return db, err
|
2019-11-04 15:00:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func (db *Database) AutoMigrate() {
|
|
|
|
if err := db._db.AutoMigrate(db.models...).Error; err != nil {
|
2019-11-04 15:00:46 +01:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-02-08 12:27:13 +01:00
|
|
|
func (db *Database) Reset() {
|
|
|
|
if err := db._db.DropTable(db.models...).Error; err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func (db *Database) GetUser(username, password string) (*User, error) {
|
2020-01-15 13:40:35 +01:00
|
|
|
var user User
|
2020-01-15 11:27:00 +01:00
|
|
|
if err := db._db.Where("username = ? AND password = ?", username, password).First(&user).Error; err != nil {
|
|
|
|
return nil, errors.New("Authentication failed!")
|
2019-12-09 08:27:46 +01:00
|
|
|
}
|
2020-01-15 13:40:35 +01:00
|
|
|
return &user, nil
|
2019-12-09 08:27:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func (db *Database) DB() *gorm.DB {
|
|
|
|
return db._db
|
2019-11-04 15:00:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func CreateCategories(db *Database) {
|
|
|
|
for _, name := range categories {
|
|
|
|
var category Category
|
|
|
|
if err := db._db.FirstOrCreate(&category, Category{Name: name}).Error; err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2019-11-04 15:00:46 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func (db *Database) mapHandlers(models []interface{}) error {
|
2019-11-04 15:00:46 +01:00
|
|
|
for _, model := range models {
|
2020-01-17 07:59:57 +01:00
|
|
|
name := reflect.ModelNameLowerPlural(model)
|
2019-11-04 15:00:46 +01:00
|
|
|
for p, action := range map[string]string{
|
|
|
|
"": "ReadAll",
|
|
|
|
"create/": "Create",
|
|
|
|
"{id}": "Read",
|
|
|
|
"{id}/update": "Update",
|
|
|
|
"{id}/delete": "Delete",
|
|
|
|
} {
|
2020-01-17 07:59:57 +01:00
|
|
|
method := reflect.ModelMethod(model, action)
|
2019-11-04 15:00:46 +01:00
|
|
|
if !method.IsValid() {
|
|
|
|
return fmt.Errorf("Action %s is not defined for model %s", action, name)
|
|
|
|
}
|
|
|
|
joinedPath := path.Join("/", name, p)
|
|
|
|
if strings.HasSuffix(p, "/") {
|
|
|
|
joinedPath += "/"
|
|
|
|
}
|
2020-01-15 11:27:00 +01:00
|
|
|
db.fns[joinedPath] = method.Interface().(func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error))
|
2019-11-04 15:00:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-15 11:27:00 +01:00
|
|
|
func (db *Database) GetFunc(path string) (GetFn, error) {
|
|
|
|
fn, ok := db.fns[path]
|
2019-11-04 15:00:46 +01:00
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("Can't map path %s to any model methods.", path)
|
|
|
|
}
|
|
|
|
return fn, nil
|
|
|
|
}
|