←Back to Documentation
Go SDK
High-performance Go client for entropyDB with goroutine support
Overview
The Go SDK provides:
- • High Performance: Optimized for concurrency
- • Context Support: Cancellation and timeouts
- • Connection Pooling: Efficient resource management
- • Query Builder: Type-safe query construction
- • Zero-Copy: Memory-efficient operations
Installation
# Install the SDK
go get github.com/entropydb/entropydb-go
# Import in your code
import (
"github.com/entropydb/entropydb-go"
"github.com/entropydb/entropydb-go/query"
)Basic Usage
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/entropydb/entropydb-go"
)
type User struct {
ID int64 `db:"id"`
Username string `db:"username"`
Email string `db:"email"`
CreatedAt time.Time `db:"created_at"`
}
func main() {
// Connect to entropyDB
config := entropydb.Config{
Host: "localhost",
Port: 5432,
Database: "mydb",
User: "admin",
Password: "password",
PoolSize: 20,
}
client, err := entropydb.NewClient(config)
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
// Create table
_, err = client.Exec(ctx, `
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
email TEXT UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
)
`)
if err != nil {
log.Fatal(err)
}
// Insert data
result, err := client.Exec(ctx,
"INSERT INTO users (username, email) VALUES ($1, $2)",
"alice", "alice@example.com")
if err != nil {
log.Fatal(err)
}
rowsAffected := result.RowsAffected()
fmt.Printf("Inserted %d row(s)\n", rowsAffected)
// Query single row
var user User
err = client.QueryRow(ctx,
"SELECT id, username, email, created_at FROM users WHERE username = $1",
"alice").Scan(&user.ID, &user.Username, &user.Email, &user.CreatedAt)
if err != nil {
log.Fatal(err)
}
fmt.Printf("User: %+v\n", user)
// Query multiple rows
rows, err := client.Query(ctx,
"SELECT id, username, email FROM users WHERE email LIKE $1",
"%@example.com")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var users []User
for rows.Next() {
var u User
if err := rows.Scan(&u.ID, &u.Username, &u.Email); err != nil {
log.Fatal(err)
}
users = append(users, u)
}
fmt.Printf("Found %d users\n", len(users))
}Connection Pooling
package main
import (
"context"
"time"
"github.com/entropydb/entropydb-go"
)
func main() {
config := entropydb.Config{
Host: "localhost",
Port: 5432,
Database: "mydb",
User: "admin",
Password: "password",
// Pool configuration
PoolSize: 20, // Maximum connections
MinConns: 5, // Minimum idle connections
MaxConnLifetime: 30 * time.Minute,
MaxConnIdleTime: 5 * time.Minute,
ConnectTimeout: 10 * time.Second,
// Performance tuning
PreferSimpleProtocol: false,
StatementCacheSize: 100,
}
client, err := entropydb.NewClient(config)
if err != nil {
panic(err)
}
defer client.Close()
// Get pool stats
stats := client.Stats()
fmt.Printf("Acquired connections: %d\n", stats.AcquiredConns)
fmt.Printf("Idle connections: %d\n", stats.IdleConns)
fmt.Printf("Total connections: %d\n", stats.TotalConns)
}Query Builder
package main
import (
"github.com/entropydb/entropydb-go/query"
)
func main() {
// Build SELECT query
q := query.Select("id", "username", "email").
From("users").
Where("email LIKE ?", "%@example.com").
And("created_at > ?", time.Now().AddDate(0, 0, -7)).
OrderBy("created_at DESC").
Limit(10)
sql, args := q.Build()
// sql: SELECT id, username, email FROM users WHERE email LIKE $1 AND created_at > $2 ORDER BY created_at DESC LIMIT 10
rows, err := client.Query(ctx, sql, args...)
// Build INSERT query
q = query.Insert("users").
Columns("username", "email").
Values("bob", "bob@example.com").
Returning("id")
var id int64
err = client.QueryRow(ctx, q.Build()).Scan(&id)
// Build UPDATE query
q = query.Update("users").
Set("email", "newemail@example.com").
Where("username = ?", "bob").
Returning("*")
// Build DELETE query
q = query.Delete("users").
Where("created_at < ?", time.Now().AddDate(0, 0, -365))
result, err := client.Exec(ctx, q.Build())
// Complex queries with joins
q = query.Select("u.username", "o.total").
From("users u").
Join("orders o", "u.id = o.user_id").
Where("o.status = ?", "completed").
GroupBy("u.username", "o.total").
Having("o.total > ?", 100)
}Transactions
package main
import (
"context"
"github.com/entropydb/entropydb-go"
)
func transferFunds(ctx context.Context, client *entropydb.Client, fromID, toID int64, amount float64) error {
// Begin transaction
tx, err := client.BeginTx(ctx, &entropydb.TxOptions{
IsolationLevel: entropydb.Serializable,
})
if err != nil {
return err
}
defer tx.Rollback(ctx)
// Debit from source account
_, err = tx.Exec(ctx,
"UPDATE accounts SET balance = balance - $1 WHERE id = $2",
amount, fromID)
if err != nil {
return err
}
// Credit to destination account
_, err = tx.Exec(ctx,
"UPDATE accounts SET balance = balance + $1 WHERE id = $2",
amount, toID)
if err != nil {
return err
}
// Record transaction
_, err = tx.Exec(ctx,
"INSERT INTO transfers (from_account, to_account, amount) VALUES ($1, $2, $3)",
fromID, toID, amount)
if err != nil {
return err
}
// Commit transaction
return tx.Commit(ctx)
}
// Using context timeout
func queryWithTimeout() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
rows, err := client.Query(ctx, "SELECT * FROM large_table")
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
log.Println("Query timed out")
}
}
}Concurrency with Goroutines
package main
import (
"context"
"sync"
)
func concurrentInserts(client *entropydb.Client, records []User) error {
ctx := context.Background()
var wg sync.WaitGroup
errChan := make(chan error, len(records))
// Process records concurrently
for _, user := range records {
wg.Add(1)
go func(u User) {
defer wg.Done()
_, err := client.Exec(ctx,
"INSERT INTO users (username, email) VALUES ($1, $2)",
u.Username, u.Email)
if err != nil {
errChan <- err
}
}(user)
}
// Wait for all goroutines
wg.Wait()
close(errChan)
// Check for errors
for err := range errChan {
if err != nil {
return err
}
}
return nil
}
// Worker pool pattern
func workerPool(client *entropydb.Client) {
ctx := context.Background()
jobs := make(chan int, 100)
results := make(chan string, 100)
// Start workers
var wg sync.WaitGroup
for w := 0; w < 10; w++ {
wg.Add(1)
go func() {
defer wg.Done()
for id := range jobs {
var username string
err := client.QueryRow(ctx,
"SELECT username FROM users WHERE id = $1",
id).Scan(&username)
if err == nil {
results <- username
}
}
}()
}
// Send jobs
for i := 1; i <= 100; i++ {
jobs <- i
}
close(jobs)
// Wait for completion
go func() {
wg.Wait()
close(results)
}()
// Collect results
for username := range results {
fmt.Println(username)
}
}Best Practices
Performance
- • Use connection pooling
- • Enable statement caching
- • Use context for cancellation
- • Batch operations when possible
Concurrency
- • Share client, not connections
- • Use worker pools for bulk operations
- • Handle errors from goroutines
- • Set appropriate timeouts