postgres

package
v0.2.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: MIT Imports: 9 Imported by: 0

README

PostgreSQL DataStore Client

A PostgreSQL implementation of the DataStore interface for the Agent SDK.

Features

  • Full CRUD operations (Create, Read, Update, Delete)
  • Query support with filtering, ordering, limit, and offset
  • Multi-tenancy support with organization ID isolation
  • Transaction support for atomic operations
  • Automatic ID generation and timestamp management

Installation

go get github.com/lib/pq

Usage

Basic Setup
import (
    "context"
    "github.com/Ingenimax/agent-sdk-go/pkg/datastore/postgres"
    "github.com/Ingenimax/agent-sdk-go/pkg/multitenancy"
)

// Create a new PostgreSQL client
client, err := postgres.New("postgres://user:password@localhost:5432/dbname?sslmode=disable")
if err != nil {
    log.Fatal(err)
}
defer client.Close()
Using an Existing Database Connection
import (
    "database/sql"
    _ "github.com/lib/pq"
)

// Create database connection
db, err := sql.Open("postgres", "postgres://user:password@localhost:5432/dbname?sslmode=disable")
if err != nil {
    log.Fatal(err)
}

// Create client with existing connection
client, err := postgres.NewWithDB(db)
if err != nil {
    log.Fatal(err)
}
defer client.Close()
CRUD Operations
// Create a context with organization ID
ctx := multitenancy.WithOrgID(context.Background(), "org-123")

// Get a collection reference
collection := client.Collection("users")

// Insert a document
data := map[string]interface{}{
    "name":  "John Doe",
    "email": "john@example.com",
    "age":   30,
}
id, err := collection.Insert(ctx, data)

// Get a document by ID
doc, err := collection.Get(ctx, id)

// Update a document
updateData := map[string]interface{}{
    "age": 31,
}
err = collection.Update(ctx, id, updateData)

// Delete a document
err = collection.Delete(ctx, id)
Query Operations
import "github.com/Ingenimax/agent-sdk-go/pkg/interfaces"

// Query with filter
docs, err := collection.Query(ctx, map[string]interface{}{
    "status": "active",
})

// Query with limit and offset
docs, err := collection.Query(ctx,
    map[string]interface{}{"status": "active"},
    interfaces.QueryWithLimit(10),
    interfaces.QueryWithOffset(20),
)

// Query with ordering
docs, err := collection.Query(ctx,
    map[string]interface{}{"status": "active"},
    interfaces.QueryWithOrderBy("created_at", "desc"),
    interfaces.QueryWithLimit(10),
)
Transactions
err := client.Transaction(ctx, func(tx interfaces.Transaction) error {
    collection := tx.Collection("users")

    // Insert document in transaction
    id1, err := collection.Insert(ctx, map[string]interface{}{
        "name": "Alice",
    })
    if err != nil {
        return err
    }

    // Update document in transaction
    err = collection.Update(ctx, id1, map[string]interface{}{
        "status": "active",
    })
    if err != nil {
        return err
    }

    // If any operation fails, the entire transaction will be rolled back
    return nil
})

Database Schema Requirements

All tables should have the following columns:

  • id (TEXT or UUID): Primary key
  • org_id (TEXT): Organization ID for multi-tenancy
  • created_at (TIMESTAMP): Creation timestamp (automatically set)
  • updated_at (TIMESTAMP): Last update timestamp (automatically set on update)

Example table creation:

CREATE TABLE users (
    id TEXT PRIMARY KEY,
    org_id TEXT NOT NULL,
    name TEXT NOT NULL,
    email TEXT NOT NULL,
    age INTEGER,
    created_at TIMESTAMP NOT NULL,
    updated_at TIMESTAMP,
    INDEX idx_org_id (org_id)
);

Environment Variables

For testing, set the following environment variable:

# Local development (SSL disabled)
export POSTGRES_URL="postgres://user:password@localhost:5432/dbname?sslmode=disable"

# Production (SSL enabled)
export POSTGRES_URL="postgres://user:password@host:5432/dbname?sslmode=require"
SSL Configuration

