mappings.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package orm
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "path"
  7. "reflect"
  8. "strings"
  9. "github.com/jinzhu/inflection"
  10. )
  11. var (
  12. fns map[string]func(map[string]string, *http.Request) (interface{}, error)
  13. )
  14. func init() {
  15. fns = make(map[string]func(map[string]string, *http.Request) (interface{}, error), 0)
  16. }
  17. func MapHandlers(models []interface{}) error {
  18. for _, model := range models {
  19. name := inflection.Plural(strings.ToLower(modelName(model)))
  20. for p, action := range map[string]string{
  21. "": "ReadAll",
  22. "create/": "Create",
  23. "{id}": "Read",
  24. "{id}/update": "Update",
  25. "{id}/delete": "Delete",
  26. } {
  27. method := reflect.ValueOf(model).MethodByName(action)
  28. if !method.IsValid() {
  29. return fmt.Errorf("Action %s is not defined for model %s", action, name)
  30. }
  31. joinedPath := path.Join("/", name, p)
  32. if strings.HasSuffix(p, "/") {
  33. joinedPath += "/"
  34. }
  35. fns[joinedPath] = method.Interface().(func(map[string]string, *http.Request) (interface{}, error))
  36. fns["/api"+joinedPath] = method.Interface().(func(map[string]string, *http.Request) (interface{}, error))
  37. }
  38. }
  39. return nil
  40. }
  41. func GetFunc(path string) (GetFn, error) {
  42. fn, ok := fns[path]
  43. if !ok {
  44. log.Println(fns)
  45. return nil, fmt.Errorf("Can't map path %s to any model methods.", path)
  46. }
  47. return fn, nil
  48. }
  49. func GetNothing(args map[string]string) (interface{}, error) {
  50. return nil, nil
  51. }
  52. func PostNothing(args map[string]string, r *http.Request) (IDer, error) {
  53. return nil, nil
  54. }
  55. func modelName(s interface{}) string {
  56. if t := reflect.TypeOf(s); t.Kind() == reflect.Ptr {
  57. return t.Elem().Name()
  58. } else {
  59. return t.Name()
  60. }
  61. }