Skip to content

Commit

Permalink
Add support to the Scylladb (#1360)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chandanaschandu authored Jan 17, 2025
1 parent ee75965 commit 5c2080a
Show file tree
Hide file tree
Showing 19 changed files with 2,683 additions and 2 deletions.
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ docker run --name kafka-1 -p 9092:9092 \
-e ALLOW_PLAINTEXT_LISTENER=yes \
-e KAFKA_CFG_NODE_ID=1 \
-v kafka_data:/bitnami \
bitnami/kafka:3.4

bitnami/kafka:3.4
docker pull scylladb/scylla
docker run --name scylla -d -p 2025:9042 scylladb/scylla



Expand Down
121 changes: 121 additions & 0 deletions docs/advanced-guide/injecting-databases-drivers/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,4 +712,125 @@ func queryDataPoints(c *gofr.Context) (any, error) {
}
return queryResp.QueryRespCnts, nil
}
```


## ScyllaDB


GoFr supports pluggable ScyllaDB drivers. It defines an interface that specifies the required methods for interacting
with ScyllaDB. Any driver implementation that adheres to this interface can be integrated into GoFr using the
`app.AddScyllaDB()` method.

```go
type ScyllaDB interface {
// Query executes a CQL (Cassandra Query Language) query on the ScyllaDB cluster
// and stores the result in the provided destination variable `dest`.
// Accepts pointer to struct or slice as dest parameter for single and multiple
Query(dest any, stmt string, values ...any) error
// QueryWithCtx executes the query with a context and binds the result into dest parameter.
// Accepts pointer to struct or slice as dest parameter for single and multiple rows retrieval respectively.
QueryWithCtx(ctx context.Context, dest any, stmt string, values ...any) error
// Exec executes a CQL statement (e.g., INSERT, UPDATE, DELETE) on the ScyllaDB cluster without returning any result.
Exec(stmt string, values ...any) error
// ExecWithCtx executes a CQL statement with the provided context and without returning any result.
ExecWithCtx(ctx context.Context, stmt string, values ...any) error
// ExecCAS executes a lightweight transaction (i.e. an UPDATE or INSERT statement containing an IF clause).
// If the transaction fails because the existing values did not match, the previous values will be stored in dest.
// Returns true if the query is applied otherwise false.
// Returns false and error if any error occur while executing the query.
// Accepts only pointer to struct and built-in types as the dest parameter.
ExecCAS(dest any, stmt string, values ...any) (bool, error)
// NewBatch initializes a new batch operation with the specified name and batch type.
NewBatch(name string, batchType int) error
// NewBatchWithCtx takes context,name and batchtype and return error.
NewBatchWithCtx(_ context.Context, name string, batchType int) error
// BatchQuery executes a batch query in the ScyllaDB cluster with the specified name, statement, and values.
BatchQuery(name, stmt string, values ...any) error
// BatchQueryWithCtx executes a batch query with the provided context.
BatchQueryWithCtx(ctx context.Context, name, stmt string, values ...any) error
// ExecuteBatchWithCtx executes a batch with context and name returns error.
ExecuteBatchWithCtx(ctx context.Context, name string) error
// HealthChecker defines the HealthChecker interface.
HealthChecker
}

```


Import the gofr's external driver for ScyllaDB:

```shell
go get gofr.dev/pkg/gofr/datasource/scylladb
```

```go
package main

import (
"github.com/gocql/gocql"

"gofr.dev/pkg/gofr"
"gofr.dev/pkg/gofr/datasource/scylladb"
"gofr.dev/pkg/gofr/http"
)

type User struct {
ID gocql.UUID `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}

func main() {
app := gofr.New()

client := scylladb.New(scylladb.Config{
Host: "localhost",
Keyspace: "my_keyspace",
Port: 2025,
Username: "root",
Password: "password",
})

app.AddScyllaDB(client)

app.GET("/users/{id}", getUser)
app.POST("/users", addUser)

app.Run()

}

func addUser(c *gofr.Context) (interface{}, error) {
var newUser User
err := c.Bind(&newUser)
if err != nil {
return nil, err
}
_ = c.ScyllaDB.ExecWithCtx(c, `INSERT INTO users (user_id, username, email) VALUES (?, ?, ?)`, newUser.ID, newUser.Name, newUser.Email)

return newUser, nil

}

func getUser(c *gofr.Context) (interface{}, error) {
var user User
id := c.PathParam("id")

userID, err := gocql.ParseUUID(id)
if err != nil {
c.Logger.Error("Invalid UUID format:", err)
return nil, err
}

err = c.ScyllaDB.QueryWithCtx(c, &user, "SELECT id, name, email FROM users WHERE id = ?", userID)
if err != nil {
c.Logger.Error("Error querying user:", err)
return nil, err
}

return user, nil
}


```
1 change: 1 addition & 0 deletions pkg/gofr/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Container struct {
Solr Solr
DGraph Dgraph
OpenTSDB OpenTSDB
ScyllaDB ScyllaDB

KVStore KVStore

Expand Down
37 changes: 37 additions & 0 deletions pkg/gofr/container/datasources.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,40 @@ type OpenTSDB interface {
// - Error if parameters are invalid, response parsing fails, or if connectivity issues occur.
DeleteAnnotation(ctx context.Context, annotation any, res any) error
}

type ScyllaDB interface {
// Query executes a CQL (Cassandra Query Language) query on the ScyllaDB cluster
// and stores the result in the provided destination variable `dest`.
// Accepts pointer to struct or slice as dest parameter for single and multiple
Query(dest any, stmt string, values ...any) error
// QueryWithCtx executes the query with a context and binds the result into dest parameter.
// Accepts pointer to struct or slice as dest parameter for single and multiple rows retrieval respectively.
QueryWithCtx(ctx context.Context, dest any, stmt string, values ...any) error
// Exec executes a CQL statement (e.g., INSERT, UPDATE, DELETE) on the ScyllaDB cluster without returning any result.
Exec(stmt string, values ...any) error
// ExecWithCtx executes a CQL statement with the provided context and without returning any result.
ExecWithCtx(ctx context.Context, stmt string, values ...any) error
// ExecCAS executes a lightweight transaction (i.e. an UPDATE or INSERT statement containing an IF clause).
// If the transaction fails because the existing values did not match, the previous values will be stored in dest.
// Returns true if the query is applied otherwise false.
// Returns false and error if any error occur while executing the query.
// Accepts only pointer to struct and built-in types as the dest parameter.
ExecCAS(dest any, stmt string, values ...any) (bool, error)
// NewBatch initializes a new batch operation with the specified name and batch type.
NewBatch(name string, batchType int) error
// NewBatchWithCtx takes context,name and batchtype and return error.
NewBatchWithCtx(_ context.Context, name string, batchType int) error
// BatchQuery executes a batch query in the ScyllaDB cluster with the specified name, statement, and values.
BatchQuery(name, stmt string, values ...any) error
// BatchQueryWithCtx executes a batch query with the provided context.
BatchQueryWithCtx(ctx context.Context, name, stmt string, values ...any) error
// ExecuteBatchWithCtx executes a batch with context and name returns error.
ExecuteBatchWithCtx(ctx context.Context, name string) error
// HealthChecker defines the HealthChecker interface.
HealthChecker
}

type ScyllaDBProvider interface {
ScyllaDB
provider
}
Loading

0 comments on commit 5c2080a

Please sign in to comment.