Browse Source

ProductOption

- implement ttlcache (close #5)
Alexey Kim 2 years ago
parent
commit
b24726e3d6
2 changed files with 43 additions and 20 deletions
  1. 27 17
      db/clickhouse.go
  2. 16 3
      db/product.go

+ 27 - 17
db/clickhouse.go

@@ -83,7 +83,8 @@ func (db *clickhouse) ProductCollections(ln model.LanguageCode, id string) ([]*g
 				var o []relation.Collection
 
 				rows, err := db.session.SelectBySql("SELECT "+
-					ln.SqlFieldSelection("title")+", "+ln.SqlFieldSelection("description")+", `id`, `handle`, `thumbnail`, "+
+					ln.SqlFieldSelection("title")+", "+ln.SqlFieldSelection("description")+
+					", `id`, `handle`, `thumbnail`, "+
 					"`created_at`, `updated_at`, `deleted_at` "+
 					"FROM `product_collection` "+
 					"ARRAY JOIN (SELECT `collection_ids` FROM `product` WHERE `id` = ?) AS cid "+
@@ -158,24 +159,33 @@ func (db *clickhouse) Product(ln model.LanguageCode, handle *string, id *string)
 }
 
 func (db *clickhouse) ProductOptions(ln model.LanguageCode, id string) ([]*generated.ProductOption, error) {
-	var options []*generated.ProductOption
-	var o []relation.ProductOption
-	_, err := db.session.
-		Select(
-			"id",
-			"product_id",
-			"created_at", "updated_at", "deleted_at",
-			ln.SqlFieldSelection("name"),
-			ln.SqlArraySelection("values")).
-		From("product_option").
-		Where("product_id=?", id).
-		OrderBy("created_at").
-		Load(&o)
-	if err != nil {
-		return nil, err
+	var (
+		options []*generated.ProductOption
+		key     = productOptionKey("product_id=?", id)
+		l       = ttlcache.LoaderFunc[string, any](
+			func(ttl *ttlcache.Cache[string, any], _ string) *ttlcache.Item[string, any] {
+				var o []relation.ProductOption
+				rows, err := db.session.
+					Select(productOptionSelection(ln)...).
+					From(key.Table()).
+					Where(key.Clause(), key.Args()...).
+					OrderBy("created_at").
+					Load(&o)
+				if rows < 1 || err != nil {
+					return nil
+				}
+
+				return ttl.Set(key.String(), o, key.TTL())
+			},
+		)
+	)
+
+	p := db.cache.Get(key.String(), ttlcache.WithLoader[string, any](l))
+	if p == nil {
+		return nil, fmt.Errorf("not found")
 	}
 
-	for _, v := range o {
+	for _, v := range p.Value().([]relation.ProductOption) {
 		options = append(options, v.As())
 	}
 

+ 16 - 3
db/product.go

@@ -11,9 +11,7 @@ var (
 		return cache.NewSQLKey(
 			"product",
 			time.Minute,
-			clause,
-			args...,
-		)
+			clause, args...)
 	}
 	productSelection = func(ln model.LanguageCode) []string {
 		return append([]string{
@@ -34,4 +32,19 @@ var (
 			args...,
 		)
 	}
+	productOptionSelection = func(ln model.LanguageCode) []string {
+		return append([]string{
+			"id", "product_id",
+			"created_at", "updated_at", "deleted_at",
+		},
+			ln.SqlFieldSelection("name"),
+			ln.SqlArraySelection("values"),
+		)
+	}
+	productOptionKey = func(clause string, args ...any) *cache.SqlKey {
+		return cache.NewSQLKey(
+			"product_option",
+			time.Second*30,
+			clause, args...)
+	}
 )