The backend for the AiteStory website
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
3.6 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package model
  2. import (
  3. "errors"
  4. "strings"
  5. "git.aiterp.net/AiteRP/aitestory/server"
  6. "git.aiterp.net/gisle/wrouter/generate"
  7. )
  8. // TagTypes are the allowed values for Tag.Type
  9. var TagTypes = []string{
  10. "Location",
  11. "Character",
  12. "Event",
  13. "Organization",
  14. "Source",
  15. }
  16. // Tag describes a tag
  17. type Tag struct {
  18. ID string
  19. Type string
  20. Name string
  21. }
  22. // Insert adds the tag to the database, giving it a new unique ID
  23. func (tag *Tag) Insert() error {
  24. db := server.Main.DB
  25. // Validate tag type
  26. if err := tag.Validate(); err != nil {
  27. return err
  28. }
  29. // Generate an ID if none exists
  30. if tag.ID == "" {
  31. tag.ID = generate.ID()
  32. }
  33. // Do the thing
  34. _, err := db.Exec("INSERT INTO `tag` (id,type,name,disabled) VALUES (?,?,?,false)", tag.ID, tag.Type, tag.Name)
  35. if err != nil {
  36. return err
  37. }
  38. return nil
  39. }
  40. // Update saves the entry for the tag in the database
  41. func (tag *Tag) Update() error {
  42. db := server.Main.DB
  43. // Validate tag type
  44. if err := tag.Validate(); err != nil {
  45. return err
  46. }
  47. // Do the thing
  48. _, err := db.Exec("UPDATE `tag` SET type=?,name=? WHERE id=?", tag.Type, tag.Name, tag.ID)
  49. if err != nil {
  50. return err
  51. }
  52. return nil
  53. }
  54. // Delete removes a tag from the database
  55. func (tag *Tag) Delete() error {
  56. db := server.Main.DB
  57. // Do the thing
  58. results, err := db.Exec("DELETE FROM `tag` WHERE id=? LIMIT 1", tag.ID)
  59. if err != nil {
  60. return err
  61. }
  62. // Count the stuffs that were done things to
  63. affected, err := results.RowsAffected()
  64. if err != nil {
  65. return err
  66. }
  67. if affected == 0 {
  68. return errors.New("tag not found")
  69. }
  70. return nil
  71. }
  72. // Validate checks the name and type, and returns an error if they're not valid. It's
  73. // ran by Update and Insert before doing anything
  74. func (tag *Tag) Validate() error {
  75. validType := false
  76. for _, tagType := range TagTypes {
  77. if tagType == tag.Type {
  78. validType = true
  79. break
  80. }
  81. }
  82. if !validType {
  83. return errors.New("invalid tag type")
  84. }
  85. // Validate tag name
  86. if len(tag.Name) == 0 || len(tag.Name) > 64 {
  87. return errors.New("invalid length")
  88. }
  89. return nil
  90. }
  91. // Hook returns the url friendly name, which is pretty much just
  92. // adding underscores to it.
  93. func (tag Tag) Hook() string {
  94. return strings.Replace(tag.Name, " ", "_", -1)
  95. }
  96. // FindTag finds a tag by ID
  97. func FindTag(key string, id string) (*Tag, error) {
  98. db := server.Main.DB
  99. // Make damn sure that – should this take user data as key – it
  100. // does not open up for a SQL injection attack
  101. if key != "name" && key != "id" {
  102. return nil, errors.New("invalid key")
  103. }
  104. rows, err := db.Query("SELECT id,type,name FROM `tag` WHERE "+key+"=? AND disabled=false", id)
  105. if err != nil {
  106. return nil, err
  107. }
  108. defer rows.Close()
  109. if !rows.Next() {
  110. return nil, errors.New("not found")
  111. }
  112. tag := new(Tag)
  113. rows.Scan(&tag.ID, &tag.Type, &tag.Name)
  114. return tag, nil
  115. }
  116. // EnsureTag finds or creates a tag.
  117. func EnsureTag(tagType, tagName string) (*Tag, error) {
  118. // Try to find it first
  119. tag, err := FindTag("name", tagName)
  120. if err != nil && err.Error() != "not found" { // You saw nothing
  121. return nil, err
  122. }
  123. // Failing that, make it
  124. if tag == nil {
  125. tag = new(Tag)
  126. tag.Type = tagType
  127. tag.Name = tagName
  128. err = tag.Insert()
  129. if err != nil {
  130. return nil, err
  131. }
  132. }
  133. return tag, nil
  134. }
  135. // ListTags finds all the tags, without filter.
  136. func ListTags() ([]Tag, error) {
  137. db := server.Main.DB
  138. rows, err := db.Query("SELECT id,type,name FROM `tag` WHERE disabled=false")
  139. if err != nil {
  140. return nil, err
  141. }
  142. defer rows.Close()
  143. results := make([]Tag, 0, 64)
  144. for rows.Next() {
  145. tag := Tag{}
  146. rows.Scan(&tag.ID, &tag.Type, &tag.Name)
  147. results = append(results, tag)
  148. }
  149. return results, nil
  150. }