From d44d7f8d1d5221047eaf223fb7a67dbbb8b4034f Mon Sep 17 00:00:00 2001
From: Jan Semmelink <jan@uafrica.com>
Date: Thu, 4 Nov 2021 09:33:06 +0200
Subject: [PATCH] Update search and reflection to return slice of user type
 docs

---
 reflection/type_clone.go |  9 ++++++++-
 search/search_test.go    |  9 ++++++++-
 search/time_series.go    | 22 ++++++++++++++--------
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/reflection/type_clone.go b/reflection/type_clone.go
index 9c3fad7..c142712 100644
--- a/reflection/type_clone.go
+++ b/reflection/type_clone.go
@@ -46,7 +46,14 @@ import (
 //than strings.HasPrefix() to check for delimiter/end of name to do full
 //word matches, and we need to extend the test to illustrate this.
 func CloneType(t reflect.Type, replace map[string]reflect.Type) (reflect.Type, error) {
-	return clone("", t, replace)
+	cloned, err := clone("", t, replace)
+	if err != nil {
+		return t, err
+	}
+	if len(replace) > 0 {
+		return t, errors.Errorf("unknown replacements: %+v", replace)
+	}
+	return cloned, nil
 }
 
 func clone(name string, t reflect.Type, replace map[string]reflect.Type) (reflect.Type, error) {
diff --git a/search/search_test.go b/search/search_test.go
index 333a254..068cb1a 100644
--- a/search/search_test.go
+++ b/search/search_test.go
@@ -71,7 +71,14 @@ func test(t *testing.T, c search.Config) {
 	if err != nil {
 		t.Errorf("failed to search: %+v", err)
 	} else {
-		t.Logf("search: %d: %+v", totalCount, docs)
+		if docsSlice, ok := docs.([]testStruct); ok {
+			t.Logf("search result total_count:%d with %d docs", totalCount, len(docsSlice))
+			if len(docsSlice) > 10 {
+				t.Errorf("got %d docs > max 10", len(docsSlice))
+			}
+		} else {
+			t.Errorf("docs %T is not []testStruct!", docs)
+		}
 	}
 
 	oldList, err := a.DelOldTimeSeries(indexName, 2)
diff --git a/search/time_series.go b/search/time_series.go
index fc004ff..9201356 100644
--- a/search/time_series.go
+++ b/search/time_series.go
@@ -24,7 +24,7 @@ type TimeSeriesHeader struct {
 
 type TimeSeries interface {
 	Write(StartTime time.Time, EndTime time.Time, data interface{}) error
-	Search(limit int) (docs []interface{}, totalCount int, err error)
+	Search(limit int) (docs interface{}, totalCount int, err error)
 }
 
 type timeSeries struct {
@@ -167,9 +167,9 @@ func (w *writer) TimeSeries(name string, tmpl interface{}) (TimeSeries, error) {
 	//define search response type
 	//similar to SearchResponseBody
 	ts.searchResponseBodyType, err = reflection.CloneType(
-		reflect.TypeOf([]reflect.StructField{}),
+		reflect.TypeOf(SearchResponseBody{}),
 		map[string]reflect.Type{
-			".hits.hits[]._slice": ts.dataType,
+			".hits.hits[]._source": ts.dataType,
 		})
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to make search response type for time-series")
@@ -268,7 +268,7 @@ func (w *writer) DelOldTimeSeries(indexName string, olderThanDays int) ([]string
 			logger.Debugf("Ignore index(%s) with invalid date(%s)", dailyIndexName, dateStr)
 		} else {
 			if date.Before(timeThreshold) {
-				logger.Debugf("Deleting index(%s).uuid(%s).docsCount(%d) older than %s days...", dailyIndexName, dailyIndexInfo.Settings.Index.UUID, dailyIndexInfo.Settings.Index.DocsCount, timeThreshold)
+				logger.Debugf("Deleting index(%s).uuid(%s) older than %s days...", dailyIndexName, dailyIndexInfo.Settings.Index.UUID, timeThreshold)
 				indicesToDelete = append(indicesToDelete, dailyIndexName)
 			}
 		}
@@ -295,11 +295,17 @@ type IndexInfoSettings struct {
 }
 
 type IndexSettings struct {
-	UUID      string `json:"uuid"`
-	DocsCount int64  `json:"docs.count"`
+	UUID             string `json:"uuid"`
+	CreationDate     string `json:"creation_date"`
+	NumberOfShards   string `json:"number_of_shards"`
+	NumberOfReplicas string `json:"number_of_replicas"`
+	ProviderName     string `json:"provided_name"` //e.g. "go-utils-audit-test-20211103"
 }
 
-func (ts *timeSeries) Search(limit int) (docs []interface{}, totalCount int, err error) {
+//Search
+//Return:
+//	docs will be a slice of the TimeSeries data type
+func (ts *timeSeries) Search(limit int) (docs interface{}, totalCount int, err error) {
 	if limit > 1000 {
 		err = errors.Errorf("limit=%d > 1000", limit)
 		return
@@ -362,7 +368,7 @@ func (ts *timeSeries) Search(limit int) (docs []interface{}, totalCount int, err
 		err = errors.Wrapf(err, "cannot get search response documents")
 		return
 	}
-	return items.Interface().([]interface{}), hitsTotalValue.Interface().(int), nil
+	return items.Interface(), hitsTotalValue.Interface().(int), nil
 }
 
 type SearchRequestBody struct {
-- 
GitLab