diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2eb4ad810..717f58a3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,6 +83,11 @@ docker pull scylladb/scylla docker run --name scylla -d -p 2025:9042 scylladb/scylla docker pull surrealdb/surrealdb:latest docker run --name surrealdb -d -p 8000:8000 surrealdb/surrealdb:latest start --bind 0.0.0.0:8000 +docker run -d --name arangodb \ + -p 8529:8529 \ + -e ARANGO_ROOT_PASSWORD=rootpassword \ + --pull always \ + arangodb:latest diff --git a/docs/advanced-guide/injecting-databases-drivers/page.md b/docs/advanced-guide/injecting-databases-drivers/page.md index d9550e97a..259b43bf2 100644 --- a/docs/advanced-guide/injecting-databases-drivers/page.md +++ b/docs/advanced-guide/injecting-databases-drivers/page.md @@ -908,11 +908,11 @@ func main() { app.AddSurrealDB(client) // GET request to fetch person by ID - app.GET("/person/{id}", func(ctx *gofr.Context) (interface{}, error) { + app.GET("/person/{id}", func(ctx *gofr.Context) (any, error) { id := ctx.PathParam("id") query := "SELECT * FROM type::thing('person', $id)" - vars := map[string]interface{}{ + vars := map[string]any{ "id": id, } @@ -925,14 +925,14 @@ func main() { }) // POST request to create a new person - app.POST("/person", func(ctx *gofr.Context) (interface{}, error) { + app.POST("/person", func(ctx *gofr.Context) (any, error) { var person Person if err := ctx.Bind(&person); err != nil { return ErrorResponse{Message: "Invalid request body"}, nil } - result, err := ctx.SurrealDB.Create(ctx, "person", map[string]interface{}{ + result, err := ctx.SurrealDB.Create(ctx, "person", map[string]any{ "name": person.Name, "age": person.Age, "email": person.Email, @@ -949,3 +949,188 @@ func main() { } ``` + + +## ArangoDB + +GoFr supports injecting `ArangoDB` that implements the following interface. Any driver that implements the interface can be +added using the `app.AddArangoDB()` method, and users can use ArangoDB across the application with `gofr.Context`. + +```go +type ArangoDB interface { + // CreateDocument creates a new document in the specified collection. + CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) + // GetDocument retrieves a document by its ID from the specified collection. + GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error + // UpdateDocument updates an existing document in the specified collection. + UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error + // DeleteDocument deletes a document by its ID from the specified collection. + DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error + + // GetEdges retrieves all the edge documents connected to a specific vertex in an ArangoDB graph. + GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error + + // Query executes an AQL query and binds the results + Query(ctx context.Context, dbName string, query string, bindVars map[string]any, result any) error + + HealthCheck(context.Context) (any, error) +} +``` + +Users can easily inject a driver that supports this interface, providing usability without compromising the extensibility to use multiple databases. + +Import the GoFr's external driver for ArangoDB: + +```shell +go get gofr.dev/pkg/gofr/datasource/arangodb@latest +``` + +### Example + +```go +package main + +import ( + "fmt" + + "gofr.dev/pkg/gofr" + "gofr.dev/pkg/gofr/datasource/arangodb" +) + +type Person struct { + Name string `json:"name"` + Age int `json:"age"` +} + +func main() { + app := gofr.New() + + // Configure the ArangoDB client + arangoClient := arangodb.New(arangodb.Config{ + Host: "localhost", + User: "root", + Password: "root", + Port: 8529, + }) + app.AddArangoDB(arangoClient) + + // Example routes demonstrating different types of operations + app.POST("/setup", Setup) + app.POST("/users/{name}", CreateUserHandler) + app.POST("/friends", CreateFriendship) + app.GET("/friends/{collection}/{vertexID}", GetEdgesHandler) + + app.Run() +} + +// Setup demonstrates database and collection creation +func Setup(ctx *gofr.Context) (interface{}, error) { + _, err := ctx.ArangoDB.CreateDocument(ctx, "social_network", "", nil) + if err != nil { + return nil, fmt.Errorf("failed to create database: %w", err) + } + + if err := createCollection(ctx, "social_network", "persons"); err != nil { + return nil, err + } + if err := createCollection(ctx, "social_network", "friendships"); err != nil { + return nil, err + } + + // Define and create the graph + edgeDefs := arangodb.EdgeDefinition{ + {Collection: "friendships", From: []string{"persons"}, To: []string{"persons"}}, + } + + _, err = ctx.ArangoDB.CreateDocument(ctx, "social_network", "social_graph", edgeDefs) + if err != nil { + return nil, fmt.Errorf("failed to create graph: %w", err) + } + + return "Setup completed successfully", nil +} + +// Helper function to create collections +func createCollection(ctx *gofr.Context, dbName, collectionName string) error { + _, err := ctx.ArangoDB.CreateDocument(ctx, dbName, collectionName, nil) + if err != nil { + return fmt.Errorf("failed to create collection %s: %w", collectionName, err) + } + return nil +} + +// CreateUserHandler demonstrates user management and document creation +func CreateUserHandler(ctx *gofr.Context) (interface{}, error) { + name := ctx.PathParam("name") + + // Create a person document + person := Person{ + Name: name, + Age: 25, + } + docID, err := ctx.ArangoDB.CreateDocument(ctx, "social_network", "persons", person) + if err != nil { + return nil, fmt.Errorf("failed to create person document: %w", err) + } + + return map[string]string{ + "message": "User created successfully", + "docID": docID, + }, nil +} + +// CreateFriendship demonstrates edge document creation +func CreateFriendship(ctx *gofr.Context) (interface{}, error) { + var req struct { + From string `json:"from"` + To string `json:"to"` + StartDate string `json:"startDate"` + } + + if err := ctx.Bind(&req); err != nil { + return nil, err + } + + edgeDocument := map[string]any{ + "_from": fmt.Sprintf("persons/%s", req.From), + "_to": fmt.Sprintf("persons/%s", req.To), + "startDate": req.StartDate, + } + + // Create an edge document for the friendship + edgeID, err := ctx.ArangoDB.CreateDocument(ctx, "social_network", "friendships", edgeDocument) + if err != nil { + return nil, fmt.Errorf("failed to create friendship: %w", err) + } + + return map[string]string{ + "message": "Friendship created successfully", + "edgeID": edgeID, + }, nil +} + +// GetEdgesHandler demonstrates fetching edges connected to a vertex +func GetEdgesHandler(ctx *gofr.Context) (interface{}, error) { + collection := ctx.PathParam("collection") + vertexID := ctx.PathParam("vertexID") + + fullVertexID := fmt.Sprintf("%s/%s", collection, vertexID) + + // Prepare a slice to hold edge details + edges := make(arangodb.EdgeDetails, 0) + + // Fetch all edges connected to the given vertex + err := ctx.ArangoDB.GetEdges(ctx, "social_network", "social_graph", "friendships", + fullVertexID, &edges) + if err != nil { + return nil, fmt.Errorf("failed to get edges: %w", err) + } + + return map[string]interface{}{ + "vertexID": vertexID, + "edges": edges, + }, nil +} +``` + + diff --git a/pkg/gofr/container/container.go b/pkg/gofr/container/container.go index 1f9d432cc..b46a90875 100644 --- a/pkg/gofr/container/container.go +++ b/pkg/gofr/container/container.go @@ -61,6 +61,7 @@ type Container struct { OpenTSDB OpenTSDB ScyllaDB ScyllaDB SurrealDB SurrealDB + ArangoDB ArangoDB KVStore KVStore diff --git a/pkg/gofr/container/datasources.go b/pkg/gofr/container/datasources.go index 8b75bb042..bb4bd0191 100644 --- a/pkg/gofr/container/datasources.go +++ b/pkg/gofr/container/datasources.go @@ -574,3 +574,29 @@ type ScyllaDBProvider interface { ScyllaDB provider } + +type ArangoDB interface { + // CreateDocument creates a new document in the specified collection. + CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) + // GetDocument retrieves a document by its ID from the specified collection. + GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error + // UpdateDocument updates an existing document in the specified collection. + UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error + // DeleteDocument deletes a document by its ID from the specified collection. + DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error + + // GetEdges retrieves all the edge documents connected to a specific vertex in an ArangoDB graph. + GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error + + // Query executes an AQL query and binds the results + Query(ctx context.Context, dbName string, query string, bindVars map[string]any, result any) error + + HealthChecker +} + +// ArangoDBProvider is an interface that extends ArangoDB with additional methods for logging, metrics, and connection management. +type ArangoDBProvider interface { + ArangoDB + + provider +} diff --git a/pkg/gofr/container/mock_container.go b/pkg/gofr/container/mock_container.go index 8d36eb8c4..c2b04378c 100644 --- a/pkg/gofr/container/mock_container.go +++ b/pkg/gofr/container/mock_container.go @@ -87,6 +87,9 @@ func NewMockContainer(t *testing.T, options ...options) (*Container, *Mocks) { opentsdbMock := NewMockOpenTSDBProvider(ctrl) container.OpenTSDB = opentsdbMock + arangoMock := NewMockArangoDBProvider(ctrl) + container.ArangoDB = arangoMock + var httpMock *service.MockHTTP container.Services = make(map[string]service.HTTP) diff --git a/pkg/gofr/container/mock_datasources.go b/pkg/gofr/container/mock_datasources.go index 06d467705..c3f402321 100644 --- a/pkg/gofr/container/mock_datasources.go +++ b/pkg/gofr/container/mock_datasources.go @@ -9752,6 +9752,282 @@ func (mr *MockMongoProviderMockRecorder) UseTracer(tracer any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseTracer", reflect.TypeOf((*MockMongoProvider)(nil).UseTracer), tracer) } +// MockSurrealDB is a mock of SurrealDB interface. +type MockSurrealDB struct { + ctrl *gomock.Controller + recorder *MockSurrealDBMockRecorder + isgomock struct{} +} + +// MockSurrealDBMockRecorder is the mock recorder for MockSurrealDB. +type MockSurrealDBMockRecorder struct { + mock *MockSurrealDB +} + +// NewMockSurrealDB creates a new mock instance. +func NewMockSurrealDB(ctrl *gomock.Controller) *MockSurrealDB { + mock := &MockSurrealDB{ctrl: ctrl} + mock.recorder = &MockSurrealDBMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSurrealDB) EXPECT() *MockSurrealDBMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockSurrealDB) Create(ctx context.Context, table string, data any) (map[string]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", ctx, table, data) + ret0, _ := ret[0].(map[string]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockSurrealDBMockRecorder) Create(ctx, table, data any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockSurrealDB)(nil).Create), ctx, table, data) +} + +// Delete mocks base method. +func (m *MockSurrealDB) Delete(ctx context.Context, table, id string) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", ctx, table, id) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockSurrealDBMockRecorder) Delete(ctx, table, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSurrealDB)(nil).Delete), ctx, table, id) +} + +// HealthCheck mocks base method. +func (m *MockSurrealDB) HealthCheck(arg0 context.Context) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HealthCheck indicates an expected call of HealthCheck. +func (mr *MockSurrealDBMockRecorder) HealthCheck(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockSurrealDB)(nil).HealthCheck), arg0) +} + +// Query mocks base method. +func (m *MockSurrealDB) Query(ctx context.Context, query string, vars map[string]any) ([]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, query, vars) + ret0, _ := ret[0].([]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockSurrealDBMockRecorder) Query(ctx, query, vars any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockSurrealDB)(nil).Query), ctx, query, vars) +} + +// Select mocks base method. +func (m *MockSurrealDB) Select(ctx context.Context, table string) ([]map[string]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Select", ctx, table) + ret0, _ := ret[0].([]map[string]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Select indicates an expected call of Select. +func (mr *MockSurrealDBMockRecorder) Select(ctx, table any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Select", reflect.TypeOf((*MockSurrealDB)(nil).Select), ctx, table) +} + +// Update mocks base method. +func (m *MockSurrealDB) Update(ctx context.Context, table, id string, data any) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", ctx, table, id, data) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockSurrealDBMockRecorder) Update(ctx, table, id, data any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockSurrealDB)(nil).Update), ctx, table, id, data) +} + +// MockSurrealBDProvider is a mock of SurrealBDProvider interface. +type MockSurrealBDProvider struct { + ctrl *gomock.Controller + recorder *MockSurrealBDProviderMockRecorder + isgomock struct{} +} + +// MockSurrealBDProviderMockRecorder is the mock recorder for MockSurrealBDProvider. +type MockSurrealBDProviderMockRecorder struct { + mock *MockSurrealBDProvider +} + +// NewMockSurrealBDProvider creates a new mock instance. +func NewMockSurrealBDProvider(ctrl *gomock.Controller) *MockSurrealBDProvider { + mock := &MockSurrealBDProvider{ctrl: ctrl} + mock.recorder = &MockSurrealBDProviderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSurrealBDProvider) EXPECT() *MockSurrealBDProviderMockRecorder { + return m.recorder +} + +// Connect mocks base method. +func (m *MockSurrealBDProvider) Connect() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Connect") +} + +// Connect indicates an expected call of Connect. +func (mr *MockSurrealBDProviderMockRecorder) Connect() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockSurrealBDProvider)(nil).Connect)) +} + +// Create mocks base method. +func (m *MockSurrealBDProvider) Create(ctx context.Context, table string, data any) (map[string]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", ctx, table, data) + ret0, _ := ret[0].(map[string]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockSurrealBDProviderMockRecorder) Create(ctx, table, data any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockSurrealBDProvider)(nil).Create), ctx, table, data) +} + +// Delete mocks base method. +func (m *MockSurrealBDProvider) Delete(ctx context.Context, table, id string) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", ctx, table, id) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockSurrealBDProviderMockRecorder) Delete(ctx, table, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSurrealBDProvider)(nil).Delete), ctx, table, id) +} + +// HealthCheck mocks base method. +func (m *MockSurrealBDProvider) HealthCheck(arg0 context.Context) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HealthCheck indicates an expected call of HealthCheck. +func (mr *MockSurrealBDProviderMockRecorder) HealthCheck(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockSurrealBDProvider)(nil).HealthCheck), arg0) +} + +// Query mocks base method. +func (m *MockSurrealBDProvider) Query(ctx context.Context, query string, vars map[string]any) ([]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, query, vars) + ret0, _ := ret[0].([]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockSurrealBDProviderMockRecorder) Query(ctx, query, vars any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockSurrealBDProvider)(nil).Query), ctx, query, vars) +} + +// Select mocks base method. +func (m *MockSurrealBDProvider) Select(ctx context.Context, table string) ([]map[string]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Select", ctx, table) + ret0, _ := ret[0].([]map[string]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Select indicates an expected call of Select. +func (mr *MockSurrealBDProviderMockRecorder) Select(ctx, table any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Select", reflect.TypeOf((*MockSurrealBDProvider)(nil).Select), ctx, table) +} + +// Update mocks base method. +func (m *MockSurrealBDProvider) Update(ctx context.Context, table, id string, data any) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", ctx, table, id, data) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockSurrealBDProviderMockRecorder) Update(ctx, table, id, data any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockSurrealBDProvider)(nil).Update), ctx, table, id, data) +} + +// UseLogger mocks base method. +func (m *MockSurrealBDProvider) UseLogger(logger any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseLogger", logger) +} + +// UseLogger indicates an expected call of UseLogger. +func (mr *MockSurrealBDProviderMockRecorder) UseLogger(logger any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseLogger", reflect.TypeOf((*MockSurrealBDProvider)(nil).UseLogger), logger) +} + +// UseMetrics mocks base method. +func (m *MockSurrealBDProvider) UseMetrics(metrics any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseMetrics", metrics) +} + +// UseMetrics indicates an expected call of UseMetrics. +func (mr *MockSurrealBDProviderMockRecorder) UseMetrics(metrics any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseMetrics", reflect.TypeOf((*MockSurrealBDProvider)(nil).UseMetrics), metrics) +} + +// UseTracer mocks base method. +func (m *MockSurrealBDProvider) UseTracer(tracer any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseTracer", tracer) +} + +// UseTracer indicates an expected call of UseTracer. +func (mr *MockSurrealBDProviderMockRecorder) UseTracer(tracer any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseTracer", reflect.TypeOf((*MockSurrealBDProvider)(nil).UseTracer), tracer) +} + // Mockprovider is a mock of provider interface. type Mockprovider struct { ctrl *gomock.Controller @@ -11755,3 +12031,299 @@ func (mr *MockScyllaDBProviderMockRecorder) UseTracer(tracer any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseTracer", reflect.TypeOf((*MockScyllaDBProvider)(nil).UseTracer), tracer) } + +// MockArangoDB is a mock of ArangoDB interface. +type MockArangoDB struct { + ctrl *gomock.Controller + recorder *MockArangoDBMockRecorder + isgomock struct{} +} + +// MockArangoDBMockRecorder is the mock recorder for MockArangoDB. +type MockArangoDBMockRecorder struct { + mock *MockArangoDB +} + +// NewMockArangoDB creates a new mock instance. +func NewMockArangoDB(ctrl *gomock.Controller) *MockArangoDB { + mock := &MockArangoDB{ctrl: ctrl} + mock.recorder = &MockArangoDBMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockArangoDB) EXPECT() *MockArangoDBMockRecorder { + return m.recorder +} + +// CreateDocument mocks base method. +func (m *MockArangoDB) CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocument", ctx, dbName, collectionName, document) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocument indicates an expected call of CreateDocument. +func (mr *MockArangoDBMockRecorder) CreateDocument(ctx, dbName, collectionName, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocument", reflect.TypeOf((*MockArangoDB)(nil).CreateDocument), ctx, dbName, collectionName, document) +} + +// DeleteDocument mocks base method. +func (m *MockArangoDB) DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocument", ctx, dbName, collectionName, documentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDocument indicates an expected call of DeleteDocument. +func (mr *MockArangoDBMockRecorder) DeleteDocument(ctx, dbName, collectionName, documentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocument", reflect.TypeOf((*MockArangoDB)(nil).DeleteDocument), ctx, dbName, collectionName, documentID) +} + +// GetDocument mocks base method. +func (m *MockArangoDB) GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDocument", ctx, dbName, collectionName, documentID, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetDocument indicates an expected call of GetDocument. +func (mr *MockArangoDBMockRecorder) GetDocument(ctx, dbName, collectionName, documentID, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDocument", reflect.TypeOf((*MockArangoDB)(nil).GetDocument), ctx, dbName, collectionName, documentID, result) +} + +// GetEdges mocks base method. +func (m *MockArangoDB) GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEdges", ctx, dbName, graphName, edgeCollection, vertexID, resp) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetEdges indicates an expected call of GetEdges. +func (mr *MockArangoDBMockRecorder) GetEdges(ctx, dbName, graphName, edgeCollection, vertexID, resp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEdges", reflect.TypeOf((*MockArangoDB)(nil).GetEdges), ctx, dbName, graphName, edgeCollection, vertexID, resp) +} + +// HealthCheck mocks base method. +func (m *MockArangoDB) HealthCheck(arg0 context.Context) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HealthCheck indicates an expected call of HealthCheck. +func (mr *MockArangoDBMockRecorder) HealthCheck(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockArangoDB)(nil).HealthCheck), arg0) +} + +// Query mocks base method. +func (m *MockArangoDB) Query(ctx context.Context, dbName, query string, bindVars map[string]any, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, dbName, query, bindVars, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// Query indicates an expected call of Query. +func (mr *MockArangoDBMockRecorder) Query(ctx, dbName, query, bindVars, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockArangoDB)(nil).Query), ctx, dbName, query, bindVars, result) +} + +// UpdateDocument mocks base method. +func (m *MockArangoDB) UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocument", ctx, dbName, collectionName, documentID, document) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateDocument indicates an expected call of UpdateDocument. +func (mr *MockArangoDBMockRecorder) UpdateDocument(ctx, dbName, collectionName, documentID, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocument", reflect.TypeOf((*MockArangoDB)(nil).UpdateDocument), ctx, dbName, collectionName, documentID, document) +} + +// MockArangoDBProvider is a mock of ArangoDBProvider interface. +type MockArangoDBProvider struct { + ctrl *gomock.Controller + recorder *MockArangoDBProviderMockRecorder + isgomock struct{} +} + +// MockArangoDBProviderMockRecorder is the mock recorder for MockArangoDBProvider. +type MockArangoDBProviderMockRecorder struct { + mock *MockArangoDBProvider +} + +// NewMockArangoDBProvider creates a new mock instance. +func NewMockArangoDBProvider(ctrl *gomock.Controller) *MockArangoDBProvider { + mock := &MockArangoDBProvider{ctrl: ctrl} + mock.recorder = &MockArangoDBProviderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockArangoDBProvider) EXPECT() *MockArangoDBProviderMockRecorder { + return m.recorder +} + +// Connect mocks base method. +func (m *MockArangoDBProvider) Connect() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Connect") +} + +// Connect indicates an expected call of Connect. +func (mr *MockArangoDBProviderMockRecorder) Connect() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockArangoDBProvider)(nil).Connect)) +} + +// CreateDocument mocks base method. +func (m *MockArangoDBProvider) CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocument", ctx, dbName, collectionName, document) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocument indicates an expected call of CreateDocument. +func (mr *MockArangoDBProviderMockRecorder) CreateDocument(ctx, dbName, collectionName, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocument", reflect.TypeOf((*MockArangoDBProvider)(nil).CreateDocument), ctx, dbName, collectionName, document) +} + +// DeleteDocument mocks base method. +func (m *MockArangoDBProvider) DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocument", ctx, dbName, collectionName, documentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDocument indicates an expected call of DeleteDocument. +func (mr *MockArangoDBProviderMockRecorder) DeleteDocument(ctx, dbName, collectionName, documentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocument", reflect.TypeOf((*MockArangoDBProvider)(nil).DeleteDocument), ctx, dbName, collectionName, documentID) +} + +// GetDocument mocks base method. +func (m *MockArangoDBProvider) GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDocument", ctx, dbName, collectionName, documentID, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetDocument indicates an expected call of GetDocument. +func (mr *MockArangoDBProviderMockRecorder) GetDocument(ctx, dbName, collectionName, documentID, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDocument", reflect.TypeOf((*MockArangoDBProvider)(nil).GetDocument), ctx, dbName, collectionName, documentID, result) +} + +// GetEdges mocks base method. +func (m *MockArangoDBProvider) GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEdges", ctx, dbName, graphName, edgeCollection, vertexID, resp) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetEdges indicates an expected call of GetEdges. +func (mr *MockArangoDBProviderMockRecorder) GetEdges(ctx, dbName, graphName, edgeCollection, vertexID, resp any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEdges", reflect.TypeOf((*MockArangoDBProvider)(nil).GetEdges), ctx, dbName, graphName, edgeCollection, vertexID, resp) +} + +// HealthCheck mocks base method. +func (m *MockArangoDBProvider) HealthCheck(arg0 context.Context) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HealthCheck indicates an expected call of HealthCheck. +func (mr *MockArangoDBProviderMockRecorder) HealthCheck(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockArangoDBProvider)(nil).HealthCheck), arg0) +} + +// Query mocks base method. +func (m *MockArangoDBProvider) Query(ctx context.Context, dbName, query string, bindVars map[string]any, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, dbName, query, bindVars, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// Query indicates an expected call of Query. +func (mr *MockArangoDBProviderMockRecorder) Query(ctx, dbName, query, bindVars, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockArangoDBProvider)(nil).Query), ctx, dbName, query, bindVars, result) +} + +// UpdateDocument mocks base method. +func (m *MockArangoDBProvider) UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocument", ctx, dbName, collectionName, documentID, document) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateDocument indicates an expected call of UpdateDocument. +func (mr *MockArangoDBProviderMockRecorder) UpdateDocument(ctx, dbName, collectionName, documentID, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocument", reflect.TypeOf((*MockArangoDBProvider)(nil).UpdateDocument), ctx, dbName, collectionName, documentID, document) +} + +// UseLogger mocks base method. +func (m *MockArangoDBProvider) UseLogger(logger any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseLogger", logger) +} + +// UseLogger indicates an expected call of UseLogger. +func (mr *MockArangoDBProviderMockRecorder) UseLogger(logger any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseLogger", reflect.TypeOf((*MockArangoDBProvider)(nil).UseLogger), logger) +} + +// UseMetrics mocks base method. +func (m *MockArangoDBProvider) UseMetrics(metrics any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseMetrics", metrics) +} + +// UseMetrics indicates an expected call of UseMetrics. +func (mr *MockArangoDBProviderMockRecorder) UseMetrics(metrics any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseMetrics", reflect.TypeOf((*MockArangoDBProvider)(nil).UseMetrics), metrics) +} + +// UseTracer mocks base method. +func (m *MockArangoDBProvider) UseTracer(tracer any) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "UseTracer", tracer) +} + +// UseTracer indicates an expected call of UseTracer. +func (mr *MockArangoDBProviderMockRecorder) UseTracer(tracer any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UseTracer", reflect.TypeOf((*MockArangoDBProvider)(nil).UseTracer), tracer) +} diff --git a/pkg/gofr/datasource/README.md b/pkg/gofr/datasource/README.md index dc9938cd8..75593d929 100644 --- a/pkg/gofr/datasource/README.md +++ b/pkg/gofr/datasource/README.md @@ -71,18 +71,19 @@ Therefore, GoFr utilizes a pluggable approach for new datasources by separating | Datasource | Health-Check | Logs | Metrics | Traces | As Driver | |------------------|:------------:|:----:|:-------:|:------:|:---------:| -| MySQL | ✅ | ✅ | ✅ | ✅ | | -| REDIS | ✅ | ✅ | ✅ | ✅ | | -| PostgreSQL | ✅ | ✅ | ✅ | ✅ | | -| MongoDB | ✅ | ✅ | ✅ | ✅ | ✅ | -| SQLite | ✅ | ✅ | ✅ | ✅ | | -| BadgerDB | ✅ | ✅ | ✅ | ✅ | ✅ | -| Cassandra | ✅ | ✅ | ✅ | ✅ | ✅ | -| ClickHouse | | ✅ | ✅ | ✅ | ✅ | -| FTP | | ✅ | | | ✅ | -| SFTP | | ✅ | | | ✅ | -| Solr | | ✅ | ✅ | ✅ | ✅ | -| DGraph | ✅ | ✅ | ✅ | ✅ | | -| Azure Event Hubs | | ✅ | ✅ | |✅ | -| OpenTSDB | ✅ | ✅ | | ✅ | ✅ | -| SurrealDB | ✅ | ✅ | | ✅ | ✅ | \ No newline at end of file +| MySQL | ✅ | ✅ | ✅ | ✅ | | +| REDIS | ✅ | ✅ | ✅ | ✅ | | +| PostgreSQL | ✅ | ✅ | ✅ | ✅ | | +| MongoDB | ✅ | ✅ | ✅ | ✅ | ✅ | +| SQLite | ✅ | ✅ | ✅ | ✅ | | +| BadgerDB | ✅ | ✅ | ✅ | ✅ | ✅ | +| Cassandra | ✅ | ✅ | ✅ | ✅ | ✅ | +| ClickHouse | | ✅ | ✅ | ✅ | ✅ | +| FTP | | ✅ | | | ✅ | +| SFTP | | ✅ | | | ✅ | +| Solr | | ✅ | ✅ | ✅ | ✅ | +| DGraph | ✅ | ✅ | ✅ | ✅ | | +| Azure Event Hubs | | ✅ | ✅ | |✅ | +| OpenTSDB | ✅ | ✅ | | ✅ | ✅ | +| SurrealDB | ✅ | ✅ | | ✅ | ✅ | +| ArangoDB | ✅| ✅ | ✅| ✅|✅| \ No newline at end of file diff --git a/pkg/gofr/datasource/arangodb/arango.go b/pkg/gofr/datasource/arangodb/arango.go new file mode 100644 index 000000000..fe8985a04 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango.go @@ -0,0 +1,263 @@ +package arangodb + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/arangodb/go-driver/v2/arangodb" + arangoShared "github.com/arangodb/go-driver/v2/arangodb/shared" + "github.com/arangodb/go-driver/v2/connection" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +const ( + defaultTimeout = 5 * time.Second + arangoEdgeCollectionType = 3 +) + +// Client represents an ArangoDB client. +type Client struct { + client arangodb.Client + logger Logger + metrics Metrics + tracer trace.Tracer + config *Config + endpoint string + *Document + *Graph +} + +type EdgeDefinition []arangodb.EdgeDefinition + +type UserOptions struct { + Password string `json:"passwd,omitempty"` + Active *bool `json:"active,omitempty"` + Extra any `json:"extra,omitempty"` +} + +// Config holds the configuration for ArangoDB connection. +type Config struct { + Host string + User string + Password string + Port int +} + +var ( + errStatusDown = errors.New("status down") + errMissingField = errors.New("missing required field in config") + errInvalidResultType = errors.New("result must be a pointer to a slice of maps") + errInvalidUserOptionsType = errors.New("userOptions must be a *UserOptions type") +) + +// New creates a new ArangoDB client with the provided configuration. +func New(c Config) *Client { + client := &Client{ + config: &c, + } + + client.Document = &Document{client: client} + client.Graph = &Graph{client: client} + + return client +} + +// UseLogger sets the logger for the ArangoDB client. +func (c *Client) UseLogger(logger any) { + if l, ok := logger.(Logger); ok { + c.logger = l + } +} + +// UseMetrics sets the metrics for the ArangoDB client. +func (c *Client) UseMetrics(metrics any) { + if m, ok := metrics.(Metrics); ok { + c.metrics = m + } +} + +// UseTracer sets the tracer for the ArangoDB client. +func (c *Client) UseTracer(tracer any) { + if t, ok := tracer.(trace.Tracer); ok { + c.tracer = t + } +} + +// Connect establishes a connection to the ArangoDB server. +func (c *Client) Connect() { + if err := c.validateConfig(); err != nil { + c.logger.Errorf("config validation error: %v", err) + return + } + + c.endpoint = fmt.Sprintf("http://%s:%d", c.config.Host, c.config.Port) + c.logger.Debugf("connecting to ArangoDB at %s", c.endpoint) + + // Use HTTP connection instead of HTTP2 + endpoint := connection.NewRoundRobinEndpoints([]string{c.endpoint}) + conn := connection.NewHttpConnection(connection.HttpConfiguration{Endpoint: endpoint}) + + // Set authentication + auth := connection.NewBasicAuth(c.config.User, c.config.Password) + if err := conn.SetAuthentication(auth); err != nil { + c.logger.Errorf("authentication setup failed: %v", err) + return + } + + // Create ArangoDB client + client := arangodb.NewClient(conn) + c.client = client + + // Test connection by fetching server version + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + _, err := c.client.Version(ctx) + if err != nil { + c.logger.Errorf("failed to verify connection: %v", err) + return + } + + // Initialize metrics + arangoBuckets := []float64{.05, .075, .1, .125, .15, .2, .3, .5, .75, 1, 2, 3, 4, 5, 7.5, 10} + c.metrics.NewHistogram("app_arango_stats", "Response time of ArangoDB operations in milliseconds.", arangoBuckets...) + + c.logger.Logf("Connected to ArangoDB successfully at %s", c.endpoint) +} + +func (c *Client) validateConfig() error { + if c.config.Host == "" { + return fmt.Errorf("%w: host is empty", errMissingField) + } + + if c.config.Port == 0 { + return fmt.Errorf("%w: port is empty", errMissingField) + } + + if c.config.User == "" { + return fmt.Errorf("%w: user is empty", errMissingField) + } + + if c.config.Password == "" { + return fmt.Errorf("%w: password is empty", errMissingField) + } + + return nil +} + +// Query executes an AQL query and binds the results. +func (c *Client) Query(ctx context.Context, dbName, query string, bindVars map[string]any, result any) error { + tracerCtx, span := c.addTrace(ctx, "query", map[string]string{"DB": dbName}) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{Operation: "query", + Database: dbName, Query: query}, startTime, "query", span) + + db, err := c.client.Database(tracerCtx, dbName) + if err != nil { + return err + } + + cursor, err := db.Query(tracerCtx, query, &arangodb.QueryOptions{BindVars: bindVars}) + if err != nil { + return err + } + + defer cursor.Close() + + resultSlice, ok := result.(*[]map[string]any) + if !ok { + return errInvalidResultType + } + + for { + var doc map[string]any + + _, err = cursor.ReadDocument(tracerCtx, &doc) + if arangoShared.IsNoMoreDocuments(err) { + break + } + + if err != nil { + return err + } + + *resultSlice = append(*resultSlice, doc) + } + + return nil +} + +// addTrace adds tracing to context if tracer is configured. +func (c *Client) addTrace(ctx context.Context, operation string, attributes map[string]string) (context.Context, trace.Span) { + if c.tracer != nil { + contextWithTrace, span := c.tracer.Start(ctx, fmt.Sprintf("arangodb-%v", operation)) + + // Add default attributes + span.SetAttributes(attribute.String("arangodb.operation", operation)) + + // Add custom attributes if provided + for key, value := range attributes { + span.SetAttributes(attribute.String(fmt.Sprintf("arangodb.%s", key), value)) + } + + return contextWithTrace, span + } + + return ctx, nil +} + +func (c *Client) sendOperationStats(ql *QueryLog, startTime time.Time, method string, span trace.Span) { + duration := time.Since(startTime).Microseconds() + ql.Duration = duration + + c.logger.Debug(ql) + + c.metrics.RecordHistogram(context.Background(), "app_arango_stats", float64(duration), + "endpoint", c.endpoint, + "type", ql.Query, + ) + + if span != nil { + defer span.End() + span.SetAttributes(attribute.Int64(fmt.Sprintf("arangodb.%v.duration", method), duration)) + } +} + +// Health represents the health status of ArangoDB. +type Health struct { + Status string `json:"status,omitempty"` + Details map[string]any `json:"details,omitempty"` +} + +// HealthCheck performs a health check. +func (c *Client) HealthCheck(ctx context.Context) (any, error) { + h := Health{ + Details: map[string]any{ + "endpoint": c.endpoint, + }, + } + + version, err := c.client.Version(ctx) + if err != nil { + h.Status = "DOWN" + return &h, errStatusDown + } + + h.Status = "UP" + h.Details["version"] = version.Version + h.Details["server"] = version.Server + + return &h, nil +} + +func (uo *UserOptions) toArangoUserOptions() *arangodb.UserOptions { + return &arangodb.UserOptions{ + Password: uo.Password, + Active: uo.Active, + Extra: uo.Extra, + } +} diff --git a/pkg/gofr/datasource/arangodb/arango_document.go b/pkg/gofr/datasource/arangodb/arango_document.go new file mode 100644 index 000000000..02728ac4b --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_document.go @@ -0,0 +1,190 @@ +package arangodb + +import ( + "context" + "errors" + "time" + + "github.com/arangodb/go-driver/v2/arangodb" +) + +var ( + errInvalidEdgeDocumentType = errors.New("document must be a map when creating an edge") + errMissingEdgeFields = errors.New("missing '_from' or '_to' field for edge document") + errInvalidFromField = errors.New("'_from' field must be a string") + errInvalidToField = errors.New("'_to' field must be a string") +) + +type Document struct { + client *Client +} + +// CreateDocument creates a new document in the specified collection. +// If the collection is an edge collection, the document must include `_from` and `_to`. +// Example for creating a regular document: +// +// doc := map[string]any{ +// "name": "Alice", +// "age": 30, +// } +// +// id, err := client.CreateDocument(ctx, "myDB", "users", doc) +// +// Example for creating an edge document: +// +// edgeDoc := map[string]any{ +// "_from": "users/123", +// "_to": "orders/456", +// "relation": "purchased", +// } +// +// id, err := client.CreateDocument(ctx, "myDB", "edges", edgeDoc). +func (d *Document) CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) { + collection, tracerCtx, err := executeCollectionOperation(ctx, *d, dbName, collectionName, + "createDocument", "") + if err != nil { + return "", err + } + + var isEdge bool + + // Check if the collection is an edge collection + isEdge, err = d.isEdgeCollection(ctx, dbName, collectionName) + if err != nil { + return "", err + } + + // Validate edge document if needed + if isEdge { + err = validateEdgeDocument(document) + if err != nil { + return "", err + } + } + + // Create the document in ArangoDB + meta, err := collection.CreateDocument(tracerCtx, document) + if err != nil { + return "", err + } + + return meta.Key, nil +} + +// GetDocument retrieves a document by its ID from the specified collection. +func (d *Document) GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error { + collection, tracerCtx, err := executeCollectionOperation(ctx, *d, dbName, collectionName, + "getDocument", documentID) + if err != nil { + return err + } + + _, err = collection.ReadDocument(tracerCtx, documentID, result) + + return err +} + +// UpdateDocument updates an existing document in the specified collection. +func (d *Document) UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error { + collection, tracerCtx, err := executeCollectionOperation(ctx, *d, dbName, collectionName, + "updateDocument", documentID) + if err != nil { + return err + } + + _, err = collection.UpdateDocument(tracerCtx, documentID, document) + + return err +} + +// DeleteDocument deletes a document by its ID from the specified collection. +func (d *Document) DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error { + collection, tracerCtx, err := executeCollectionOperation(ctx, *d, dbName, collectionName, + "deleteDocument", documentID) + if err != nil { + return err + } + + _, err = collection.DeleteDocument(tracerCtx, documentID) + + return err +} + +// isEdgeCollection checks if the given collection is an edge collection. +func (d *Document) isEdgeCollection(ctx context.Context, dbName, collectionName string) (bool, error) { + collection, err := d.getCollection(ctx, dbName, collectionName) + if err != nil { + return false, err + } + + properties, err := collection.Properties(ctx) + if err != nil { + return false, err + } + + // ArangoDB type: 3 = Edge Collection, 2 = Document Collection + return properties.Type == arangoEdgeCollectionType, nil +} + +func executeCollectionOperation(ctx context.Context, d Document, dbName, collectionName, + operation string, documentID string) (arangodb.Collection, context.Context, error) { + tracerCtx, span := d.client.addTrace(ctx, operation, map[string]string{"collection": collectionName}) + startTime := time.Now() + + ql := &QueryLog{Operation: operation, + Database: dbName, + Collection: collectionName} + + if documentID != "" { + ql.ID = documentID + } + + defer d.client.sendOperationStats(ql, startTime, operation, span) + + collection, err := d.getCollection(tracerCtx, dbName, collectionName) + if err != nil { + return nil, nil, err + } + + return collection, tracerCtx, nil +} + +// validateEdgeDocument ensures the document contains valid `_from` and `_to` fields when creating an edge. +func validateEdgeDocument(document any) error { + docMap, ok := document.(map[string]any) + if !ok { + return errInvalidEdgeDocumentType + } + + from, fromExists := docMap["_from"] + to, toExists := docMap["_to"] + + if !fromExists || !toExists { + return errMissingEdgeFields + } + + // Ensure `_from` and `_to` are strings + if _, ok := from.(string); !ok { + return errInvalidFromField + } + + if _, ok := to.(string); !ok { + return errInvalidToField + } + + return nil +} + +func (d *Document) getCollection(ctx context.Context, dbName, collectionName string) (arangodb.Collection, error) { + db, err := d.client.client.Database(ctx, dbName) + if err != nil { + return nil, err + } + + collection, err := db.Collection(ctx, collectionName) + if err != nil { + return nil, err + } + + return collection, nil +} diff --git a/pkg/gofr/datasource/arangodb/arango_document_test.go b/pkg/gofr/datasource/arangodb/arango_document_test.go new file mode 100644 index 000000000..d677e9e97 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_document_test.go @@ -0,0 +1,254 @@ +package arangodb + +import ( + "context" + "testing" + + "github.com/arangodb/go-driver/v2/arangodb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func Test_Client_CreateDocument(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil).AnyTimes() + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil).AnyTimes() + mockCollection.EXPECT().Properties(gomock.Any()).Return(arangodb.CollectionProperties{}, nil) + mockCollection.EXPECT().CreateDocument(gomock.Any(), "testDocument"). + Return(arangodb.CollectionDocumentCreateResponse{DocumentMeta: arangodb.DocumentMeta{ + Key: "testDocument", ID: "1"}}, nil) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + docName, err := client.CreateDocument(context.Background(), "testDB", + "testCollection", "testDocument") + require.Equal(t, "testDocument", docName) + require.NoError(t, err, "Expected no error while truncating the collection") +} + +func Test_Client_CreateDocument_Error(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil).AnyTimes() + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil).AnyTimes() + mockCollection.EXPECT().Properties(gomock.Any()).Return(arangodb.CollectionProperties{}, nil) + mockCollection.EXPECT().CreateDocument(gomock.Any(), "testDocument"). + Return(arangodb.CollectionDocumentCreateResponse{}, errDocumentNotFound) + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) + + docName, err := client.CreateDocument(context.Background(), "testDB", + "testCollection", "testDocument") + require.Equal(t, "", docName) + require.ErrorIs(t, err, errDocumentNotFound, err, "Expected error when document not found") +} + +func Test_Client_GetDocument(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().ReadDocument(gomock.Any(), "testDocument", "").Return(arangodb.DocumentMeta{ + Key: "testKey", ID: "1"}, nil) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.GetDocument(context.Background(), "testDB", + "testCollection", "testDocument", "") + require.NoError(t, err, "Expected no error while reading the document") +} + +func Test_Client_GetDocument_Error(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().ReadDocument(gomock.Any(), "testDocument", ""). + Return(arangodb.DocumentMeta{}, errDocumentNotFound) + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) + + err := client.GetDocument(context.Background(), "testDB", + "testCollection", "testDocument", "") + require.ErrorIs(t, err, errDocumentNotFound, err, "Expected error when document not found") +} + +func Test_Client_UpdateDocument(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + testDocument := map[string]any{"field": "value"} + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().UpdateDocument(gomock.Any(), "testDocument", testDocument). + Return(arangodb.CollectionDocumentUpdateResponse{ + DocumentMeta: arangodb.DocumentMeta{Key: "testKey", ID: "1", Rev: ""}}, nil) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.UpdateDocument(context.Background(), "testDB", "testCollection", + "testDocument", testDocument) + require.NoError(t, err, "Expected no error while updating the document") +} + +func Test_Client_UpdateDocument_Error(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + testDocument := map[string]any{"field": "value"} + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().UpdateDocument(gomock.Any(), "testDocument", testDocument). + Return(arangodb.CollectionDocumentUpdateResponse{}, errDocumentNotFound) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.UpdateDocument(context.Background(), "testDB", "testCollection", "testDocument", testDocument) + require.ErrorIs(t, err, errDocumentNotFound, "Expected error while updating the document") +} + +func Test_Client_DeleteDocument(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().DeleteDocument(gomock.Any(), "testDocument"). + Return(arangodb.CollectionDocumentDeleteResponse{ + DocumentMeta: arangodb.DocumentMeta{Key: "testKey", ID: "1", Rev: ""}}, nil) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.DeleteDocument(context.Background(), "testDB", "testCollection", + "testDocument") + require.NoError(t, err, "Expected no error while updating the document") +} + +func Test_Client_DeleteDocument_Error(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + mockDB := NewMockDatabase(gomock.NewController(t)) + mockCollection := NewMockCollection(gomock.NewController(t)) + + mockArango.EXPECT().Database(gomock.Any(), "testDB").Return(mockDB, nil) + mockDB.EXPECT().Collection(gomock.Any(), "testCollection").Return(mockCollection, nil) + mockCollection.EXPECT().DeleteDocument(gomock.Any(), "testDocument"). + Return(arangodb.CollectionDocumentDeleteResponse{}, errDocumentNotFound) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.DeleteDocument(context.Background(), "testDB", "testCollection", + "testDocument") + require.ErrorIs(t, err, errDocumentNotFound, "Expected error while updating the document") +} + +func TestExecuteCollectionOperation(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockLogger := NewMockLogger(ctrl) + mockMetrics := NewMockMetrics(ctrl) + mockArango := NewMockArango(ctrl) + mockDatabase := NewMockDatabase(ctrl) + mockCollection := NewMockCollection(ctrl) + + client := New(Config{Host: "localhost", Port: 8527, User: "root", Password: "root"}) + client.UseLogger(mockLogger) + client.UseMetrics(mockMetrics) + + client.client = mockArango + d := Document{client: client} + + ctx := context.Background() + dbName := "testDB" + collectionName := "testCollection" + operation := "createDocument" + documentID := "doc123" + + mockArango.EXPECT().Database(ctx, dbName).Return(mockDatabase, nil) + mockDatabase.EXPECT().Collection(ctx, collectionName).Return(mockCollection, nil) + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram(ctx, "app_arango_stats", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) + + _, _, err := executeCollectionOperation(ctx, d, dbName, collectionName, operation, documentID) + require.NoError(t, err) +} + +func TestValidateEdgeDocument(t *testing.T) { + tests := []struct { + name string + document any + expectedError error + }{ + { + name: "Success - Valid Edge Document", + document: map[string]any{ + "_from": "vertex1", + "_to": "vertex2", + }, + expectedError: nil, + }, + { + name: "Fail - Document is Not a Map", + document: "invalid", + expectedError: errInvalidEdgeDocumentType, + }, + { + name: "Fail - Missing _from Field", + document: map[string]any{ + "_to": "vertex2", + }, + expectedError: errMissingEdgeFields, + }, + { + name: "Fail - Missing _to Field", + document: map[string]any{ + "_from": "vertex1", + }, + expectedError: errMissingEdgeFields, + }, + { + name: "Fail - _from is Not a String", + document: map[string]any{ + "_from": 123, + "_to": "vertex2", + }, + expectedError: errInvalidFromField, + }, + { + name: "Fail - _to is Not a String", + document: map[string]any{ + "_from": "vertex1", + "_to": 123, + }, + expectedError: errInvalidToField, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := validateEdgeDocument(tc.document) + assert.Equal(t, tc.expectedError, err) + }) + } +} diff --git a/pkg/gofr/datasource/arangodb/arango_graph.go b/pkg/gofr/datasource/arangodb/arango_graph.go new file mode 100644 index 000000000..e9da26d9e --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_graph.go @@ -0,0 +1,71 @@ +package arangodb + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/arangodb/go-driver/v2/arangodb" +) + +var ( + errInvalidInput = errors.New("invalid input parameter") + errInvalidResponseType = errors.New("invalid response type") +) + +type EdgeDetails []arangodb.EdgeDetails + +type Graph struct { + client *Client +} + +// GetEdges fetches all edges connected to a given vertex in the specified edge collection. +// +// Parameters: +// - ctx: Request context for tracing and cancellation. +// - dbName: Database name. +// - graphName: Graph name. +// - edgeCollection: Edge collection name. +// - vertexID: Full vertex ID (e.g., "persons/16563"). +// - resp: Pointer to `*EdgeDetails` to store results. +// +// Returns an error if input is invalid, `resp` is of the wrong type, or the query fails. +func (c *Client) GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, + resp any) error { + if vertexID == "" || edgeCollection == "" { + return errInvalidInput + } + + // Type check the response parameter + edgeResp, ok := resp.(*EdgeDetails) + if !ok { + return fmt.Errorf("%w: must be *[]arangodb.EdgeDetails", errInvalidResponseType) + } + + tracerCtx, span := c.addTrace(ctx, "getEdges", map[string]string{ + "DB": dbName, "Graph": graphName, "Collection": edgeCollection, "Vertex": vertexID, + }) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{ + Operation: "getEdges", + Database: dbName, + Collection: edgeCollection, + }, startTime, "getEdges", span) + + db, err := c.client.Database(tracerCtx, dbName) + if err != nil { + return err + } + + edges, err := db.GetEdges(tracerCtx, edgeCollection, vertexID, nil) + if err != nil { + return err + } + + // Assign the result to the provided response parameter + *edgeResp = edges + + return nil +} diff --git a/pkg/gofr/datasource/arangodb/arango_helper.go b/pkg/gofr/datasource/arangodb/arango_helper.go new file mode 100644 index 000000000..9cb101148 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_helper.go @@ -0,0 +1,99 @@ +package arangodb + +import ( + "context" + "fmt" + "time" + + "github.com/arangodb/go-driver/v2/arangodb" +) + +func (c *Client) user(ctx context.Context, username string) (arangodb.User, error) { + return c.client.User(ctx, username) +} + +func (c *Client) database(ctx context.Context, name string) (arangodb.Database, error) { + return c.client.Database(ctx, name) +} + +func (c *Client) databases(ctx context.Context) ([]arangodb.Database, error) { + return c.client.Databases(ctx) +} + +func (c *Client) version(ctx context.Context) (arangodb.VersionInfo, error) { + return c.client.Version(ctx) +} + +// createUser creates a new user in ArangoDB. +func (c *Client) createUser(ctx context.Context, username string, options any) error { + tracerCtx, span := c.addTrace(ctx, "createUser", map[string]string{"user": username}) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{Operation: "createUser", ID: username}, + startTime, "createUser", span) + + userOptions, ok := options.(UserOptions) + if !ok { + return fmt.Errorf("%w", errInvalidUserOptionsType) + } + + _, err := c.client.CreateUser(tracerCtx, username, userOptions.toArangoUserOptions()) + if err != nil { + return err + } + + return nil +} + +// dropUser deletes a user from ArangoDB. +func (c *Client) dropUser(ctx context.Context, username string) error { + tracerCtx, span := c.addTrace(ctx, "dropUser", map[string]string{"user": username}) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{Operation: "dropUser", + ID: username}, startTime, "dropUser", span) + + err := c.client.RemoveUser(tracerCtx, username) + if err != nil { + return err + } + + return err +} + +// grantDB grants permissions for a database to a user. +func (c *Client) grantDB(ctx context.Context, database, username, permission string) error { + tracerCtx, span := c.addTrace(ctx, "grantDB", map[string]string{"DB": database}) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{Operation: "grantDB", + Database: database, ID: username}, startTime, "grantDB", span) + + user, err := c.client.User(tracerCtx, username) + if err != nil { + return err + } + + err = user.SetDatabaseAccess(tracerCtx, database, arangodb.Grant(permission)) + + return err +} + +// grantCollection grants permissions for a collection to a user. +func (c *Client) grantCollection(ctx context.Context, database, collection, username, permission string) error { + tracerCtx, span := c.addTrace(ctx, "GrantCollection", map[string]string{"collection": collection}) + startTime := time.Now() + + defer c.sendOperationStats(&QueryLog{Operation: "GrantCollection", + Database: database, Collection: collection, ID: username}, startTime, + "GrantCollection", span) + + user, err := c.client.User(tracerCtx, username) + if err != nil { + return err + } + + err = user.SetCollectionAccess(tracerCtx, database, collection, arangodb.Grant(permission)) + + return err +} diff --git a/pkg/gofr/datasource/arangodb/arango_helper_test.go b/pkg/gofr/datasource/arangodb/arango_helper_test.go new file mode 100644 index 000000000..44581fe15 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_helper_test.go @@ -0,0 +1,239 @@ +package arangodb + +import ( + "context" + "testing" + + "github.com/arangodb/go-driver/v2/arangodb" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel" + "go.uber.org/mock/gomock" +) + +func Test_Client_CreateUser(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + + mockArango.EXPECT().AddUser(gomock.Any(), "test", &arangodb.UserOptions{Password: "user123"}). + Return(nil, nil) + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram(context.Background(), "app_arango_stats", + gomock.Any(), "endpoint", gomock.Any(), gomock.Any(), gomock.Any()) + + err := client.createUser(context.Background(), "test", UserOptions{ + Password: "user123", + Extra: nil, + }) + require.NoError(t, err, "Test_Arango_CreateUser: failed to create user") +} + +func Test_Client_DropUser(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + + // Ensure the mock returns nil as an error type + mockArango.EXPECT().DropUser(gomock.Any(), "test").Return(nil) + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram(context.Background(), "app_arango_stats", gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) + + err := client.dropUser(context.Background(), "test") + require.NoError(t, err, "Test_Arango_DropUser: failed to drop user") +} + +func Test_Client_GrantDB(t *testing.T) { + client, mockArango, mockUser, mockLogger, mockMetrics := setupDB(t) + + // Test data + ctx := context.Background() + dbName := "testDB" + username := "testUser" + + // Expectations + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram( + ctx, "app_arango_stats", gomock.Any(), "endpoint", + gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + // Expect user() call and return our mock user that implements the full interface + mockArango.EXPECT().User(gomock.Any(), username).Return(mockUser, nil).MaxTimes(2) + + // Test cases + testCases := []struct { + name string + dbName string + username string + permission string + expectErr bool + }{ + { + name: "Valid grant read-write", + dbName: dbName, + username: username, + permission: string(arangodb.GrantReadWrite), + expectErr: false, + }, + { + name: "Valid grant read-only", + dbName: dbName, + username: username, + permission: string(arangodb.GrantReadOnly), + expectErr: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := client.grantDB(ctx, tc.dbName, tc.username, tc.permission) + if tc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_Client_GrantDB_Errors(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + + ctx := context.Background() + dbName := "testDB" + username := "testUser" + + // Expect user() call to return error + mockArango.EXPECT().User(gomock.Any(), username).Return(nil, errUserNotFound) + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram(ctx, "app_arango_stats", gomock.Any(), "endpoint", + gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + err := client.grantDB(ctx, dbName, username, string(arangodb.GrantReadWrite)) + require.Error(t, err) +} + +func TestUser(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockArango := NewMockArango(ctrl) + mockUser := NewMockUser(ctrl) + client := &Client{client: mockArango} + + ctx := context.Background() + username := "testUser" + + t.Run("Successful user fetch", func(t *testing.T) { + mockArango.EXPECT(). + User(ctx, username). + Return(mockUser, nil) + + user, err := client.user(ctx, username) + require.NoError(t, err) + require.NotNil(t, user) + }) + + t.Run("user fetch error", func(t *testing.T) { + mockArango.EXPECT(). + User(ctx, username). + Return(nil, errUserNotFound) + + user, err := client.user(ctx, username) + require.Error(t, err) + require.Nil(t, user) + }) +} + +func TestClient_Database(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockLogger := NewMockLogger(ctrl) + mockMetrics := NewMockMetrics(ctrl) + mockArango := NewMockArango(ctrl) + + config := Config{Host: "localhost", Port: 8527, User: "root", Password: "root"} + client := New(config) + client.UseLogger(mockLogger) + client.UseMetrics(mockMetrics) + client.UseTracer(otel.GetTracerProvider().Tracer("gofr-arangodb")) + + client.client = mockArango + + mockDatabase := NewMockDatabase(gomock.NewController(t)) + + ctx := context.Background() + dbName := "testDB" + + t.Run("Get database Success", func(t *testing.T) { + mockArango.EXPECT(). + Database(ctx, dbName). + Return(mockDatabase, nil) + mockDatabase.EXPECT().Name().Return(dbName) + + db, err := client.database(ctx, dbName) + require.NoError(t, err) + require.NotNil(t, db) + require.Equal(t, dbName, db.Name()) + }) + + t.Run("Get database Error", func(t *testing.T) { + mockArango.EXPECT(). + Database(ctx, dbName). + Return(nil, errDBNotFound) + + db, err := client.database(ctx, dbName) + require.Error(t, err) + require.Nil(t, db) + }) + + // Test database operations + t.Run("database Operations", func(t *testing.T) { + mockArango.EXPECT(). + Database(ctx, dbName). + Return(mockDatabase, nil) + mockDatabase.EXPECT().Name().Return(dbName) + mockDatabase.EXPECT().Remove(ctx).Return(nil) + mockDatabase.EXPECT().Collection(ctx, "testCollection").Return(nil, nil) + + db, err := client.database(ctx, dbName) + require.NoError(t, err) + require.Equal(t, dbName, db.Name()) + + err = db.Remove(ctx) + require.NoError(t, err) + + coll, err := db.Collection(ctx, "testCollection") + require.NoError(t, err) + require.Nil(t, coll) + }) +} + +func Test_Client_GrantCollection(t *testing.T) { + client, mockArango, mockUser, mockLogger, mockMetrics := setupDB(t) + + mockLogger.EXPECT().Debug(gomock.Any()) + mockMetrics.EXPECT().RecordHistogram( + context.Background(), "app_arango_stats", gomock.Any(), "endpoint", + gomock.Any(), gomock.Any(), gomock.Any()) + + mockArango.EXPECT().User(gomock.Any(), "testUser").Return(mockUser, nil) + + err := client.grantCollection(context.Background(), "testDB", "testCollection", + "testUser", string(arangodb.GrantReadOnly)) + + require.NoError(t, err) +} + +func Test_Client_GrantCollection_Error(t *testing.T) { + client, mockArango, _, mockLogger, mockMetrics := setupDB(t) + + mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() + mockMetrics.EXPECT().RecordHistogram( + context.Background(), "app_arango_stats", gomock.Any(), "endpoint", + gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + mockArango.EXPECT().User(gomock.Any(), "testUser").Return(nil, errUserNotFound) + + err := client.grantCollection(context.Background(), "testDB", "testCollection", + "testUser", string(arangodb.GrantReadOnly)) + + require.ErrorIs(t, errUserNotFound, err, "Expected error when user not found") +} diff --git a/pkg/gofr/datasource/arangodb/arango_test.go b/pkg/gofr/datasource/arangodb/arango_test.go new file mode 100644 index 000000000..0c8c2b7c3 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/arango_test.go @@ -0,0 +1,132 @@ +package arangodb + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel" + "go.uber.org/mock/gomock" +) + +var ( + errUserNotFound = errors.New("user not found") + errDBNotFound = errors.New("database not found") + errDocumentNotFound = errors.New("document not found") +) + +func setupDB(t *testing.T) (*Client, *MockArango, *MockUser, *MockLogger, *MockMetrics) { + t.Helper() + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // Setup + mockLogger := NewMockLogger(ctrl) + mockMetrics := NewMockMetrics(ctrl) + mockArango := NewMockArango(ctrl) + mockUser := NewMockUser(ctrl) + + config := Config{Host: "localhost", Port: 8527, User: "root", Password: "root"} + client := New(config) + client.UseLogger(mockLogger) + client.UseMetrics(mockMetrics) + client.UseTracer(otel.GetTracerProvider().Tracer("gofr-arangodb")) + + client.client = mockArango + + return client, mockArango, mockUser, mockLogger, mockMetrics +} + +func Test_NewArangoClient_Error(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + metrics := NewMockMetrics(ctrl) + logger := NewMockLogger(ctrl) + + logger.EXPECT().Errorf("failed to verify connection: %v", gomock.Any()) + logger.EXPECT().Debugf(gomock.Any(), gomock.Any()) + + client := New(Config{Host: "localhost", Port: 8529, Password: "root", User: "admin"}) + + client.UseLogger(logger) + client.UseMetrics(metrics) + client.Connect() + + require.NotNil(t, client) +} + +func TestValidateConfig(t *testing.T) { + testCases := []struct { + name string + config Config + expectErr bool + errMsg string + }{ + { + name: "Valid config", + config: Config{ + Host: "localhost", + Port: 8529, + User: "root", + Password: "password", + }, + expectErr: false, + }, + { + name: "Empty host", + config: Config{ + Port: 8529, + User: "root", + Password: "password", + }, + expectErr: true, + errMsg: "missing required field in config: host is empty", + }, + { + name: "Empty port", + config: Config{ + Host: "localhost", + User: "root", + Password: "password", + }, + expectErr: true, + errMsg: "missing required field in config: port is empty", + }, + { + name: "Empty user", + config: Config{ + Host: "localhost", + Port: 8529, + Password: "password", + }, + expectErr: true, + errMsg: "missing required field in config: user is empty", + }, + { + name: "Empty password", + config: Config{ + Host: "localhost", + Port: 8529, + User: "root", + }, + expectErr: true, + errMsg: "missing required field in config: password is empty", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + client := &Client{config: &tc.config} + err := client.validateConfig() + + if tc.expectErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/gofr/datasource/arangodb/go.mod b/pkg/gofr/datasource/arangodb/go.mod new file mode 100644 index 000000000..e0eb14123 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/go.mod @@ -0,0 +1,32 @@ +module gofr.dev/pkg/gofr/datasource/arangodb + +go 1.23.4 + +require ( + github.com/arangodb/go-driver/v2 v2.1.2 + github.com/stretchr/testify v1.10.0 + go.opentelemetry.io/otel v1.34.0 + go.opentelemetry.io/otel/trace v1.34.0 + go.uber.org/mock v0.5.0 +) + +require ( + github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dchest/siphash v1.2.3 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/kkdai/maglev v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/zerolog v1.33.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/pkg/gofr/datasource/arangodb/go.sum b/pkg/gofr/datasource/arangodb/go.sum new file mode 100644 index 000000000..f5f91c8d7 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/go.sum @@ -0,0 +1,71 @@ +github.com/arangodb/go-driver/v2 v2.1.2 h1:3dxx97pjcJPajw4hnHJMXRz2bY/KizUj/ZrlAVEx10Q= +github.com/arangodb/go-driver/v2 v2.1.2/go.mod h1:POYSylTzBPej3qEouU3dSyfdVfo3WxawaRwzhA9mbJ4= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kkdai/maglev v0.2.0 h1:w6DCW0kAA6fstZqXkrBrlgIC3jeIRXkjOYea/m6EK/Y= +github.com/kkdai/maglev v0.2.0/go.mod h1:d+mt8Lmt3uqi9aRb/BnPjzD0fy+ETs1vVXiGRnqHVZ4= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/gofr/datasource/arangodb/interface.go b/pkg/gofr/datasource/arangodb/interface.go new file mode 100644 index 000000000..ed8d9695a --- /dev/null +++ b/pkg/gofr/datasource/arangodb/interface.go @@ -0,0 +1,29 @@ +package arangodb + +import ( + "context" + + "github.com/arangodb/go-driver/v2/arangodb" +) + +type ArangoDB interface { + Connect() + + user(ctx context.Context, username string) (arangodb.User, error) + database(ctx context.Context, name string) (arangodb.Database, error) + databases(ctx context.Context) ([]arangodb.Database, error) + version(ctx context.Context) (arangodb.VersionInfo, error) + + CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) + GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error + UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error + DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error + + // GetEdges retrieves all the edge documents connected to a specific vertex in an ArangoDB graph. + GetEdges(ctx context.Context, dbName, graphName, edgeCollection, vertexID string, resp any) error + + // Query operations + Query(ctx context.Context, dbName string, query string, bindVars map[string]any, result any) error + + HealthCheck(ctx context.Context) (any, error) +} diff --git a/pkg/gofr/datasource/arangodb/logger.go b/pkg/gofr/datasource/arangodb/logger.go new file mode 100644 index 000000000..145174703 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/logger.go @@ -0,0 +1,47 @@ +package arangodb + +import ( + "fmt" + "io" + "regexp" + "strings" +) + +type Logger interface { + Debug(args ...any) + Debugf(pattern string, args ...any) + Logf(pattern string, args ...any) + Errorf(pattern string, args ...any) +} + +type QueryLog struct { + Query string `json:"query"` + Duration int64 `json:"duration"` + Database string `json:"database,omitempty"` + Collection string `json:"collection,omitempty"` + Filter any `json:"filter,omitempty"` + ID any `json:"id,omitempty"` + Operation string `json:"operation,omitempty"` +} + +// PrettyPrint formats the QueryLog for output. +func (ql *QueryLog) PrettyPrint(writer io.Writer) { + if ql.Filter == nil { + ql.Filter = "" + } + + if ql.ID == nil { + ql.ID = "" + } + + fmt.Fprintf(writer, "\u001B[38;5;8m%-32s \u001B[38;5;206m%-6s\u001B[0m %8d\u001B[38;5;8mµs\u001B[0m %s %s\n", + clean(ql.Operation), "ARANGODB", ql.Duration, + clean(strings.Join([]string{ql.Database, ql.Collection, fmt.Sprint(ql.Filter), fmt.Sprint(ql.ID)}, " ")), clean(ql.Query)) +} + +func clean(query string) string { + // Replace multiple consecutive whitespace characters with a single space + query = regexp.MustCompile(`\s+`).ReplaceAllString(query, " ") + // Trim leading and trailing whitespace from the string + return strings.TrimSpace(query) +} diff --git a/pkg/gofr/datasource/arangodb/logger_test.go b/pkg/gofr/datasource/arangodb/logger_test.go new file mode 100644 index 000000000..8bfba6827 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/logger_test.go @@ -0,0 +1,27 @@ +package arangodb + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_PrettyPrint(t *testing.T) { + queryLog := QueryLog{ + Query: "", + Duration: 12345, + Database: "test", + Collection: "test", + Filter: true, + ID: "12345", + Operation: "getDocument", + } + expected := "getDocument" + + var buf bytes.Buffer + + queryLog.PrettyPrint(&buf) + + assert.Contains(t, buf.String(), expected) +} diff --git a/pkg/gofr/datasource/arangodb/metrics.go b/pkg/gofr/datasource/arangodb/metrics.go new file mode 100644 index 000000000..868d30f89 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/metrics.go @@ -0,0 +1,9 @@ +package arangodb + +import "context" + +// Metrics defines the interface for capturing metrics. +type Metrics interface { + NewHistogram(name, desc string, buckets ...float64) + RecordHistogram(ctx context.Context, name string, value float64, labels ...string) +} diff --git a/pkg/gofr/datasource/arangodb/mock_collection.go b/pkg/gofr/datasource/arangodb/mock_collection.go new file mode 100644 index 000000000..3a53ce518 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_collection.go @@ -0,0 +1,670 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: collection.go +// +// Generated by this command: +// +// mockgen -source=collection.go -destination=./mock_collection.go -package=arangodb +// + +// Package arangodb is a generated GoMock package. +package arangodb + +import ( + context "context" + reflect "reflect" + + arangodb "github.com/arangodb/go-driver/v2/arangodb" + gomock "go.uber.org/mock/gomock" +) + +// MockCollection is a mock of Collection interface. +type MockCollection struct { + ctrl *gomock.Controller + recorder *MockCollectionMockRecorder +} + +// MockCollectionMockRecorder is the mock recorder for MockCollection. +type MockCollectionMockRecorder struct { + mock *MockCollection +} + +// NewMockCollection creates a new mock instance. +func NewMockCollection(ctrl *gomock.Controller) *MockCollection { + mock := &MockCollection{ctrl: ctrl} + mock.recorder = &MockCollectionMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCollection) EXPECT() *MockCollectionMockRecorder { + return m.recorder +} + +// Count mocks base method. +func (m *MockCollection) Count(ctx context.Context) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Count", ctx) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Count indicates an expected call of Count. +func (mr *MockCollectionMockRecorder) Count(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockCollection)(nil).Count), ctx) +} + +// CreateDocument mocks base method. +func (m *MockCollection) CreateDocument(ctx context.Context, document any) (arangodb.CollectionDocumentCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocument", ctx, document) + ret0, _ := ret[0].(arangodb.CollectionDocumentCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocument indicates an expected call of CreateDocument. +func (mr *MockCollectionMockRecorder) CreateDocument(ctx, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocument", reflect.TypeOf((*MockCollection)(nil).CreateDocument), ctx, document) +} + +// CreateDocumentWithOptions mocks base method. +func (m *MockCollection) CreateDocumentWithOptions(ctx context.Context, document any, options *arangodb.CollectionDocumentCreateOptions) (arangodb.CollectionDocumentCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocumentWithOptions", ctx, document, options) + ret0, _ := ret[0].(arangodb.CollectionDocumentCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocumentWithOptions indicates an expected call of CreateDocumentWithOptions. +func (mr *MockCollectionMockRecorder) CreateDocumentWithOptions(ctx, document, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocumentWithOptions", reflect.TypeOf((*MockCollection)(nil).CreateDocumentWithOptions), ctx, document, options) +} + +// CreateDocuments mocks base method. +func (m *MockCollection) CreateDocuments(ctx context.Context, documents any) (arangodb.CollectionDocumentCreateResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocuments", ctx, documents) + ret0, _ := ret[0].(arangodb.CollectionDocumentCreateResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocuments indicates an expected call of CreateDocuments. +func (mr *MockCollectionMockRecorder) CreateDocuments(ctx, documents any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocuments", reflect.TypeOf((*MockCollection)(nil).CreateDocuments), ctx, documents) +} + +// CreateDocumentsWithOptions mocks base method. +func (m *MockCollection) CreateDocumentsWithOptions(ctx context.Context, documents any, opts *arangodb.CollectionDocumentCreateOptions) (arangodb.CollectionDocumentCreateResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocumentsWithOptions", ctx, documents, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentCreateResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocumentsWithOptions indicates an expected call of CreateDocumentsWithOptions. +func (mr *MockCollectionMockRecorder) CreateDocumentsWithOptions(ctx, documents, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocumentsWithOptions", reflect.TypeOf((*MockCollection)(nil).CreateDocumentsWithOptions), ctx, documents, opts) +} + +// Database mocks base method. +func (m *MockCollection) Database() arangodb.Database { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "database") + ret0, _ := ret[0].(arangodb.Database) + return ret0 +} + +// Database indicates an expected call of Database. +func (mr *MockCollectionMockRecorder) Database() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "database", reflect.TypeOf((*MockCollection)(nil).Database)) +} + +// DeleteDocument mocks base method. +func (m *MockCollection) DeleteDocument(ctx context.Context, key string) (arangodb.CollectionDocumentDeleteResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocument", ctx, key) + ret0, _ := ret[0].(arangodb.CollectionDocumentDeleteResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteDocument indicates an expected call of DeleteDocument. +func (mr *MockCollectionMockRecorder) DeleteDocument(ctx, key any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocument", reflect.TypeOf((*MockCollection)(nil).DeleteDocument), ctx, key) +} + +// DeleteDocumentWithOptions mocks base method. +func (m *MockCollection) DeleteDocumentWithOptions(ctx context.Context, key string, opts *arangodb.CollectionDocumentDeleteOptions) (arangodb.CollectionDocumentDeleteResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocumentWithOptions", ctx, key, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentDeleteResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteDocumentWithOptions indicates an expected call of DeleteDocumentWithOptions. +func (mr *MockCollectionMockRecorder) DeleteDocumentWithOptions(ctx, key, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocumentWithOptions", reflect.TypeOf((*MockCollection)(nil).DeleteDocumentWithOptions), ctx, key, opts) +} + +// DeleteDocuments mocks base method. +func (m *MockCollection) DeleteDocuments(ctx context.Context, keys []string) (arangodb.CollectionDocumentDeleteResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocuments", ctx, keys) + ret0, _ := ret[0].(arangodb.CollectionDocumentDeleteResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteDocuments indicates an expected call of DeleteDocuments. +func (mr *MockCollectionMockRecorder) DeleteDocuments(ctx, keys any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocuments", reflect.TypeOf((*MockCollection)(nil).DeleteDocuments), ctx, keys) +} + +// DeleteDocumentsWithOptions mocks base method. +func (m *MockCollection) DeleteDocumentsWithOptions(ctx context.Context, documents any, opts *arangodb.CollectionDocumentDeleteOptions) (arangodb.CollectionDocumentDeleteResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocumentsWithOptions", ctx, documents, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentDeleteResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteDocumentsWithOptions indicates an expected call of DeleteDocumentsWithOptions. +func (mr *MockCollectionMockRecorder) DeleteDocumentsWithOptions(ctx, documents, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocumentsWithOptions", reflect.TypeOf((*MockCollection)(nil).DeleteDocumentsWithOptions), ctx, documents, opts) +} + +// DeleteIndex mocks base method. +func (m *MockCollection) DeleteIndex(ctx context.Context, name string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteIndex", ctx, name) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteIndex indicates an expected call of DeleteIndex. +func (mr *MockCollectionMockRecorder) DeleteIndex(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteIndex", reflect.TypeOf((*MockCollection)(nil).DeleteIndex), ctx, name) +} + +// DeleteIndexByID mocks base method. +func (m *MockCollection) DeleteIndexByID(ctx context.Context, id string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteIndexByID", ctx, id) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteIndexByID indicates an expected call of DeleteIndexByID. +func (mr *MockCollectionMockRecorder) DeleteIndexByID(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteIndexByID", reflect.TypeOf((*MockCollection)(nil).DeleteIndexByID), ctx, id) +} + +// DocumentExists mocks base method. +func (m *MockCollection) DocumentExists(ctx context.Context, key string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DocumentExists", ctx, key) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DocumentExists indicates an expected call of DocumentExists. +func (mr *MockCollectionMockRecorder) DocumentExists(ctx, key any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DocumentExists", reflect.TypeOf((*MockCollection)(nil).DocumentExists), ctx, key) +} + +// EnsureGeoIndex mocks base method. +func (m *MockCollection) EnsureGeoIndex(ctx context.Context, fields []string, options *arangodb.CreateGeoIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureGeoIndex", ctx, fields, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureGeoIndex indicates an expected call of EnsureGeoIndex. +func (mr *MockCollectionMockRecorder) EnsureGeoIndex(ctx, fields, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureGeoIndex", reflect.TypeOf((*MockCollection)(nil).EnsureGeoIndex), ctx, fields, options) +} + +// EnsureInvertedIndex mocks base method. +func (m *MockCollection) EnsureInvertedIndex(ctx context.Context, options *arangodb.InvertedIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureInvertedIndex", ctx, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureInvertedIndex indicates an expected call of EnsureInvertedIndex. +func (mr *MockCollectionMockRecorder) EnsureInvertedIndex(ctx, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureInvertedIndex", reflect.TypeOf((*MockCollection)(nil).EnsureInvertedIndex), ctx, options) +} + +// EnsureMDIIndex mocks base method. +func (m *MockCollection) EnsureMDIIndex(ctx context.Context, fields []string, options *arangodb.CreateMDIIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureMDIIndex", ctx, fields, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureMDIIndex indicates an expected call of EnsureMDIIndex. +func (mr *MockCollectionMockRecorder) EnsureMDIIndex(ctx, fields, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureMDIIndex", reflect.TypeOf((*MockCollection)(nil).EnsureMDIIndex), ctx, fields, options) +} + +// EnsureMDIPrefixedIndex mocks base method. +func (m *MockCollection) EnsureMDIPrefixedIndex(ctx context.Context, fields []string, options *arangodb.CreateMDIPrefixedIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureMDIPrefixedIndex", ctx, fields, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureMDIPrefixedIndex indicates an expected call of EnsureMDIPrefixedIndex. +func (mr *MockCollectionMockRecorder) EnsureMDIPrefixedIndex(ctx, fields, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureMDIPrefixedIndex", reflect.TypeOf((*MockCollection)(nil).EnsureMDIPrefixedIndex), ctx, fields, options) +} + +// EnsurePersistentIndex mocks base method. +func (m *MockCollection) EnsurePersistentIndex(ctx context.Context, fields []string, options *arangodb.CreatePersistentIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsurePersistentIndex", ctx, fields, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsurePersistentIndex indicates an expected call of EnsurePersistentIndex. +func (mr *MockCollectionMockRecorder) EnsurePersistentIndex(ctx, fields, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsurePersistentIndex", reflect.TypeOf((*MockCollection)(nil).EnsurePersistentIndex), ctx, fields, options) +} + +// EnsureTTLIndex mocks base method. +func (m *MockCollection) EnsureTTLIndex(ctx context.Context, fields []string, expireAfter int, options *arangodb.CreateTTLIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureTTLIndex", ctx, fields, expireAfter, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureTTLIndex indicates an expected call of EnsureTTLIndex. +func (mr *MockCollectionMockRecorder) EnsureTTLIndex(ctx, fields, expireAfter, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureTTLIndex", reflect.TypeOf((*MockCollection)(nil).EnsureTTLIndex), ctx, fields, expireAfter, options) +} + +// EnsureZKDIndex mocks base method. +func (m *MockCollection) EnsureZKDIndex(ctx context.Context, fields []string, options *arangodb.CreateZKDIndexOptions) (arangodb.IndexResponse, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureZKDIndex", ctx, fields, options) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureZKDIndex indicates an expected call of EnsureZKDIndex. +func (mr *MockCollectionMockRecorder) EnsureZKDIndex(ctx, fields, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureZKDIndex", reflect.TypeOf((*MockCollection)(nil).EnsureZKDIndex), ctx, fields, options) +} + +// Index mocks base method. +func (m *MockCollection) Index(ctx context.Context, name string) (arangodb.IndexResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Index", ctx, name) + ret0, _ := ret[0].(arangodb.IndexResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Index indicates an expected call of Index. +func (mr *MockCollectionMockRecorder) Index(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index", reflect.TypeOf((*MockCollection)(nil).Index), ctx, name) +} + +// IndexExists mocks base method. +func (m *MockCollection) IndexExists(ctx context.Context, name string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IndexExists", ctx, name) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IndexExists indicates an expected call of IndexExists. +func (mr *MockCollectionMockRecorder) IndexExists(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexExists", reflect.TypeOf((*MockCollection)(nil).IndexExists), ctx, name) +} + +// Indexes mocks base method. +func (m *MockCollection) Indexes(ctx context.Context) ([]arangodb.IndexResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Indexes", ctx) + ret0, _ := ret[0].([]arangodb.IndexResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Indexes indicates an expected call of Indexes. +func (mr *MockCollectionMockRecorder) Indexes(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Indexes", reflect.TypeOf((*MockCollection)(nil).Indexes), ctx) +} + +// Name mocks base method. +func (m *MockCollection) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockCollectionMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockCollection)(nil).Name)) +} + +// Properties mocks base method. +func (m *MockCollection) Properties(ctx context.Context) (arangodb.CollectionProperties, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Properties", ctx) + ret0, _ := ret[0].(arangodb.CollectionProperties) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Properties indicates an expected call of Properties. +func (mr *MockCollectionMockRecorder) Properties(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Properties", reflect.TypeOf((*MockCollection)(nil).Properties), ctx) +} + +// ReadDocument mocks base method. +func (m *MockCollection) ReadDocument(ctx context.Context, key string, result any) (arangodb.DocumentMeta, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadDocument", ctx, key, result) + ret0, _ := ret[0].(arangodb.DocumentMeta) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadDocument indicates an expected call of ReadDocument. +func (mr *MockCollectionMockRecorder) ReadDocument(ctx, key, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDocument", reflect.TypeOf((*MockCollection)(nil).ReadDocument), ctx, key, result) +} + +// ReadDocumentWithOptions mocks base method. +func (m *MockCollection) ReadDocumentWithOptions(ctx context.Context, key string, result any, opts *arangodb.CollectionDocumentReadOptions) (arangodb.DocumentMeta, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadDocumentWithOptions", ctx, key, result, opts) + ret0, _ := ret[0].(arangodb.DocumentMeta) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadDocumentWithOptions indicates an expected call of ReadDocumentWithOptions. +func (mr *MockCollectionMockRecorder) ReadDocumentWithOptions(ctx, key, result, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDocumentWithOptions", reflect.TypeOf((*MockCollection)(nil).ReadDocumentWithOptions), ctx, key, result, opts) +} + +// ReadDocuments mocks base method. +func (m *MockCollection) ReadDocuments(ctx context.Context, keys []string) (arangodb.CollectionDocumentReadResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadDocuments", ctx, keys) + ret0, _ := ret[0].(arangodb.CollectionDocumentReadResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadDocuments indicates an expected call of ReadDocuments. +func (mr *MockCollectionMockRecorder) ReadDocuments(ctx, keys any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDocuments", reflect.TypeOf((*MockCollection)(nil).ReadDocuments), ctx, keys) +} + +// ReadDocumentsWithOptions mocks base method. +func (m *MockCollection) ReadDocumentsWithOptions(ctx context.Context, documents any, opts *arangodb.CollectionDocumentReadOptions) (arangodb.CollectionDocumentReadResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadDocumentsWithOptions", ctx, documents, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentReadResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReadDocumentsWithOptions indicates an expected call of ReadDocumentsWithOptions. +func (mr *MockCollectionMockRecorder) ReadDocumentsWithOptions(ctx, documents, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDocumentsWithOptions", reflect.TypeOf((*MockCollection)(nil).ReadDocumentsWithOptions), ctx, documents, opts) +} + +// Remove mocks base method. +func (m *MockCollection) Remove(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remove", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Remove indicates an expected call of Remove. +func (mr *MockCollectionMockRecorder) Remove(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockCollection)(nil).Remove), ctx) +} + +// RemoveWithOptions mocks base method. +func (m *MockCollection) RemoveWithOptions(ctx context.Context, opts *arangodb.RemoveCollectionOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveWithOptions", ctx, opts) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveWithOptions indicates an expected call of RemoveWithOptions. +func (mr *MockCollectionMockRecorder) RemoveWithOptions(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveWithOptions", reflect.TypeOf((*MockCollection)(nil).RemoveWithOptions), ctx, opts) +} + +// ReplaceDocument mocks base method. +func (m *MockCollection) ReplaceDocument(ctx context.Context, key string, document any) (arangodb.CollectionDocumentReplaceResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceDocument", ctx, key, document) + ret0, _ := ret[0].(arangodb.CollectionDocumentReplaceResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplaceDocument indicates an expected call of ReplaceDocument. +func (mr *MockCollectionMockRecorder) ReplaceDocument(ctx, key, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceDocument", reflect.TypeOf((*MockCollection)(nil).ReplaceDocument), ctx, key, document) +} + +// ReplaceDocumentWithOptions mocks base method. +func (m *MockCollection) ReplaceDocumentWithOptions(ctx context.Context, key string, document any, options *arangodb.CollectionDocumentReplaceOptions) (arangodb.CollectionDocumentReplaceResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceDocumentWithOptions", ctx, key, document, options) + ret0, _ := ret[0].(arangodb.CollectionDocumentReplaceResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplaceDocumentWithOptions indicates an expected call of ReplaceDocumentWithOptions. +func (mr *MockCollectionMockRecorder) ReplaceDocumentWithOptions(ctx, key, document, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceDocumentWithOptions", reflect.TypeOf((*MockCollection)(nil).ReplaceDocumentWithOptions), ctx, key, document, options) +} + +// ReplaceDocuments mocks base method. +func (m *MockCollection) ReplaceDocuments(ctx context.Context, documents any) (arangodb.CollectionDocumentReplaceResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceDocuments", ctx, documents) + ret0, _ := ret[0].(arangodb.CollectionDocumentReplaceResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplaceDocuments indicates an expected call of ReplaceDocuments. +func (mr *MockCollectionMockRecorder) ReplaceDocuments(ctx, documents any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceDocuments", reflect.TypeOf((*MockCollection)(nil).ReplaceDocuments), ctx, documents) +} + +// ReplaceDocumentsWithOptions mocks base method. +func (m *MockCollection) ReplaceDocumentsWithOptions(ctx context.Context, documents any, opts *arangodb.CollectionDocumentReplaceOptions) (arangodb.CollectionDocumentReplaceResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceDocumentsWithOptions", ctx, documents, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentReplaceResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplaceDocumentsWithOptions indicates an expected call of ReplaceDocumentsWithOptions. +func (mr *MockCollectionMockRecorder) ReplaceDocumentsWithOptions(ctx, documents, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceDocumentsWithOptions", reflect.TypeOf((*MockCollection)(nil).ReplaceDocumentsWithOptions), ctx, documents, opts) +} + +// SetProperties mocks base method. +func (m *MockCollection) SetProperties(ctx context.Context, options arangodb.SetCollectionPropertiesOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetProperties", ctx, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetProperties indicates an expected call of SetProperties. +func (mr *MockCollectionMockRecorder) SetProperties(ctx, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProperties", reflect.TypeOf((*MockCollection)(nil).SetProperties), ctx, options) +} + +// Shards mocks base method. +func (m *MockCollection) Shards(ctx context.Context, details bool) (arangodb.CollectionShards, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Shards", ctx, details) + ret0, _ := ret[0].(arangodb.CollectionShards) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Shards indicates an expected call of Shards. +func (mr *MockCollectionMockRecorder) Shards(ctx, details any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shards", reflect.TypeOf((*MockCollection)(nil).Shards), ctx, details) +} + +// Truncate mocks base method. +func (m *MockCollection) Truncate(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Truncate", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Truncate indicates an expected call of Truncate. +func (mr *MockCollectionMockRecorder) Truncate(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Truncate", reflect.TypeOf((*MockCollection)(nil).Truncate), ctx) +} + +// UpdateDocument mocks base method. +func (m *MockCollection) UpdateDocument(ctx context.Context, key string, document any) (arangodb.CollectionDocumentUpdateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocument", ctx, key, document) + ret0, _ := ret[0].(arangodb.CollectionDocumentUpdateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateDocument indicates an expected call of UpdateDocument. +func (mr *MockCollectionMockRecorder) UpdateDocument(ctx, key, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocument", reflect.TypeOf((*MockCollection)(nil).UpdateDocument), ctx, key, document) +} + +// UpdateDocumentWithOptions mocks base method. +func (m *MockCollection) UpdateDocumentWithOptions(ctx context.Context, key string, document any, options *arangodb.CollectionDocumentUpdateOptions) (arangodb.CollectionDocumentUpdateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocumentWithOptions", ctx, key, document, options) + ret0, _ := ret[0].(arangodb.CollectionDocumentUpdateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateDocumentWithOptions indicates an expected call of UpdateDocumentWithOptions. +func (mr *MockCollectionMockRecorder) UpdateDocumentWithOptions(ctx, key, document, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocumentWithOptions", reflect.TypeOf((*MockCollection)(nil).UpdateDocumentWithOptions), ctx, key, document, options) +} + +// UpdateDocuments mocks base method. +func (m *MockCollection) UpdateDocuments(ctx context.Context, documents any) (arangodb.CollectionDocumentUpdateResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocuments", ctx, documents) + ret0, _ := ret[0].(arangodb.CollectionDocumentUpdateResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateDocuments indicates an expected call of UpdateDocuments. +func (mr *MockCollectionMockRecorder) UpdateDocuments(ctx, documents any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocuments", reflect.TypeOf((*MockCollection)(nil).UpdateDocuments), ctx, documents) +} + +// UpdateDocumentsWithOptions mocks base method. +func (m *MockCollection) UpdateDocumentsWithOptions(ctx context.Context, documents any, opts *arangodb.CollectionDocumentUpdateOptions) (arangodb.CollectionDocumentUpdateResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocumentsWithOptions", ctx, documents, opts) + ret0, _ := ret[0].(arangodb.CollectionDocumentUpdateResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateDocumentsWithOptions indicates an expected call of UpdateDocumentsWithOptions. +func (mr *MockCollectionMockRecorder) UpdateDocumentsWithOptions(ctx, documents, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocumentsWithOptions", reflect.TypeOf((*MockCollection)(nil).UpdateDocumentsWithOptions), ctx, documents, opts) +} diff --git a/pkg/gofr/datasource/arangodb/mock_database.go b/pkg/gofr/datasource/arangodb/mock_database.go new file mode 100644 index 000000000..1693d8cc5 --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_database.go @@ -0,0 +1,538 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: database.go +// +// Generated by this command: +// +// mockgen -source=database.go -destination=./mock_database.go -package=arangodb +// + +// Package arangodb is a generated GoMock package. +package arangodb + +import ( + context "context" + reflect "reflect" + + arangodb "github.com/arangodb/go-driver/v2/arangodb" + gomock "go.uber.org/mock/gomock" +) + +// MockArangoDatabase is a mock of database interface. +type MockDatabase struct { + ctrl *gomock.Controller + recorder *MockDatabaseMockRecorder +} + +// MockDatabaseMockRecorder is the mock recorder for MockArangoDatabase. +type MockDatabaseMockRecorder struct { + mock *MockDatabase +} + +// NewMockDatabase creates a new mock instance. +func NewMockDatabase(ctrl *gomock.Controller) *MockDatabase { + mock := &MockDatabase{ctrl: ctrl} + mock.recorder = &MockDatabaseMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDatabase) EXPECT() *MockDatabaseMockRecorder { + return m.recorder +} + +// Analyzer mocks base method. +func (m *MockDatabase) Analyzer(ctx context.Context, name string) (arangodb.Analyzer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Analyzer", ctx, name) + ret0, _ := ret[0].(arangodb.Analyzer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Analyzer indicates an expected call of Analyzer. +func (mr *MockDatabaseMockRecorder) Analyzer(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Analyzer", reflect.TypeOf((*MockDatabase)(nil).Analyzer), ctx, name) +} + +// Analyzers mocks base method. +func (m *MockDatabase) Analyzers(ctx context.Context) (arangodb.AnalyzersResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Analyzers", ctx) + ret0, _ := ret[0].(arangodb.AnalyzersResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Analyzers indicates an expected call of Analyzers. +func (mr *MockDatabaseMockRecorder) Analyzers(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Analyzers", reflect.TypeOf((*MockDatabase)(nil).Analyzers), ctx) +} + +// BeginTransaction mocks base method. +func (m *MockDatabase) BeginTransaction(ctx context.Context, cols arangodb.TransactionCollections, opts *arangodb.BeginTransactionOptions) (arangodb.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginTransaction", ctx, cols, opts) + ret0, _ := ret[0].(arangodb.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeginTransaction indicates an expected call of BeginTransaction. +func (mr *MockDatabaseMockRecorder) BeginTransaction(ctx, cols, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginTransaction", reflect.TypeOf((*MockDatabase)(nil).BeginTransaction), ctx, cols, opts) +} + +// Collection mocks base method. +func (m *MockDatabase) Collection(ctx context.Context, name string) (arangodb.Collection, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Collection", ctx, name) + ret0, _ := ret[0].(arangodb.Collection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Collection indicates an expected call of Collection. +func (mr *MockDatabaseMockRecorder) Collection(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Collection", reflect.TypeOf((*MockDatabase)(nil).Collection), ctx, name) +} + +// CollectionExists mocks base method. +func (m *MockDatabase) CollectionExists(ctx context.Context, name string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CollectionExists", ctx, name) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CollectionExists indicates an expected call of CollectionExists. +func (mr *MockDatabaseMockRecorder) CollectionExists(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CollectionExists", reflect.TypeOf((*MockDatabase)(nil).CollectionExists), ctx, name) +} + +// Collections mocks base method. +func (m *MockDatabase) Collections(ctx context.Context) ([]arangodb.Collection, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Collections", ctx) + ret0, _ := ret[0].([]arangodb.Collection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Collections indicates an expected call of Collections. +func (mr *MockDatabaseMockRecorder) Collections(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Collections", reflect.TypeOf((*MockDatabase)(nil).Collections), ctx) +} + +// CreateArangoSearchAliasView mocks base method. +func (m *MockDatabase) CreateArangoSearchAliasView(ctx context.Context, name string, options *arangodb.ArangoSearchAliasViewProperties) (arangodb.ArangoSearchViewAlias, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateArangoSearchAliasView", ctx, name, options) + ret0, _ := ret[0].(arangodb.ArangoSearchViewAlias) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateArangoSearchAliasView indicates an expected call of CreateArangoSearchAliasView. +func (mr *MockDatabaseMockRecorder) CreateArangoSearchAliasView(ctx, name, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateArangoSearchAliasView", reflect.TypeOf((*MockDatabase)(nil).CreateArangoSearchAliasView), ctx, name, options) +} + +// CreateArangoSearchView mocks base method. +func (m *MockDatabase) CreateArangoSearchView(ctx context.Context, name string, options *arangodb.ArangoSearchViewProperties) (arangodb.ArangoSearchView, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateArangoSearchView", ctx, name, options) + ret0, _ := ret[0].(arangodb.ArangoSearchView) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateArangoSearchView indicates an expected call of CreateArangoSearchView. +func (mr *MockDatabaseMockRecorder) CreateArangoSearchView(ctx, name, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateArangoSearchView", reflect.TypeOf((*MockDatabase)(nil).CreateArangoSearchView), ctx, name, options) +} + +// CreateCollection mocks base method. +func (m *MockDatabase) CreateCollection(ctx context.Context, name string, props *arangodb.CreateCollectionProperties) (arangodb.Collection, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateCollection", ctx, name, props) + ret0, _ := ret[0].(arangodb.Collection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateCollection indicates an expected call of CreateCollection. +func (mr *MockDatabaseMockRecorder) CreateCollection(ctx, name, props any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCollection", reflect.TypeOf((*MockDatabase)(nil).CreateCollection), ctx, name, props) +} + +// CreateCollectionWithOptions mocks base method. +func (m *MockDatabase) CreateCollectionWithOptions(ctx context.Context, name string, props *arangodb.CreateCollectionProperties, options *arangodb.CreateCollectionOptions) (arangodb.Collection, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateCollectionWithOptions", ctx, name, props, options) + ret0, _ := ret[0].(arangodb.Collection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateCollectionWithOptions indicates an expected call of CreateCollectionWithOptions. +func (mr *MockDatabaseMockRecorder) CreateCollectionWithOptions(ctx, name, props, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCollectionWithOptions", reflect.TypeOf((*MockDatabase)(nil).CreateCollectionWithOptions), ctx, name, props, options) +} + +// CreateGraph mocks base method. +func (m *MockDatabase) CreateGraph(ctx context.Context, name string, graph *arangodb.GraphDefinition, options *arangodb.CreateGraphOptions) (arangodb.Graph, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateGraph", ctx, name, graph, options) + ret0, _ := ret[0].(arangodb.Graph) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateGraph indicates an expected call of CreateGraph. +func (mr *MockDatabaseMockRecorder) CreateGraph(ctx, name, graph, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGraph", reflect.TypeOf((*MockDatabase)(nil).CreateGraph), ctx, name, graph, options) +} + +// EnsureAnalyzer mocks base method. +func (m *MockDatabase) EnsureAnalyzer(ctx context.Context, analyzer *arangodb.AnalyzerDefinition) (bool, arangodb.Analyzer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureAnalyzer", ctx, analyzer) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(arangodb.Analyzer) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// EnsureAnalyzer indicates an expected call of EnsureAnalyzer. +func (mr *MockDatabaseMockRecorder) EnsureAnalyzer(ctx, analyzer any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureAnalyzer", reflect.TypeOf((*MockDatabase)(nil).EnsureAnalyzer), ctx, analyzer) +} + +// ExplainQuery mocks base method. +func (m *MockDatabase) ExplainQuery(ctx context.Context, query string, bindVars map[string]any, opts *arangodb.ExplainQueryOptions) (arangodb.ExplainQueryResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExplainQuery", ctx, query, bindVars, opts) + ret0, _ := ret[0].(arangodb.ExplainQueryResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExplainQuery indicates an expected call of ExplainQuery. +func (mr *MockDatabaseMockRecorder) ExplainQuery(ctx, query, bindVars, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExplainQuery", reflect.TypeOf((*MockDatabase)(nil).ExplainQuery), ctx, query, bindVars, opts) +} + +// GetCollection mocks base method. +func (m *MockDatabase) GetCollection(ctx context.Context, name string, options *arangodb.GetCollectionOptions) (arangodb.Collection, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCollection", ctx, name, options) + ret0, _ := ret[0].(arangodb.Collection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCollection indicates an expected call of GetCollection. +func (mr *MockDatabaseMockRecorder) GetCollection(ctx, name, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCollection", reflect.TypeOf((*MockDatabase)(nil).GetCollection), ctx, name, options) +} + +// GetEdges mocks base method. +func (m *MockDatabase) GetEdges(ctx context.Context, name, vertex string, options *arangodb.GetEdgesOptions) ([]arangodb.EdgeDetails, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEdges", ctx, name, vertex, options) + ret0, _ := ret[0].([]arangodb.EdgeDetails) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetEdges indicates an expected call of GetEdges. +func (mr *MockDatabaseMockRecorder) GetEdges(ctx, name, vertex, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEdges", reflect.TypeOf((*MockDatabase)(nil).GetEdges), ctx, name, vertex, options) +} + +// Graph mocks base method. +func (m *MockDatabase) Graph(ctx context.Context, name string, options *arangodb.GetGraphOptions) (arangodb.Graph, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Graph", ctx, name, options) + ret0, _ := ret[0].(arangodb.Graph) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Graph indicates an expected call of Graph. +func (mr *MockDatabaseMockRecorder) Graph(ctx, name, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Graph", reflect.TypeOf((*MockDatabase)(nil).Graph), ctx, name, options) +} + +// GraphExists mocks base method. +func (m *MockDatabase) GraphExists(ctx context.Context, name string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GraphExists", ctx, name) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GraphExists indicates an expected call of GraphExists. +func (mr *MockDatabaseMockRecorder) GraphExists(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GraphExists", reflect.TypeOf((*MockDatabase)(nil).GraphExists), ctx, name) +} + +// Graphs mocks base method. +func (m *MockDatabase) Graphs(ctx context.Context) (arangodb.GraphsResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Graphs", ctx) + ret0, _ := ret[0].(arangodb.GraphsResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Graphs indicates an expected call of Graphs. +func (mr *MockDatabaseMockRecorder) Graphs(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Graphs", reflect.TypeOf((*MockDatabase)(nil).Graphs), ctx) +} + +// Info mocks base method. +func (m *MockDatabase) Info(ctx context.Context) (arangodb.DatabaseInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Info", ctx) + ret0, _ := ret[0].(arangodb.DatabaseInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Info indicates an expected call of Info. +func (mr *MockDatabaseMockRecorder) Info(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockDatabase)(nil).Info), ctx) +} + +// ListTransactions mocks base method. +func (m *MockDatabase) ListTransactions(ctx context.Context) ([]arangodb.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTransactions", ctx) + ret0, _ := ret[0].([]arangodb.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTransactions indicates an expected call of ListTransactions. +func (mr *MockDatabaseMockRecorder) ListTransactions(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTransactions", reflect.TypeOf((*MockDatabase)(nil).ListTransactions), ctx) +} + +// ListTransactionsWithStatuses mocks base method. +func (m *MockDatabase) ListTransactionsWithStatuses(ctx context.Context, statuses ...arangodb.TransactionStatus) ([]arangodb.Transaction, error) { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range statuses { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListTransactionsWithStatuses", varargs...) + ret0, _ := ret[0].([]arangodb.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTransactionsWithStatuses indicates an expected call of ListTransactionsWithStatuses. +func (mr *MockDatabaseMockRecorder) ListTransactionsWithStatuses(ctx any, statuses ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, statuses...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTransactionsWithStatuses", reflect.TypeOf((*MockDatabase)(nil).ListTransactionsWithStatuses), varargs...) +} + +// Name mocks base method. +func (m *MockDatabase) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockDatabaseMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockDatabase)(nil).Name)) +} + +// Query mocks base method. +func (m *MockDatabase) Query(ctx context.Context, query string, opts *arangodb.QueryOptions) (arangodb.Cursor, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, query, opts) + ret0, _ := ret[0].(arangodb.Cursor) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockDatabaseMockRecorder) Query(ctx, query, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockDatabase)(nil).Query), ctx, query, opts) +} + +// QueryBatch mocks base method. +func (m *MockDatabase) QueryBatch(ctx context.Context, query string, opts *arangodb.QueryOptions, result any) (arangodb.CursorBatch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryBatch", ctx, query, opts, result) + ret0, _ := ret[0].(arangodb.CursorBatch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryBatch indicates an expected call of QueryBatch. +func (mr *MockDatabaseMockRecorder) QueryBatch(ctx, query, opts, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryBatch", reflect.TypeOf((*MockDatabase)(nil).QueryBatch), ctx, query, opts, result) +} + +// Remove mocks base method. +func (m *MockDatabase) Remove(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remove", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Remove indicates an expected call of Remove. +func (mr *MockDatabaseMockRecorder) Remove(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockDatabase)(nil).Remove), ctx) +} + +// Transaction mocks base method. +func (m *MockDatabase) Transaction(ctx context.Context, id arangodb.TransactionID) (arangodb.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Transaction", ctx, id) + ret0, _ := ret[0].(arangodb.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Transaction indicates an expected call of Transaction. +func (mr *MockDatabaseMockRecorder) Transaction(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockDatabase)(nil).Transaction), ctx, id) +} + +// TransactionJS mocks base method. +func (m *MockDatabase) TransactionJS(ctx context.Context, options arangodb.TransactionJSOptions) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TransactionJS", ctx, options) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TransactionJS indicates an expected call of TransactionJS. +func (mr *MockDatabaseMockRecorder) TransactionJS(ctx, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionJS", reflect.TypeOf((*MockDatabase)(nil).TransactionJS), ctx, options) +} + +// ValidateQuery mocks base method. +func (m *MockDatabase) ValidateQuery(ctx context.Context, query string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateQuery", ctx, query) + ret0, _ := ret[0].(error) + return ret0 +} + +// ValidateQuery indicates an expected call of ValidateQuery. +func (mr *MockDatabaseMockRecorder) ValidateQuery(ctx, query any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateQuery", reflect.TypeOf((*MockDatabase)(nil).ValidateQuery), ctx, query) +} + +// View mocks base method. +func (m *MockDatabase) View(ctx context.Context, name string) (arangodb.View, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "View", ctx, name) + ret0, _ := ret[0].(arangodb.View) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// View indicates an expected call of View. +func (mr *MockDatabaseMockRecorder) View(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "View", reflect.TypeOf((*MockDatabase)(nil).View), ctx, name) +} + +// ViewExists mocks base method. +func (m *MockDatabase) ViewExists(ctx context.Context, name string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewExists", ctx, name) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ViewExists indicates an expected call of ViewExists. +func (mr *MockDatabaseMockRecorder) ViewExists(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewExists", reflect.TypeOf((*MockDatabase)(nil).ViewExists), ctx, name) +} + +// Views mocks base method. +func (m *MockDatabase) Views(ctx context.Context) (arangodb.ViewsResponseReader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Views", ctx) + ret0, _ := ret[0].(arangodb.ViewsResponseReader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Views indicates an expected call of Views. +func (mr *MockDatabaseMockRecorder) Views(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Views", reflect.TypeOf((*MockDatabase)(nil).Views), ctx) +} + +// ViewsAll mocks base method. +func (m *MockDatabase) ViewsAll(ctx context.Context) ([]arangodb.View, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewsAll", ctx) + ret0, _ := ret[0].([]arangodb.View) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ViewsAll indicates an expected call of ViewsAll. +func (mr *MockDatabaseMockRecorder) ViewsAll(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewsAll", reflect.TypeOf((*MockDatabase)(nil).ViewsAll), ctx) +} + +// WithTransaction mocks base method. +func (m *MockDatabase) WithTransaction(ctx context.Context, cols arangodb.TransactionCollections, opts *arangodb.BeginTransactionOptions, commitOptions *arangodb.CommitTransactionOptions, abortOptions *arangodb.AbortTransactionOptions, w arangodb.TransactionWrap) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WithTransaction", ctx, cols, opts, commitOptions, abortOptions, w) + ret0, _ := ret[0].(error) + return ret0 +} + +// WithTransaction indicates an expected call of WithTransaction. +func (mr *MockDatabaseMockRecorder) WithTransaction(ctx, cols, opts, commitOptions, abortOptions, w any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithTransaction", reflect.TypeOf((*MockDatabase)(nil).WithTransaction), ctx, cols, opts, commitOptions, abortOptions, w) +} diff --git a/pkg/gofr/datasource/arangodb/mock_interfaces.go b/pkg/gofr/datasource/arangodb/mock_interfaces.go new file mode 100644 index 000000000..aa958e59f --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_interfaces.go @@ -0,0 +1,724 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go +// +// Generated by this command: +// +// mockgen -source=interface.go -destination=mock_interfaces.go -package=arangodb +// + +// Package arangodb is a generated GoMock package. +package arangodb + +import ( + "context" + "fmt" + "github.com/arangodb/go-driver/v2/connection" + reflect "reflect" + "strings" + + arangodb "github.com/arangodb/go-driver/v2/arangodb" + gomock "go.uber.org/mock/gomock" +) + +// MockArangoMockRecorder is the mock recorder for MockArango. +type MockArangoMockRecorder struct { + mock *MockArango +} + +// NewMockArango creates a new mock instance. +func NewMockArango(ctrl *gomock.Controller) *MockArango { + mock := &MockArango{ctrl: ctrl} + mock.recorder = &MockArangoMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockArango) EXPECT() *MockArangoMockRecorder { + return m.recorder +} + +// MockArango is a mock of ArangoDB interface. +type MockArango struct { + ctrl *gomock.Controller + recorder *MockArangoMockRecorder +} + +func (m *MockArango) Connection() connection.Connection { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connection") + return ret[0].(connection.Connection) +} + +func (mr *MockArangoMockRecorder) Connection() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connection", reflect.TypeOf((*MockArango)(nil).Connection)) +} + +func (m *MockArango) Get(ctx context.Context, output interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", ctx, output, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Get(ctx, output interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockArango)(nil).Get), ctx, output, urlParts) +} + +func (m *MockArango) Post(ctx context.Context, output, input interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Post", ctx, output, input, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Post(ctx, output, input interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Post", reflect.TypeOf((*MockArango)(nil).Post), ctx, output, input, urlParts) +} + +func (m *MockArango) Put(ctx context.Context, output, input interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Put", ctx, output, input, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Put(ctx, output, input interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockArango)(nil).Put), ctx, output, input, urlParts) +} + +func (m *MockArango) Delete(ctx context.Context, output interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", ctx, output, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Delete(ctx, output interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockArango)(nil).Delete), ctx, output, urlParts) +} + +func (m *MockArango) Head(ctx context.Context, output interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Head", ctx, output, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Head(ctx, output interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Head", reflect.TypeOf((*MockArango)(nil).Head), ctx, output, urlParts) +} + +func (m *MockArango) Patch(ctx context.Context, output, input interface{}, urlParts ...string) (connection.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Patch", ctx, output, input, urlParts) + return ret[0].(connection.Response), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) Patch(ctx, output, input interface{}, urlParts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Patch", reflect.TypeOf((*MockArango)(nil).Patch), ctx, output, input, urlParts) +} + +func (m *MockArango) CreateDatabase(ctx context.Context, name string, options *arangodb.CreateDatabaseOptions) (arangodb.Database, error) { + db := NewMockDatabase(m.ctrl) + if strings.Contains(name, "error") { + return nil,fmt.Errorf("database not found") + } + + return db,nil +} + +func (mr *MockArangoMockRecorder) CreateDatabase(ctx, name, options interface{}) *gomock.Call { + return mr.CreateDB(ctx, name) +} + +func (m *MockArango) GetDatabase(ctx context.Context, name string, options *arangodb.GetDatabaseOptions) (arangodb.Database, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDatabase", ctx, name, options) + return ret[0].(arangodb.Database), ret[1].(error) +} + +func (mr *MockArangoMockRecorder) GetDatabase(ctx, name, options interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDatabase", reflect.TypeOf((*MockArango)(nil).GetDatabase), ctx, name, options) +} + +func (m *MockArango) DatabaseExists(ctx context.Context, name string) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) AccessibleDatabases(ctx context.Context) ([]arangodb.Database, error) { + //TODO implement me + panic("implement me") +} + + +func (m *MockArango) UserExists(ctx context.Context, name string) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) Users(ctx context.Context) ([]arangodb.User, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) ReplaceUser(ctx context.Context, name string, options *arangodb.UserOptions) (arangodb.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceUser", ctx, name, options) + return ret[0].(arangodb.User), ret[1].(error) +} + +// Mock recorder method for setting up expectations +func (mr *MockArangoMockRecorder) ReplaceUser(ctx, name, options interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceUser", reflect.TypeOf((*MockArango)(nil).ReplaceUser), ctx, name, options) +} + +func (m *MockArango) UpdateUser(ctx context.Context, name string, options *arangodb.UserOptions) (arangodb.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateUser", ctx, name, options) + return ret[0].(arangodb.User), ret[1].(error) +} + +// Mock recorder method for setting up expectations +func (mr *MockArangoMockRecorder) UpdateUser(ctx, name, options interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockArango)(nil).UpdateUser), ctx, name, options) +} + + +func (m *MockArango) RemoveUser(ctx context.Context, name string) error { + return m.DropUser(ctx, name) +} + +func (m *MockArango) VersionWithOptions(ctx context.Context, opts *arangodb.GetVersionOptions) (arangodb.VersionInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VersionWithOptions", ctx, opts) + return ret[0].(arangodb.VersionInfo), ret[1].(error) +} + +// Mock recorder method for setting up expectations +func (mr *MockArangoMockRecorder) VersionWithOptions(ctx, opts interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VersionWithOptions", reflect.TypeOf((*MockArango)(nil).VersionWithOptions), ctx, opts) +} + + +func (m *MockArango) ServerRole(ctx context.Context) (arangodb.ServerRole, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) ServerID(ctx context.Context) (string, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) GetLogLevels(ctx context.Context, opts *arangodb.LogLevelsGetOptions) (arangodb.LogLevels, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) SetLogLevels(ctx context.Context, logLevels arangodb.LogLevels, opts *arangodb.LogLevelsSetOptions) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupCreate(ctx context.Context, opt *arangodb.BackupCreateOptions) (arangodb.BackupResponse, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupRestore(ctx context.Context, id string) (arangodb.BackupRestoreResponse, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupDelete(ctx context.Context, id string) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupList(ctx context.Context, opt *arangodb.BackupListOptions) (arangodb.ListBackupsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupUpload(ctx context.Context, backupId string, remoteRepository string, config interface{}) (arangodb.TransferMonitor, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) BackupDownload(ctx context.Context, backupId string, remoteRepository string, config interface{}) (arangodb.TransferMonitor, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) TransferMonitor(jobId string, transferType arangodb.TransferType) (arangodb.TransferMonitor, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) GetLicense(ctx context.Context) (arangodb.License, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) SetLicense(ctx context.Context, license string, force bool) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) Health(ctx context.Context) (arangodb.ClusterHealth, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) DatabaseInventory(ctx context.Context, dbName string) (arangodb.DatabaseInventory, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) MoveShard(ctx context.Context, col arangodb.Collection, shard arangodb.ShardID, fromServer, toServer arangodb.ServerID) (string, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) CleanOutServer(ctx context.Context, serverID arangodb.ServerID) (string, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) ResignServer(ctx context.Context, serverID arangodb.ServerID) (string, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) NumberOfServers(ctx context.Context) (arangodb.NumberOfServersResponse, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) IsCleanedOut(ctx context.Context, serverID arangodb.ServerID) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) RemoveServer(ctx context.Context, serverID arangodb.ServerID) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) ServerMode(ctx context.Context) (arangodb.ServerMode, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) SetServerMode(ctx context.Context, mode arangodb.ServerMode) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) CheckAvailability(ctx context.Context, serverEndpoint string) error { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) AsyncJobList(ctx context.Context, jobType arangodb.AsyncJobStatusType, opts *arangodb.AsyncJobListOptions) ([]string, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) AsyncJobStatus(ctx context.Context, jobID string) (arangodb.AsyncJobStatusType, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) AsyncJobCancel(ctx context.Context, jobID string) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockArango) AsyncJobDelete(ctx context.Context, deleteType arangodb.AsyncJobDeleteType, opts *arangodb.AsyncJobDeleteOptions) (bool, error) { + //TODO implement me + panic("implement me") +} + +// Connect mocks base method. +func (m *MockArango) Connect() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Connect") +} + +// Connect indicates an expected call of Connect. +func (mr *MockArangoMockRecorder) Connect() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockArango)(nil).Connect)) +} + +// CreateCollection mocks base method. +func (m *MockArango) CreateCollection(ctx context.Context, database, collection string, isEdge bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateCollection", ctx, database, collection, isEdge) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateCollection indicates an expected call of CreateCollection. +func (mr *MockArangoMockRecorder) CreateCollection(ctx, database, collection, isEdge any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCollection", reflect.TypeOf((*MockArango)(nil).CreateCollection), ctx, database, collection, isEdge) +} + +// CreateDB mocks base method. +func (m *MockArango) CreateDB(ctx context.Context, database string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDB", ctx, database) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateDB indicates an expected call of CreateDB. +func (mr *MockArangoMockRecorder) CreateDB(ctx, database any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDB", reflect.TypeOf((*MockArango)(nil).CreateDB), ctx, database) +} + +// CreateDocument mocks base method. +func (m *MockArango) CreateDocument(ctx context.Context, dbName, collectionName string, document any) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateDocument", ctx, dbName, collectionName, document) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateDocument indicates an expected call of CreateDocument. +func (mr *MockArangoMockRecorder) CreateDocument(ctx, dbName, collectionName, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDocument", reflect.TypeOf((*MockArango)(nil).CreateDocument), ctx, dbName, collectionName, document) +} + +// CreateEdgeDocument mocks base method. +func (m *MockArango) CreateEdgeDocument(ctx context.Context, dbName, collectionName, from, to string, document any) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateEdgeDocument", ctx, dbName, collectionName, from, to, document) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateEdgeDocument indicates an expected call of CreateEdgeDocument. +func (mr *MockArangoMockRecorder) CreateEdgeDocument(ctx, dbName, collectionName, from, to, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEdgeDocument", reflect.TypeOf((*MockArango)(nil).CreateEdgeDocument), ctx, dbName, collectionName, from, to, document) +} + +// CreateGraph mocks base method. +func (m *MockArango) CreateGraph(ctx context.Context, database, graph string, edgeDefinitions any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateGraph", ctx, database, graph, edgeDefinitions) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateGraph indicates an expected call of CreateGraph. +func (mr *MockArangoMockRecorder) CreateGraph(ctx, database, graph, edgeDefinitions any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateGraph", reflect.TypeOf((*MockArango)(nil).CreateGraph), ctx, database, graph, edgeDefinitions) +} + +func (m *MockArango) CreateUser(ctx context. Context, name string, options *arangodb.UserOptions) (arangodb.User, error){ + return nil,m.AddUser(ctx, name, options) +} + +// CreateUser mocks base method. +func (m *MockArango) AddUser(ctx context.Context, username string, options any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateUser", ctx, username, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateUser indicates an expected call of CreateUser. +func (mr *MockArangoMockRecorder) AddUser(ctx, username, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockArango)(nil).CreateUser), ctx, username, options) +} + +// Database mocks base method. +func (m *MockArango) Database(ctx context.Context, name string) (arangodb.Database, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "database", ctx, name) + ret0, _ := ret[0].(arangodb.Database) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Database indicates an expected call of Database. +func (mr *MockArangoMockRecorder) Database(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "database", reflect.TypeOf((*MockArango)(nil).Database), ctx, name) +} + +// Databases mocks base method. +func (m *MockArango) Databases(ctx context.Context) ([]arangodb.Database, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "databases", ctx) + ret0, _ := ret[0].([]arangodb.Database) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Databases indicates an expected call of Databases. +func (mr *MockArangoMockRecorder) Databases(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "databases", reflect.TypeOf((*MockArango)(nil).Databases), ctx) +} + +// DeleteDocument mocks base method. +func (m *MockArango) DeleteDocument(ctx context.Context, dbName, collectionName, documentID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDocument", ctx, dbName, collectionName, documentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDocument indicates an expected call of DeleteDocument. +func (mr *MockArangoMockRecorder) DeleteDocument(ctx, dbName, collectionName, documentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDocument", reflect.TypeOf((*MockArango)(nil).DeleteDocument), ctx, dbName, collectionName, documentID) +} + +// DropCollection mocks base method. +func (m *MockArango) DropCollection(ctx context.Context, database, collection string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DropCollection", ctx, database, collection) + ret0, _ := ret[0].(error) + return ret0 +} + +// DropCollection indicates an expected call of DropCollection. +func (mr *MockArangoMockRecorder) DropCollection(ctx, database, collection any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropCollection", reflect.TypeOf((*MockArango)(nil).DropCollection), ctx, database, collection) +} + +// DropDB mocks base method. +func (m *MockArango) DropDB(ctx context.Context, database string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DropDB", ctx, database) + ret0, _ := ret[0].(error) + return ret0 +} + +// DropDB indicates an expected call of DropDB. +func (mr *MockArangoMockRecorder) DropDB(ctx, database any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropDB", reflect.TypeOf((*MockArango)(nil).DropDB), ctx, database) +} + +// DropGraph mocks base method. +func (m *MockArango) DropGraph(ctx context.Context, database, graph string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DropGraph", ctx, database, graph) + ret0, _ := ret[0].(error) + return ret0 +} + +// DropGraph indicates an expected call of DropGraph. +func (mr *MockArangoMockRecorder) DropGraph(ctx, database, graph any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropGraph", reflect.TypeOf((*MockArango)(nil).DropGraph), ctx, database, graph) +} + +// DropUser mocks base method. +func (m *MockArango) DropUser(ctx context.Context, username string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DropUser", ctx, username) + ret0, _ := ret[0].(error) + return ret0 +} + +// DropUser indicates an expected call of DropUser. +func (mr *MockArangoMockRecorder) DropUser(ctx, username any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropUser", reflect.TypeOf((*MockArango)(nil).DropUser), ctx, username) +} + +// GetDocument mocks base method. +func (m *MockArango) GetDocument(ctx context.Context, dbName, collectionName, documentID string, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDocument", ctx, dbName, collectionName, documentID, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetDocument indicates an expected call of GetDocument. +func (mr *MockArangoMockRecorder) GetDocument(ctx, dbName, collectionName, documentID, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDocument", reflect.TypeOf((*MockArango)(nil).GetDocument), ctx, dbName, collectionName, documentID, result) +} + +// GrantCollection mocks base method. +func (m *MockArango) GrantCollection(ctx context.Context, database, collection, username, permission string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GrantCollection", ctx, database, collection, username, permission) + ret0, _ := ret[0].(error) + return ret0 +} + +// GrantCollection indicates an expected call of GrantCollection. +func (mr *MockArangoMockRecorder) GrantCollection(ctx, database, collection, username, permission any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GrantCollection", reflect.TypeOf((*MockArango)(nil).GrantCollection), ctx, database, collection, username, permission) +} + +// GrantDB mocks base method. +func (m *MockArango) GrantDB(ctx context.Context, database, username, permission string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GrantDB", ctx, database, username, permission) + ret0, _ := ret[0].(error) + return ret0 +} + +// GrantDB indicates an expected call of GrantDB. +func (mr *MockArangoMockRecorder) GrantDB(ctx, database, username, permission any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GrantDB", reflect.TypeOf((*MockArango)(nil).GrantDB), ctx, database, username, permission) +} + +// HealthCheck mocks base method. +func (m *MockArango) HealthCheck(ctx context.Context) (any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", ctx) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HealthCheck indicates an expected call of HealthCheck. +func (mr *MockArangoMockRecorder) HealthCheck(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockArango)(nil).HealthCheck), ctx) +} + +// ListCollections mocks base method. +func (m *MockArango) ListCollections(ctx context.Context, database string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCollections", ctx, database) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCollections indicates an expected call of ListCollections. +func (mr *MockArangoMockRecorder) ListCollections(ctx, database any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCollections", reflect.TypeOf((*MockArango)(nil).ListCollections), ctx, database) +} + +// ListDBs mocks base method. +func (m *MockArango) ListDBs(ctx context.Context) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDBs", ctx) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDBs indicates an expected call of ListDBs. +func (mr *MockArangoMockRecorder) ListDBs(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDBs", reflect.TypeOf((*MockArango)(nil).ListDBs), ctx) +} + +// ListGraphs mocks base method. +func (m *MockArango) ListGraphs(ctx context.Context, database string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGraphs", ctx, database) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGraphs indicates an expected call of ListGraphs. +func (mr *MockArangoMockRecorder) ListGraphs(ctx, database any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGraphs", reflect.TypeOf((*MockArango)(nil).ListGraphs), ctx, database) +} + +// Query mocks base method. +func (m *MockArango) Query(ctx context.Context, dbName, query string, bindVars map[string]any, result any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, dbName, query, bindVars, result) + ret0, _ := ret[0].(error) + return ret0 +} + +// Query indicates an expected call of Query. +func (mr *MockArangoMockRecorder) Query(ctx, dbName, query, bindVars, result any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockArango)(nil).Query), ctx, dbName, query, bindVars, result) +} + +// TruncateCollection mocks base method. +func (m *MockArango) TruncateCollection(ctx context.Context, database, collection string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TruncateCollection", ctx, database, collection) + ret0, _ := ret[0].(error) + return ret0 +} + +// TruncateCollection indicates an expected call of TruncateCollection. +func (mr *MockArangoMockRecorder) TruncateCollection(ctx, database, collection any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TruncateCollection", reflect.TypeOf((*MockArango)(nil).TruncateCollection), ctx, database, collection) +} + +// UpdateDocument mocks base method. +func (m *MockArango) UpdateDocument(ctx context.Context, dbName, collectionName, documentID string, document any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateDocument", ctx, dbName, collectionName, documentID, document) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateDocument indicates an expected call of UpdateDocument. +func (mr *MockArangoMockRecorder) UpdateDocument(ctx, dbName, collectionName, documentID, document any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDocument", reflect.TypeOf((*MockArango)(nil).UpdateDocument), ctx, dbName, collectionName, documentID, document) +} + +// User mocks base method. +func (m *MockArango) User(ctx context.Context, username string) (arangodb.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "user", ctx, username) + ret0, _ := ret[0].(arangodb.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// User indicates an expected call of User. +func (mr *MockArangoMockRecorder) User(ctx, username any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "user", reflect.TypeOf((*MockArango)(nil).User), ctx, username) +} + +// Version mocks base method. +func (m *MockArango) Version(ctx context.Context) (arangodb.VersionInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "version", ctx) + ret0, _ := ret[0].(arangodb.VersionInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Version indicates an expected call of Version. +func (mr *MockArangoMockRecorder) Version(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "version", reflect.TypeOf((*MockArango)(nil).Version), ctx) +} diff --git a/pkg/gofr/datasource/arangodb/mock_logger.go b/pkg/gofr/datasource/arangodb/mock_logger.go new file mode 100644 index 000000000..50450314b --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_logger.go @@ -0,0 +1,106 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: logger.go +// +// Generated by this command: +// +// mockgen -source=logger.go -destination=mock_logger.go -package=arangodb +// + +// Package arangodb is a generated GoMock package. +package arangodb + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockLogger is a mock of Logger interface. +type MockLogger struct { + ctrl *gomock.Controller + recorder *MockLoggerMockRecorder +} + +// MockLoggerMockRecorder is the mock recorder for MockLogger. +type MockLoggerMockRecorder struct { + mock *MockLogger +} + +// NewMockLogger creates a new mock instance. +func NewMockLogger(ctrl *gomock.Controller) *MockLogger { + mock := &MockLogger{ctrl: ctrl} + mock.recorder = &MockLoggerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLogger) EXPECT() *MockLoggerMockRecorder { + return m.recorder +} + +// Debug mocks base method. +func (m *MockLogger) Debug(args ...any) { + m.ctrl.T.Helper() + varargs := []any{} + for _, a := range args { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Debug", varargs...) +} + +// Debug indicates an expected call of Debug. +func (mr *MockLoggerMockRecorder) Debug(args ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), args...) +} + +// Debugf mocks base method. +func (m *MockLogger) Debugf(pattern string, args ...any) { + m.ctrl.T.Helper() + varargs := []any{pattern} + for _, a := range args { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Debugf", varargs...) +} + +// Debugf indicates an expected call of Debugf. +func (mr *MockLoggerMockRecorder) Debugf(pattern any, args ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{pattern}, args...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debugf", reflect.TypeOf((*MockLogger)(nil).Debugf), varargs...) +} + +// Errorf mocks base method. +func (m *MockLogger) Errorf(pattern string, args ...any) { + m.ctrl.T.Helper() + varargs := []any{pattern} + for _, a := range args { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Errorf", varargs...) +} + +// Errorf indicates an expected call of Errorf. +func (mr *MockLoggerMockRecorder) Errorf(pattern any, args ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{pattern}, args...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Errorf", reflect.TypeOf((*MockLogger)(nil).Errorf), varargs...) +} + +// Logf mocks base method. +func (m *MockLogger) Logf(pattern string, args ...any) { + m.ctrl.T.Helper() + varargs := []any{pattern} + for _, a := range args { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Logf", varargs...) +} + +// Logf indicates an expected call of Logf. +func (mr *MockLoggerMockRecorder) Logf(pattern any, args ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{pattern}, args...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logf", reflect.TypeOf((*MockLogger)(nil).Logf), varargs...) +} diff --git a/pkg/gofr/datasource/arangodb/mock_metrics.go b/pkg/gofr/datasource/arangodb/mock_metrics.go new file mode 100644 index 000000000..2ca4023ea --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_metrics.go @@ -0,0 +1,74 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: metrics.go +// +// Generated by this command: +// +// mockgen -source=metrics.go -destination=mock_metrics.go -package=arangodb +// + +// Package arangodb is a generated GoMock package. +package arangodb + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockMetrics is a mock of Metrics interface. +type MockMetrics struct { + ctrl *gomock.Controller + recorder *MockMetricsMockRecorder +} + +// MockMetricsMockRecorder is the mock recorder for MockMetrics. +type MockMetricsMockRecorder struct { + mock *MockMetrics +} + +// NewMockMetrics creates a new mock instance. +func NewMockMetrics(ctrl *gomock.Controller) *MockMetrics { + mock := &MockMetrics{ctrl: ctrl} + mock.recorder = &MockMetricsMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockMetrics) EXPECT() *MockMetricsMockRecorder { + return m.recorder +} + +// NewHistogram mocks base method. +func (m *MockMetrics) NewHistogram(name, desc string, buckets ...float64) { + m.ctrl.T.Helper() + varargs := []any{name, desc} + for _, a := range buckets { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "NewHistogram", varargs...) +} + +// NewHistogram indicates an expected call of NewHistogram. +func (mr *MockMetricsMockRecorder) NewHistogram(name, desc any, buckets ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{name, desc}, buckets...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewHistogram", reflect.TypeOf((*MockMetrics)(nil).NewHistogram), varargs...) +} + +// RecordHistogram mocks base method. +func (m *MockMetrics) RecordHistogram(ctx context.Context, name string, value float64, labels ...string) { + m.ctrl.T.Helper() + varargs := []any{ctx, name, value} + for _, a := range labels { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "RecordHistogram", varargs...) +} + +// RecordHistogram indicates an expected call of RecordHistogram. +func (mr *MockMetricsMockRecorder) RecordHistogram(ctx, name, value any, labels ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, name, value}, labels...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordHistogram", reflect.TypeOf((*MockMetrics)(nil).RecordHistogram), varargs...) +} diff --git a/pkg/gofr/datasource/arangodb/mock_user.go b/pkg/gofr/datasource/arangodb/mock_user.go new file mode 100644 index 000000000..7e2a999cc --- /dev/null +++ b/pkg/gofr/datasource/arangodb/mock_user.go @@ -0,0 +1,59 @@ +package arangodb + +import ( + "context" + + "github.com/arangodb/go-driver/v2/arangodb" + "go.uber.org/mock/gomock" +) + +// MockUser implements the complete arangodb.user interface. +type MockUser struct { + ctrl *gomock.Controller + name string + active bool +} + +func NewMockUser(ctrl *gomock.Controller) *MockUser { + return &MockUser{ + ctrl: ctrl, + name: "testUser", + active: true, + } +} + +func (m *MockUser) Name() string { return m.name } +func (m *MockUser) IsActive() bool { return m.active } +func (*MockUser) Extra(any) error { return nil } + +func (*MockUser) AccessibleDatabases(context.Context) (map[string]arangodb.Grant, error) { + return nil, nil +} + +func (*MockUser) AccessibleDatabasesFull(context.Context) (map[string]arangodb.DatabasePermissions, error) { + return nil, nil +} + +func (*MockUser) GetDatabaseAccess(context.Context, string) (arangodb.Grant, error) { + return arangodb.GrantNone, nil +} + +func (*MockUser) GetCollectionAccess(context.Context, string, string) (arangodb.Grant, error) { + return arangodb.GrantNone, nil +} + +func (*MockUser) SetDatabaseAccess(context.Context, string, arangodb.Grant) error { + return nil +} + +func (*MockUser) SetCollectionAccess(context.Context, string, string, arangodb.Grant) error { + return nil +} + +func (*MockUser) RemoveDatabaseAccess(context.Context, string) error { + return nil +} + +func (*MockUser) RemoveCollectionAccess(context.Context, string, string) error { + return nil +} diff --git a/pkg/gofr/external_db.go b/pkg/gofr/external_db.go index e8cc5112a..a6bda92ba 100644 --- a/pkg/gofr/external_db.go +++ b/pkg/gofr/external_db.go @@ -145,6 +145,7 @@ func (a *App) AddOpenTSDB(db container.OpenTSDBProvider) { a.container.OpenTSDB = db } +// AddScyllaDB sets the ScyllaDB datasource in the app's container. func (a *App) AddScyllaDB(db container.ScyllaDBProvider) { // Create the ScyllaDB client with the provided configuration db.UseLogger(a.Logger()) @@ -156,6 +157,23 @@ func (a *App) AddScyllaDB(db container.ScyllaDBProvider) { a.container.ScyllaDB = db } +// AddArangoDB sets the ArangoDB datasource in the app's container. +func (a *App) AddArangoDB(db container.ArangoDBProvider) { + // Set up logger, metrics, and tracer + db.UseLogger(a.Logger()) + db.UseMetrics(a.Metrics()) + + // Get tracer from OpenTelemetry + tracer := otel.GetTracerProvider().Tracer("gofr-arangodb") + db.UseTracer(tracer) + + // Connect to ArangoDB + db.Connect() + + // Add the ArangoDB provider to the container + a.container.ArangoDB = db +} + func (a *App) AddSurrealDB(db container.SurrealBDProvider) { db.UseLogger(a.Logger()) db.UseMetrics(a.Metrics()) diff --git a/pkg/gofr/external_db_test.go b/pkg/gofr/external_db_test.go index 4d5e4accd..f1bea39f0 100644 --- a/pkg/gofr/external_db_test.go +++ b/pkg/gofr/external_db_test.go @@ -1,6 +1,7 @@ package gofr import ( + "strconv" "testing" "github.com/stretchr/testify/assert" @@ -203,3 +204,26 @@ func TestApp_AddScyllaDB(t *testing.T) { assert.Equal(t, mock, app.container.ScyllaDB) }) } + +func TestApp_AddArangoDB(t *testing.T) { + t.Run("Adding ArangoDB", func(t *testing.T) { + port := testutil.GetFreePort(t) + t.Setenv("METRICS_PORT", strconv.Itoa(port)) + + app := New() + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mock := container.NewMockArangoDBProvider(ctrl) + + mock.EXPECT().UseLogger(app.Logger()) + mock.EXPECT().UseMetrics(app.Metrics()) + mock.EXPECT().UseTracer(otel.GetTracerProvider().Tracer("gofr-arangodb")) + mock.EXPECT().Connect() + + app.AddArangoDB(mock) + + assert.Equal(t, mock, app.container.ArangoDB) + }) +}