Skip to content

Commit 5b44fc6

Browse files
committed
- proper caching method implemented
1 parent 5dc4d58 commit 5b44fc6

File tree

5 files changed

+104
-58
lines changed

5 files changed

+104
-58
lines changed

controllers/crud.go

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/http"
77
"strconv"
88
"strings"
9+
"sync"
910
)
1011

1112
//CreateName create new name on database of type NameType
@@ -25,14 +26,27 @@ func CreateName(c *gin.Context) {
2526
return
2627
}
2728

29+
//Check the cache
30+
preloadTable := checkCache(c)
31+
32+
//Check if there's an exact name on the database
33+
for _, name := range preloadTable {
34+
if name.Name == input.Name {
35+
c.JSON(http.StatusBadRequest, gin.H{"Message": " Duplicate entry " + name.Name})
36+
return
37+
}
38+
}
39+
2840
//create name
2941
n, err := input.CreateName()
3042
if err != nil {
3143
c.JSON(http.StatusInternalServerError, gin.H{"Error": err.Error()})
3244
return
3345
}
3446

47+
clearCache(c)
3548
c.JSON(http.StatusOK, n)
49+
return
3650
}
3751

3852
//GetID read name by id
@@ -82,32 +96,21 @@ func GetName(c *gin.Context) {
8296
func GetMetaphoneMatch(c *gin.Context) {
8397
var nameType models.NameType
8498

85-
//Check the cache
86-
var preloadTable []models.NameType
87-
cache, existKey := c.Get("nameTypes")
88-
if existKey {
89-
preloadTable = cache.([]models.NameType)
90-
} else {
91-
allNames, err := nameType.GetAllNames()
92-
if err != nil {
93-
c.JSON(http.StatusInternalServerError, gin.H{"Message": "Error on caching all name types"})
94-
return
95-
}
96-
preloadTable = allNames
97-
}
98-
9999
//name to be searched
100100
name := c.Params.ByName("name")
101101

102+
//Check the cache
103+
preloadTable := checkCache(c)
104+
102105
//search similar names
103106
canonicalEntity, err := nameType.GetSimilarMatch(name, preloadTable)
104107
if err != nil {
105108
c.JSON(http.StatusNotFound, gin.H{"Message": "Couldn't find canonical entity"})
106109
return
110+
} else {
111+
c.JSON(200, canonicalEntity)
112+
return
107113
}
108-
109-
c.JSON(200, canonicalEntity)
110-
return
111114
}
112115

113116
//UpdateName update name by id
@@ -151,22 +154,30 @@ func UpdateName(c *gin.Context) {
151154
c.JSON(http.StatusBadRequest, gin.H{"Message": "Every item on json is the same on the database id " + param})
152155
return
153156
} else {
154-
if input.Name != "" {
157+
if input.Name != "" && input.Name == name.Name {
155158
name.Name = input.Name
156159
}
157-
if input.Classification != "" {
160+
if input.Classification != "" && input.Classification == name.Classification {
158161
name.Classification = input.Classification
159162
}
160-
if input.Metaphone != "" {
163+
if input.Metaphone != "" && input.Metaphone == name.Metaphone {
161164
name.Metaphone = input.Metaphone
162165
}
163-
if input.NameVariations != "" {
166+
if input.NameVariations != "" && input.NameVariations == name.NameVariations {
164167
name.NameVariations = input.NameVariations
165168
}
166169

167-
db.Save(name)
170+
r := db.Save(name)
171+
if r.Error != nil {
172+
c.JSON(http.StatusBadRequest, gin.H{"Error": r.Error})
173+
return
174+
}
175+
168176
c.JSON(http.StatusOK, name)
177+
clearCache(c)
178+
return
169179
}
180+
170181
}
171182

172183
//DeleteName delete name off database by id
@@ -197,4 +208,35 @@ func DeleteName(c *gin.Context) {
197208
}
198209

199210
c.JSON(http.StatusOK, gin.H{"Delete": "id " + param + " was deleted"})
211+
clearCache(c)
212+
return
213+
}
214+
215+
func checkCache(c *gin.Context) []models.NameType {
216+
var nameType models.NameType
217+
var preloadTable []models.NameType
218+
219+
cache, existKey := c.Get("nameTypes")
220+
if existKey {
221+
preloadTable = cache.([]models.NameType)
222+
} else {
223+
allNames, err := nameType.GetAllNames()
224+
if err != nil {
225+
c.JSON(http.StatusInternalServerError, gin.H{"Message": "Error on caching all name types"})
226+
return nil
227+
}
228+
preloadTable = allNames
229+
c.Set("nameTypes", preloadTable)
230+
}
231+
232+
return preloadTable
233+
}
234+
235+
func clearCache(c *gin.Context) {
236+
cache, exist := c.Get("nameTypes")
237+
if exist {
238+
if cm, ok := cache.(sync.Map); ok {
239+
cm.Delete("preloadTable")
240+
}
241+
}
200242
}

database/db.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,23 @@ func ConnectDB() *gorm.DB {
4343

4444
dsn := DbUsername + ":" + DbPassword + "@tcp" + "(" + DbHost + ":" + DbPort + ")/" + DbName + "?" + "parseTime=true&loc=Local"
4545

46-
err = uploadCSVNameTypes(dsn)
46+
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
4747
if err != nil {
48-
fmt.Printf("Error uploading .csv to database : error=%v\n", err)
48+
fmt.Printf("Error connecting to database : error=%v\n", err)
4949
return nil
5050
}
5151

52-
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
52+
err = db.AutoMigrate(models.NameType{}, models.User{}, models.Log{})
5353
if err != nil {
54-
fmt.Printf("Error connecting to database : error=%v\n", err)
54+
fmt.Printf("Error on gorm auto migrate to database : error=%v\n", err)
55+
return nil
56+
}
57+
58+
DB = db
59+
60+
err = uploadCSVNameTypes()
61+
if err != nil {
62+
fmt.Printf("Error uploading .csv to database : error=%v\n", err)
5563
return nil
5664
}
5765

@@ -87,15 +95,9 @@ func createDatabase(host, username, password, dbName string) error {
8795
}
8896

8997
//UploadCSVNameTypes upload the .csv file on database folder on names table
90-
func uploadCSVNameTypes(dsn string) error {
91-
// Open a connection to the MySQL server
92-
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
93-
if err != nil {
94-
return fmt.Errorf("failed to connect to MySQL: %v", err)
95-
}
96-
98+
func uploadCSVNameTypes() error {
9799
var name models.NameType
98-
db.Raw("select * from name_types where id = 1").Find(&name)
100+
DB.Raw("select * from name_types where id = 1").Find(&name)
99101

100102
if name.ID == 0 {
101103
start := time.Now()

main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ import (
99

1010
func init() {
1111
db := database.ConnectDB()
12-
models.DB = db
13-
14-
err := db.AutoMigrate(models.NameType{}, models.User{}, models.Log{})
15-
if err != nil {
16-
fmt.Printf("Error on gorm auto migrate to database : error=%v\n", err)
12+
if db.Error != nil {
13+
fmt.Printf("Error on connecting to the database : error=%v\n", db.Error)
1714
return
1815
}
16+
models.DB = db
1917

20-
err = models.CreateRoot()
18+
err := models.CreateRoot()
2119
if err != nil {
2220
fmt.Printf("Error on creating root user on database: error=%v\n", err)
2321
return

models/name.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (n *NameType) CreateName() (*NameType, error) {
2929

3030
func (*NameType) GetAllNames() ([]NameType, error) {
3131
var Names []NameType
32-
r := DB.Raw("select * from name_types").Find(&Names)
32+
r := DB.Raw("select * from name_types where name_types.deleted_at is null").Find(&Names)
3333
if r.Error != nil {
3434
return nil, r.Error
3535
}
@@ -38,7 +38,7 @@ func (*NameType) GetAllNames() ([]NameType, error) {
3838

3939
func (*NameType) GetNameById(id int) (*NameType, *gorm.DB, error) {
4040
var getName NameType
41-
data := DB.Raw("select * from name_types where id = ?", id).Find(&getName)
41+
data := DB.Raw("select * from name_types where id = ? AND name_types.deleted_at is null", id).Find(&getName)
4242
if data.Error != nil {
4343
return nil, nil, data.Error
4444
}
@@ -47,7 +47,7 @@ func (*NameType) GetNameById(id int) (*NameType, *gorm.DB, error) {
4747

4848
func (*NameType) GetNameByName(name string) (*NameType, error) {
4949
var getName NameType
50-
data := DB.Raw("select * from name_types where name = ?", name).Find(&getName)
50+
data := DB.Raw("select * from name_types where name = ? AND name_types.deleted_at is null", name).Find(&getName)
5151
if data.Error != nil {
5252
return nil, data.Error
5353
}
@@ -56,7 +56,7 @@ func (*NameType) GetNameByName(name string) (*NameType, error) {
5656

5757
func (*NameType) GetNameByMetaphone(mtf string) ([]NameType, error) {
5858
var getNames []NameType
59-
data := DB.Raw("select * from name_types where metaphone = ?", mtf).Find(&getNames)
59+
data := DB.Raw("select * from name_types where metaphone = ? AND name_types.deleted_at is null", mtf).Find(&getNames)
6060
if data.Error != nil {
6161
return nil, data.Error
6262
}
@@ -116,7 +116,7 @@ func (n *NameType) GetSimilarMatch(name string, allNames []NameType) (*NameType,
116116

117117
func (*NameType) DeleteNameById(id int) (NameType, error) {
118118
var getName NameType
119-
r := DB.Raw("select * from name_types where id = ?", id).Find(&getName)
119+
r := DB.Where("id = ?", id).Delete(&getName)
120120
if r.Error != nil {
121121
return NameType{}, r.Error
122122
}

routes/routes.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/gin-gonic/gin"
88
"net/http"
99
"os"
10+
"sync"
1011
"time"
1112
)
1213

@@ -45,12 +46,14 @@ func HandleRequests() {
4546

4647
//main middleware validation
4748
r.Use(middlewares.ValidateAuth())
49+
cache := &sync.Map{}
50+
r.Use(cachingNameTypes(cache))
4851

4952
//CRUD routes
5053
r.POST("/name", middlewares.ValidateName(), middlewares.ValidateNameJSON(), controllers.CreateName)
5154
r.GET("/:id", middlewares.ValidateID(), controllers.GetID)
5255
r.GET("/name/:name", middlewares.ValidateName(), controllers.GetName)
53-
r.GET("/metaphone/:name", middlewares.ValidateName(), cachingNameTypes(nameTypesCache), controllers.GetMetaphoneMatch)
56+
r.GET("/metaphone/:name", middlewares.ValidateName(), controllers.GetMetaphoneMatch)
5457
r.PATCH("/:id", middlewares.ValidateID(), middlewares.ValidateNameJSON(), controllers.UpdateName)
5558
r.DELETE("/:id", middlewares.ValidateID(), controllers.DeleteName)
5659

@@ -61,21 +64,22 @@ func HandleRequests() {
6164
}
6265
}
6366

64-
func cachingNameTypes(nameTypesCache []models.NameType) gin.HandlerFunc {
65-
var name models.NameType
66-
67-
if nameTypesCache == nil {
68-
nameTypes, err := name.GetAllNames()
69-
if err != nil {
70-
return func(c *gin.Context) {
67+
func cachingNameTypes(cache *sync.Map) gin.HandlerFunc {
68+
return func(c *gin.Context) {
69+
//Check the cache
70+
cacheData, existKey := cache.Load("nameTypes")
71+
if existKey {
72+
c.Set("nameTypes", cacheData)
73+
} else {
74+
var nameType models.NameType
75+
allNames, err := nameType.GetAllNames()
76+
if err != nil {
7177
c.JSON(http.StatusInternalServerError, gin.H{"Message": "Error on caching all name types"})
78+
return
7279
}
80+
cache.Store("nameTypes", allNames)
81+
c.Set("nameTypes", allNames)
7382
}
74-
nameTypesCache = nameTypes
75-
}
76-
77-
return func(c *gin.Context) {
78-
c.Set("nameTypes", nameTypesCache)
7983
c.Next()
8084
}
8185
}

0 commit comments

Comments
 (0)