PostgreSQL SSL modes:

  • sslmode=disable - No SSL (local development only)
  • sslmode=require - Require SSL but don't verify certificate
  • sslmode=verify-ca - Require SSL and verify certificate authority
  • sslmode=verify-full - Require SSL and verify certificate + hostname (recommended for production)

Multi-Tenancy

All operations automatically filter by organization ID from the context. To set the organization ID:

ctx := multitenancy.WithOrgID(context.Background(), "your-org-id")

Error Handling

The client returns descriptive errors for common scenarios:

  • Document not found
  • Document not owned by organization
  • Database connection errors
  • Query execution errors

Always check for errors and handle them appropriately:

doc, err := collection.Get(ctx, id)
if err != nil {
    if strings.Contains(err.Error(), "document not found") {
        // Handle not found case
    } else {
        // Handle other errors
    }
}

Testing

Run the tests with:

export POSTGRES_URL="postgres://user:password@localhost:5432/testdb?sslmode=disable"
go test ./pkg/datastore/postgres/...

Make sure you have a PostgreSQL database running and accessible with the connection string provided.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client implements the DataStore interface for PostgreSQL

func New

func New(connectionString string, options ...Option) (*Client, error)

New creates a new PostgreSQL client

func NewWithDB

func NewWithDB(db *sql.DB) (*Client, error)

NewWithDB creates a new PostgreSQL client with an existing database connection

func (*Client) Close

func (c *Client) Close() error

Close closes the database connection

func (*Client) Collection

func (c *Client) Collection(name string) interfaces.CollectionRef

Collection returns a reference to a specific collection/table

func (*Client) Transaction

func (c *Client) Transaction(ctx context.Context, fn func(tx interfaces.Transaction) error) error

Transaction executes multiple operations in a transaction

type Collection

type Collection struct {
	// contains filtered or unexported fields
}

Collection represents a reference to a collection/table

func (*Collection) Delete

func (c *Collection) Delete(ctx context.Context, id string) error

Delete deletes a document by ID

func (*Collection) Get

func (c *Collection) Get(ctx context.Context, id string) (map[string]interface{}, error)

Get retrieves a document by ID

func (*Collection) Insert

func (c *Collection) Insert(ctx context.Context, data map[string]interface{}) (string, error)

Insert inserts a document into the collection

func (*Collection) Query

func (c *Collection) Query(ctx context.Context, filter map[string]interface{}, options ...interfaces.QueryOption) ([]map[string]interface{}, error)

Query queries documents in the collection

func (*Collection) Update

func (c *Collection) Update(ctx context.Context, id string, data map[string]interface{}) error

Update updates a document by ID

type Option

type Option func(*Client)

Option represents an option for configuring the client

type Transaction

type Transaction struct {
	// contains filtered or unexported fields
}

Transaction represents a database transaction

func (*Transaction) Collection

func (t *Transaction) Collection(name string) interfaces.CollectionRef

Collection returns a reference to a specific collection/table within the transaction

func (*Transaction) Commit

func (t *Transaction) Commit() error

Commit commits the transaction

func (*Transaction) Rollback

func (t *Transaction) Rollback() error

Rollback rolls back the transaction

type TransactionCollection

type TransactionCollection struct {
	// contains filtered or unexported fields
}

TransactionCollection represents a collection within a transaction

func (*TransactionCollection) Delete

func (c *TransactionCollection) Delete(ctx context.Context, id string) error

Delete deletes a document by ID within a transaction

func (*TransactionCollection) Get

func (c *TransactionCollection) Get(ctx context.Context, id string) (map[string]interface{}, error)

Get retrieves a document by ID within a transaction

func (*TransactionCollection) Insert

func (c *TransactionCollection) Insert(ctx context.Context, data map[string]interface{}) (string, error)

Insert inserts a document into the collection within a transaction

func (*TransactionCollection) Query

func (c *TransactionCollection) Query(ctx context.Context, filter map[string]interface{}, options ...interfaces.QueryOption) ([]map[string]interface{}, error)

Query queries documents in the collection within a transaction

func (*TransactionCollection) Update

func (c *TransactionCollection) Update(ctx context.Context, id string, data map[string]interface{}) error

Update updates a document by ID within a transaction

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL