Browse Source

Collection

- impl
Alexey Kim 2 năm trước cách đây
mục cha
commit
3496660059
4 tập tin đã thay đổi với 73 bổ sung7 xóa
  1. 48 0
      db/clickhouse.go
  2. 1 0
      db/database.go
  3. 23 1
      graphql/query_collections.go
  4. 1 6
      graphql/query_product.go

+ 48 - 0
db/clickhouse.go

@@ -10,6 +10,7 @@ import (
 	"github.com/jellydator/ttlcache/v3"
 	"github.com/mailru/dbr"
 	_ "github.com/mailru/go-clickhouse"
+	"gshopper.com/gshopify/products/cache"
 	"gshopper.com/gshopify/products/graphql/generated"
 	"gshopper.com/gshopify/products/relation"
 	"net/url"
@@ -75,6 +76,53 @@ func New(ctx context.Context, forceDebug bool) (Database, error) {
 	return r, nil
 }
 
+func (db *clickhouse) Collection(ln model.LanguageCode, handle *string, id *string) (*generated.Collection, error) {
+	var (
+		clause = strings.Builder{}
+		vars   []any
+		key    *cache.SqlKey
+		loader ttlcache.LoaderFunc[string, any]
+	)
+
+	if id != nil {
+		clause.WriteString("id=?")
+		vars = append(vars, *id)
+	}
+
+	if handle != nil {
+		if clause.Len() > 0 {
+			clause.WriteString(" AND ")
+		}
+
+		clause.WriteString("handle=?")
+		vars = append(vars, *handle)
+	}
+
+	key = productCollectionKey(clause.String(), vars...)
+	loader = func(ttl *ttlcache.Cache[string, any], _ string) *ttlcache.Item[string, any] {
+		var o relation.ProductCollection
+		rows, err := db.session.
+			Select(productCollectionSelection(ln)...).
+			From(key.Table()).
+			Where(key.Clause(), key.Args()...).
+			Limit(1).
+			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](loader))
+	if p == nil {
+		return nil, fmt.Errorf("not found")
+	}
+
+	collection := p.Value().(relation.ProductCollection)
+	return collection.As(), nil
+}
+
 func (db *clickhouse) Collections(ln model.LanguageCode) ([]*generated.Collection, error) {
 	var (
 		collections []*generated.Collection

+ 1 - 0
db/database.go

@@ -21,6 +21,7 @@ type Database interface {
 	ProductVariants(ctx *middleware.GShopifyContext, id string) ([]*generated.ProductVariant, error)
 	ProductVariantOptions(ln model.LanguageCode, id string) ([]*generated.SelectedOption, error)
 
+	Collection(ln model.LanguageCode, handle *string, id *string) (*generated.Collection, error)
 	Collections(ln model.LanguageCode) ([]*generated.Collection, error)
 	ProductCollections(ln model.LanguageCode, id string) ([]*generated.Collection, error)
 	CollectionProducts(ln model.LanguageCode, id string) ([]*generated.Product, error)

+ 23 - 1
graphql/query_collections.go

@@ -2,6 +2,7 @@ package graphql
 
 import (
 	"context"
+	"fmt"
 	"github.com/gshopify/service-wrapper/fun"
 	"github.com/gshopify/service-wrapper/model"
 	"github.com/gshopify/service-wrapper/server/middleware"
@@ -11,7 +12,28 @@ import (
 )
 
 func (r *queryResolver) Collection(ctx context.Context, handle *string, id *string) (*generated.Collection, error) {
-	panic("not implemented")
+	var (
+		inContext *middleware.GShopifyContext
+		err       error
+	)
+
+	if inContext, err = middleware.InContext(ctx); err != nil {
+		return nil, err
+	}
+
+	if id == nil && handle == nil {
+		return nil, fmt.Errorf("at least one argument must be specified")
+	}
+
+	if id != nil {
+		if s, err := model.ParseId(model.GidCollection, *id); err != nil {
+			return nil, err
+		} else {
+			*id = s
+		}
+	}
+
+	return r.db.Collection(inContext.Language, handle, id)
 }
 
 func (r *queryResolver) Collections(ctx context.Context,

+ 1 - 6
graphql/query_product.go

@@ -15,7 +15,6 @@ import (
 func (r *queryResolver) Product(ctx context.Context, handle *string, id *string) (*generated.Product, error) {
 	var (
 		inContext *middleware.GShopifyContext
-		product   *generated.Product
 		err       error
 	)
 
@@ -35,11 +34,7 @@ func (r *queryResolver) Product(ctx context.Context, handle *string, id *string)
 		}
 	}
 
-	if product, err = r.db.Product(inContext.Language, handle, id); err != nil {
-		return nil, err
-	}
-
-	return product, nil
+	return r.db.Product(inContext.Language, handle, id)
 }
 
 func (r *queryResolver) Products(ctx context.Context,