33package nroci
44
55import (
6+ "context"
67 "fmt"
78 "time"
89
10+ "github.com/newrelic/go-agent/v3/newrelic"
911 "github.com/oracle/nosql-go-sdk/nosqldb"
1012)
1113
@@ -58,6 +60,10 @@ type ClientWrapper struct {
5860 Client OCIClient
5961}
6062
63+ type ClientResponseWrapper [T any ] struct {
64+ ClientResponse T
65+ }
66+
6167func NRDefaultConfig () * ConfigWrapper {
6268 cfg := nosqldb.Config {}
6369 return & ConfigWrapper {
@@ -74,3 +80,54 @@ func NRCreateClient(cfg *ConfigWrapper) (*ClientWrapper, error) {
7480 Client : client ,
7581 }, nil
7682}
83+
84+ // executeWithDatastoreSegment is a generic helper function that executes a query with a given function from the
85+ // OCI Client. It takes a type parameter T as any because of the different response types that are used within the
86+ // OCI Client. This function will take the transaction from the context (if it exists) and create a Datastore Segment.
87+ // It will then call whatever client function has been passed in.
88+ func executeWithDatastoreSegment [T any ](
89+ ctx context.Context ,
90+ req * nosqldb.TableRequest ,
91+ fn func () (T , error ),
92+ ) (* ClientResponseWrapper [T ], error ) {
93+
94+ txn := newrelic .FromContext (ctx )
95+ if txn == nil {
96+ return nil , fmt .Errorf ("error executing DoTableRequest, no transaction" )
97+ }
98+
99+ sgmt := newrelic.DatastoreSegment {
100+ StartTime : txn .StartSegmentNow (),
101+ Product : newrelic .DatastoreOracle ,
102+ Collection : req .TableName ,
103+ Operation : req .Namespace ,
104+ DatabaseName : req .Namespace ,
105+ }
106+
107+ responseWrapper := ClientResponseWrapper [T ]{}
108+ res , err := fn () // call the client function
109+ responseWrapper .ClientResponse = res
110+ if err != nil {
111+ return & responseWrapper , fmt .Errorf ("error making request: %s" , err .Error ())
112+ }
113+ // 4. End segment
114+ sgmt .End ()
115+ // 5. Return result
116+ return & responseWrapper , nil
117+ }
118+
119+ // Wrapper for nosqldb.Client.DoTableRequest. Provide the ClientWrapper and Context as parameters in addition to the nosqldbTableRequest.
120+ // Returns a ClientResponseWrapper[*nosqldbTableResult] and error.
121+ func NRDoTableRequest (cw * ClientWrapper , ctx context.Context , req * nosqldb.TableRequest ) (* ClientResponseWrapper [* nosqldb.TableResult ], error ) {
122+ return executeWithDatastoreSegment (ctx , req , func () (* nosqldb.TableResult , error ) {
123+ return cw .Client .DoTableRequest (req )
124+ })
125+ }
126+
127+ // Wrapper for nosqldb.Client.DoTableRequestWait. Provide the ClientWrapper and Context as parameters in addition to the nosqldbTableRequest,
128+ // timeout, and pollInterval. Returns a ClientResponseWrapper[*nosqldbTableResult] and error.
129+ func NRDoTableRequestAndWait (cw * ClientWrapper , ctx context.Context , req * nosqldb.TableRequest , timeout time.Duration , pollInterval time.Duration ) (* ClientResponseWrapper [* nosqldb.TableResult ], error ) {
130+ return executeWithDatastoreSegment (ctx , req , func () (* nosqldb.TableResult , error ) {
131+ return cw .Client .DoTableRequestAndWait (req , timeout , pollInterval )
132+ })
133+ }
0 commit comments