@@ -2,12 +2,9 @@ package mongo
22
33import (
44 "context"
5- "fmt"
65 "time"
76
87 log "github.com/sirupsen/logrus"
9-
10- "go.mongodb.org/mongo-driver/bson"
118)
129
1310const (
@@ -78,200 +75,3 @@ func (c *Connection) CheckConnection(ctx context.Context) bool {
7875 }
7976 return err == nil
8077}
81-
82- type QuoteResult [Q any , R QuoteHashProvider ] struct {
83- Quotes []Q
84- RetainedQuotes []R
85- QuoteHashToIndex map [string ]int
86- Error error
87- }
88-
89- type QuoteQuery struct {
90- Ctx context.Context
91- Conn * Connection
92- StartDate time.Time
93- EndDate time.Time
94- QuoteCollection string
95- RetainedCollection string
96- }
97-
98- func ListQuotesByDateRange [Q any , R QuoteHashProvider ](
99- query QuoteQuery ,
100- mapper func (bson.D ) Q ,
101- ) QuoteResult [Q , R ] {
102- dbCtx , cancel := context .WithTimeout (query .Ctx , query .Conn .timeout )
103- defer cancel ()
104- quotes , quoteHashes , err := fetchQuotesByDateRange (dbCtx , query .Conn , query .StartDate , query .EndDate , query .QuoteCollection , mapper )
105- if err != nil {
106- return QuoteResult [Q , R ]{Error : err }
107- }
108- quoteHashToIndex := make (map [string ]int , len (quoteHashes ))
109- for i , hash := range quoteHashes {
110- if hash != "" {
111- quoteHashToIndex [hash ] = i
112- }
113- }
114- retainedQuotes , additionalHashes , err := fetchRetainedQuotes [R ](dbCtx , query .Conn , query .StartDate , query .EndDate , query .RetainedCollection , quoteHashes )
115- if err != nil {
116- return QuoteResult [Q , R ]{Error : err }
117- }
118- if len (additionalHashes ) > 0 {
119- additionalQuotes , additionalHashIndices , err := fetchAdditionalQuotes (dbCtx , query .Conn , query .QuoteCollection , additionalHashes , mapper )
120- if err != nil {
121- log .Errorf ("Error processing additional quotes: %v" , err )
122- } else {
123- baseIndex := len (quotes )
124- for i , hash := range additionalHashIndices {
125- if hash != "" {
126- quoteHashToIndex [hash ] = baseIndex + i
127- }
128- }
129- quotes = append (quotes , additionalQuotes ... )
130- }
131- }
132- logDbInteraction (Read , fmt .Sprintf ("Found %d quotes and %d retained quotes in date range" ,
133- len (quotes ), len (retainedQuotes )))
134- return QuoteResult [Q , R ]{
135- Quotes : quotes ,
136- RetainedQuotes : retainedQuotes ,
137- QuoteHashToIndex : quoteHashToIndex ,
138- Error : nil ,
139- }
140- }
141-
142- func fetchQuotesByDateRange [Q any ](
143- ctx context.Context ,
144- conn * Connection ,
145- startDate , endDate time.Time ,
146- collectionName string ,
147- mapper func (bson.D ) Q ,
148- ) ([]Q , []string , error ) {
149- quoteFilter := bson.D {
150- {Key : "agreement_timestamp" , Value : bson.D {
151- {Key : "$gte" , Value : startDate .Unix ()},
152- {Key : "$lte" , Value : endDate .Unix ()},
153- }},
154- }
155- var storedQuotes []bson.D
156- quoteCursor , err := conn .Collection (collectionName ).Find (ctx , quoteFilter )
157- if err != nil {
158- return nil , nil , err
159- }
160- if err = quoteCursor .All (ctx , & storedQuotes ); err != nil {
161- return nil , nil , err
162- }
163- quoteHashes := make ([]string , 0 , len (storedQuotes ))
164- quotes := make ([]Q , 0 , len (storedQuotes ))
165- for _ , stored := range storedQuotes {
166- quoteObj := mapper (stored )
167- quotes = append (quotes , quoteObj )
168- hashValue , ok := getStringValueFromBSON (stored , "hash" )
169- if ok {
170- quoteHashes = append (quoteHashes , hashValue )
171- }
172- }
173- return quotes , quoteHashes , nil
174- }
175-
176- func getStringValueFromBSON (doc bson.D , key string ) (string , bool ) {
177- data , err := bson .Marshal (doc )
178- if err != nil {
179- return "" , false
180- }
181- rawValue := bson .Raw (data ).Lookup (key )
182- return rawValue .StringValueOK ()
183- }
184-
185- type QuoteHashProvider interface {
186- GetQuoteHash () string
187- }
188-
189- func fetchRetainedQuotes [R QuoteHashProvider ](
190- ctx context.Context ,
191- conn * Connection ,
192- startDate , endDate time.Time ,
193- collectionName string ,
194- existingQuoteHashes []string ,
195- ) ([]R , []string , error ) {
196- retainedFilter := createRetainedFilter (startDate , endDate , existingQuoteHashes )
197- var retainedQuotes []R
198- retainedCursor , err := conn .Collection (collectionName ).Find (ctx , retainedFilter )
199- if err != nil {
200- return nil , nil , err
201- }
202- if err = retainedCursor .All (ctx , & retainedQuotes ); err != nil {
203- return nil , nil , err
204- }
205- additionalHashes := findAdditionalQuoteHashes (retainedQuotes , existingQuoteHashes )
206- return retainedQuotes , additionalHashes , nil
207- }
208-
209- func createRetainedFilter (startDate , endDate time.Time , quoteHashes []string ) bson.D {
210- return bson.D {
211- {Key : "$or" , Value : bson.A {
212- bson.D {{Key : "quote_hash" , Value : bson.D {
213- {Key : "$in" , Value : quoteHashes },
214- }}},
215- bson.D {
216- {Key : "created_at" , Value : bson.D {
217- {Key : "$gte" , Value : startDate .Unix ()},
218- {Key : "$lte" , Value : endDate .Unix ()},
219- }},
220- },
221- }},
222- }
223- }
224-
225- func findAdditionalQuoteHashes [R QuoteHashProvider ](retainedQuotes []R , existingQuoteHashes []string ) []string {
226- existingMap := make (map [string ]bool , len (existingQuoteHashes ))
227- for _ , hash := range existingQuoteHashes {
228- existingMap [hash ] = true
229- }
230- additionalMap := make (map [string ]bool )
231- for i := range retainedQuotes {
232- hash := retainedQuotes [i ].GetQuoteHash ()
233- if ! existingMap [hash ] {
234- additionalMap [hash ] = true
235- }
236- }
237- additionalHashes := make ([]string , 0 , len (additionalMap ))
238- for hash := range additionalMap {
239- additionalHashes = append (additionalHashes , hash )
240- }
241- return additionalHashes
242- }
243-
244- func fetchAdditionalQuotes [Q any ](
245- ctx context.Context ,
246- conn * Connection ,
247- collectionName string ,
248- hashes []string ,
249- mapper func (bson.D ) Q ,
250- ) ([]Q , []string , error ) {
251- quoteFilter := bson.D {
252- {Key : "hash" , Value : bson.D {
253- {Key : "$in" , Value : hashes },
254- }},
255- }
256- var storedQuotes []bson.D
257- quoteCursor , err := conn .Collection (collectionName ).Find (ctx , quoteFilter )
258- if err != nil {
259- return nil , nil , err
260- }
261- if err = quoteCursor .All (ctx , & storedQuotes ); err != nil {
262- return nil , nil , err
263- }
264- quotes := make ([]Q , 0 , len (storedQuotes ))
265- resultHashes := make ([]string , 0 , len (storedQuotes ))
266- for _ , stored := range storedQuotes {
267- quoteObj := mapper (stored )
268- quotes = append (quotes , quoteObj )
269- hashValue , ok := getStringValueFromBSON (stored , "hash" )
270- if ok {
271- resultHashes = append (resultHashes , hashValue )
272- } else {
273- resultHashes = append (resultHashes , "" )
274- }
275- }
276- return quotes , resultHashes , nil
277- }
0 commit comments