Jelajahi Sumber

Products

- impl
Alexey Kim 2 tahun lalu
induk
melakukan
f2d81f03ff
4 mengubah file dengan 69 tambahan dan 24 penghapusan
  1. 19 9
      db/clickhouse.go
  2. 1 1
      db/database.go
  3. 31 11
      graphql/helper/product.go
  4. 18 3
      graphql/query_product.go

+ 19 - 9
db/clickhouse.go

@@ -299,10 +299,23 @@ func (db *clickhouse) ProductVariants(ctx *middleware.GShopifyContext, id string
 	return variants, nil
 }
 
-func (db *clickhouse) CollectionProducts(ln model.LanguageCode, id string) ([]*generated.Product, error) {
+func (db *clickhouse) Products(ln model.LanguageCode, collectionId *string) ([]*generated.Product, error) {
+	var (
+		clause = strings.Builder{}
+		args   []any
+	)
+
+	clause.WriteString("t.status = ?")
+	args = append(args, model.ProductStatusActive)
+
+	if collectionId != nil {
+		clause.WriteString(" AND has(t.collections, ?)")
+		args = append(args, *collectionId)
+	}
+
 	var (
 		products []*generated.Product
-		key      = productKey(ln, defaultCurrency, "has(t.collections, ?) AND t.status = ?", id, model.ProductStatusActive)
+		key      = productKey(ln, defaultCurrency, clause.String(), args...)
 		l        = ttlcache.LoaderFunc[string, any](
 			func(ttl *ttlcache.Cache[string, any], _ string) *ttlcache.Item[string, any] {
 				var o []relation.Product
@@ -324,13 +337,10 @@ func (db *clickhouse) CollectionProducts(ln model.LanguageCode, id string) ([]*g
 		)
 	)
 
-	p := db.cache.Get(key.String(), ttlcache.WithLoader[string, any](l))
-	if p == nil {
-		return nil, fmt.Errorf("not found")
-	}
-
-	for _, row := range p.Value().([]relation.Product) {
-		products = append(products, row.As())
+	if p := db.cache.Get(key.String(), ttlcache.WithLoader[string, any](l)); p != nil {
+		for _, row := range p.Value().([]relation.Product) {
+			products = append(products, row.As())
+		}
 	}
 
 	return products, nil

+ 1 - 1
db/database.go

@@ -17,6 +17,7 @@ type Database interface {
 	Close() error
 
 	Product(ln model.LanguageCode, handle *string, id *string) (*generated.Product, error)
+	Products(ln model.LanguageCode, collectionId *string) ([]*generated.Product, error)
 	ProductOptions(ln model.LanguageCode, id string) ([]*generated.ProductOption, error)
 	ProductVariants(ctx *middleware.GShopifyContext, id string) ([]*generated.ProductVariant, error)
 	ProductVariantOptions(ln model.LanguageCode, id string) ([]*generated.SelectedOption, error)
@@ -24,5 +25,4 @@ type Database interface {
 	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)
 }

+ 31 - 11
graphql/helper/product.go

@@ -55,24 +55,44 @@ func NewProductConnection(src []*generated.Product,
 	return connection, nil
 }
 
-// SortProducts TODO: ProductCollectionSortKeysBestSelling
-// SortProducts TODO: ProductCollectionSortKeysCollectionDefault
-// SortProducts TODO: ProductCollectionSortKeysManual
-// SortProducts TODO: ProductCollectionSortKeysRelevance
-func SortProducts(src []*generated.Product, sortKey *generated.ProductCollectionSortKeys) []*generated.Product {
-	if sortKey == nil || !sortKey.IsValid() {
+func SortProducts(src []*generated.Product, k fmt.Stringer) []*generated.Product {
+	if k == nil {
 		return src[:]
 	}
 
+	sortBy := k.String()
+	if !generated.ProductSortKeys(sortBy).IsValid() &&
+		!generated.ProductCollectionSortKeys(sortBy).IsValid() {
+		return src[:]
+	}
+
+	return internalSortProducts(src[:], sortBy)
+}
+
+// internalSortProducts TODO: generated.ProductCollectionSortKeysBestSelling
+// internalSortProducts TODO: generated.ProductCollectionSortKeysCollectionDefault
+// internalSortProducts TODO: generated.ProductCollectionSortKeysManual
+// internalSortProducts TODO: generated.ProductCollectionSortKeysRelevance
+// internalSortProducts TODO: generated.ProductSortKeysBestSelling
+// internalSortProducts TODO: generated.ProductSortKeysRelevance
+func internalSortProducts(src []*generated.Product, key string) []*generated.Product {
 	sort.Slice(src[:], func(i, j int) bool {
-		switch *sortKey {
-		case generated.ProductCollectionSortKeysID:
+		switch key {
+		case "ID":
 			return src[i].ID < src[j].ID
-		case generated.ProductCollectionSortKeysTitle:
+		case "TITLE":
 			return src[i].Title < src[j].Title
-		case generated.ProductCollectionSortKeysCreated:
+		case "PRODUCT_TYPE":
+			return src[i].ProductType < src[j].ProductType
+		case "VENDOR":
+			return src[i].Vendor < src[j].Vendor
+		case "CREATED":
+			return src[i].CreatedAt < src[j].CreatedAt
+		case "CREATED_AT":
 			return src[i].CreatedAt < src[j].CreatedAt
-		case generated.ProductCollectionSortKeysPrice:
+		case "UPDATED_AT":
+			return src[i].UpdatedAt < src[j].UpdatedAt
+		case "PRICE":
 			return src[i].PriceRange.MinVariantPrice.Amount < src[j].PriceRange.MinVariantPrice.Amount
 		}
 

+ 18 - 3
graphql/query_product.go

@@ -38,8 +38,23 @@ func (r *queryResolver) Product(ctx context.Context, handle *string, id *string)
 }
 
 func (r *queryResolver) Products(ctx context.Context,
-	after *string, before *string, first *int, last *int, query *string, reverse *bool, sortKey *generated.ProductSortKeys) (*generated.ProductConnection, error) {
-	panic("not implemented")
+	after *string, before *string, first *int, last *int, query *string, reverse *bool, sort *generated.ProductSortKeys) (*generated.ProductConnection, error) {
+	var (
+		inContext *middleware.GShopifyContext
+		products  []*generated.Product
+		err       error
+	)
+
+	if inContext, err = middleware.InContext(ctx); err != nil {
+		return nil, err
+	}
+
+	if products, err = r.db.Products(inContext.Language, nil); err != nil {
+		return nil, err
+	}
+
+	products = helper.SortProducts(products, sort)
+	return helper.NewProductConnection(products, after, before, first, last, reverse)
 }
 
 func (r *productResolver) Description(_ context.Context, product *generated.Product, truncateAt *int) (string, error) {
@@ -66,7 +81,7 @@ func (r *collectionResolver) Products(ctx context.Context, collection *generated
 		return nil, err
 	}
 
-	if products, err = r.db.CollectionProducts(inContext.Language, rawId); err != nil {
+	if products, err = r.db.Products(inContext.Language, &rawId); err != nil {
 		return nil, err
 	}