# How to Configure Database Actions Using the Probe DB Plugin: A Complete Guide

> Configure database actions in Probe using the DB plugin. Learn to define workflow steps with a DSN, SQL query, and parameters for seamless database integration.

- Repository: [Tomohisa Oda/probe](https://github.com/linyows/probe)
- Tags: how-to-guide
- Published: 2026-03-06

---

**You configure database actions in Probe by defining workflow steps with `uses: db` and providing a URL-style DSN, SQL query, and optional parameters in the `with` block.**

The Probe DB plugin, part of the `linyows/probe` repository, enables direct SQL execution against MySQL, PostgreSQL, and SQLite databases within your automation workflows. This guide explains how to configure database actions using the Probe DB plugin by examining the source implementation in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go) and practical examples from the official repository.

## Understanding the Probe DB Plugin Architecture

The plugin follows a structured execution pipeline defined in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go). Understanding these internals ensures you configure database actions correctly and debug issues effectively.

### Request Parsing and Validation

The `ParseRequest` function (lines 43-86 in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go)) validates your configuration before execution. It checks for required fields, expands the `timeout` string into a Go `time.Duration`, and extracts the driver-specific DSN from your URL-style connection string.

### DSN Conversion and Driver Detection

The `parseDSN` function (lines 96-161) handles database-specific connection string transformations:

- **MySQL**: Converts `mysql://user:pass@host:port/db` to `user:pass@tcp(host:port)/db`
- **PostgreSQL**: Normalizes `postgres://` or `postgresql://` schemes
- **SQLite**: Supports `file:./path/to/file.db` for file-based databases and `file::memory:` for in-memory operations

### Query Execution Flow

After opening the database with `sql.Open`, the plugin detects query type (lines 86-93). SELECT statements route to `executeSelectQuery`, while INSERT, UPDATE, DELETE, and DDL statements use `executeNonSelectQuery`. Results convert to `map[string]any` via `probe.StructToMapByTags` for uniform handling.

## Configuring Database Connections with DSN Strings

Proper DSN configuration is critical when you configure database actions using the Probe DB plugin. The plugin requires URL-style connection strings that it converts internally to driver-specific formats.

### MySQL DSN Format

Use the `mysql://` scheme with standard URL encoding:

```yaml
dsn: "mysql://admin:secret@localhost:3306/production"

```

The `parseDSN` function strips the scheme and reconstructs the DSN using Go's `mysql` driver format: `user:pass@tcp(host:port)/dbname`.

### PostgreSQL DSN Format

PostgreSQL connections accept both `postgres://` and `postgresql://` schemes:

```yaml
dsn: "postgres://user:password@db.example.com:5432/inventory?sslmode=disable"

```

The plugin normalizes `postgresql://` to `postgres://` internally while preserving all query parameters like `sslmode`.

### SQLite File and In-Memory Modes

SQLite supports two operational modes via the `file:` scheme:

**File-based database:**

```yaml
dsn: "file:./testdata/my.db"

```

**In-memory database:**

```yaml
dsn: "file::memory:"

```

Both variants pass through `parseDSN` with the `sqlite3` driver designation.

## Writing SQL Queries and Parameters

When you configure database actions using the Probe DB plugin, you define SQL operations through the `query` and `params` fields in your workflow step.

### Parameterized Queries

The plugin supports positional parameters using `?` placeholders for MySQL and SQLite, or `$1`, `$2` syntax for PostgreSQL:

```yaml
- name: Insert User
  uses: db
  with:
    dsn: "file:./app.db"
    query: "INSERT INTO users (name, email) VALUES (?, ?)"
    params:
      - Jane Smith
      - jane@example.com

```

The `params` array accepts any JSON-compatible type, which `ParseRequest` validates before execution.

### Query Type Detection

The plugin automatically determines execution strategy based on query prefix:

- **SELECT queries**: Return result sets as arrays of maps
- **Non-SELECT queries**: Return `rows_affected` counts

This detection occurs in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go) (lines 86-93) without requiring explicit configuration.

## Complete Configuration Examples

These practical implementations demonstrate how to configure database actions using the Probe DB plugin across different database engines.

### SQLite Workflow Example

The [`examples/sqlite.yml`](https://github.com/linyows/probe/blob/main/examples/sqlite.yml) file in the repository demonstrates full CRUD operations:

```yaml
name: SQLite Database Examples
jobs:
- name: SQLite Examples
  defaults:
    db:
      dsn: file:./testdata/sqlite.db
  steps:
  - name: Create table
    uses: db
    with:
      query: |
        CREATE TABLE users (
          id INTEGER PRIMARY KEY,
          name TEXT NOT NULL,
          email TEXT UNIQUE
        )
  - name: Insert a row
    uses: db
    with:
      query: INSERT INTO users (name, email) VALUES (?, ?)
      params:
        - John Doe
        - john@example.com
  - name: Select all
    uses: db
    with:
      query: SELECT * FROM users
    test: res.code == 0 && res.rows_affected > 0

```

### MySQL Query Configuration

```yaml
- name: MySQL Query
  uses: db
  with:
    dsn: "mysql://admin:secret@localhost:3306/sales"
    query: "SELECT order_id, total FROM orders WHERE status = ?"
    params: ["completed"]
    timeout: "15s"

```

### PostgreSQL Update Example

```yaml
- name: PostgreSQL Update
  uses: db
  with:
    dsn: "postgres://bob:pwd@db.example.com:5432/inventory?sslmode=disable"
    query: "UPDATE products SET stock = stock - $1 WHERE id = $2"
    params: [5, 42]

```

## Implementing Callbacks for Custom Logic

The DB plugin supports optional callbacks for pre-execution validation and post-execution processing. These are defined in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go) (lines 35-42) and wired into `ExecuteQuery` (lines 42-55).

```go
probe.ExecuteQuery(
    map[string]any{
        "dsn":   "file::memory:",
        "query": "SELECT 1",
    },
    probe.WithBefore(func(q string, p []any) {
        fmt.Println("About to run:", q, "with", p)
    }),
    probe.WithAfter(func(r *probe.Result) {
        fmt.Printf("Query finished in %v, rows: %d\n", r.RT, r.Res.RowsAffected)
    }),
)

```

Use `WithBefore` for logging or parameter sanitization, and `WithAfter` for custom result handling or metrics collection.

## Summary

- **The Probe DB plugin** enables SQL execution against MySQL, PostgreSQL, and SQLite through URL-style DSN configuration in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go).
- **DSN formats** require specific schemes: `mysql://` for MySQL, `postgres://` for PostgreSQL, and `file:` for SQLite (including `file::memory:` for in-memory databases).
- **Query execution** supports parameterized statements with automatic SELECT vs. non-SELECT detection, returning results as generic maps via `probe.StructToMapByTags`.
- **Optional callbacks** (`WithBefore`, `WithAfter`) allow custom logic injection at lines 35-55 of [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go).

## Frequently Asked Questions

### What database drivers does the Probe DB plugin support?

The plugin supports **MySQL**, **PostgreSQL**, and **SQLite** through Go's standard `sql` package. The `parseDSN` function in [`db/client.go`](https://github.com/linyows/probe/blob/main/db/client.go) (lines 96-161) handles driver-specific connection string transformations for each database type.

### How do I use in-memory SQLite databases with Probe?

Specify `file::memory:` as your DSN value. This creates a temporary in-memory database that persists for the duration of the workflow step. The `parseDSN` function recognizes this pattern and passes it to the `sqlite3` driver without modification.

### Can I use named parameters in my SQL queries?

No, the plugin currently supports only **positional parameters**. Use `?` placeholders for MySQL and SQLite, or `$1`, `$2` syntax for PostgreSQL. The `params` array in your configuration must match the number of placeholders in your query string.

### What happens if my database query times out?

The plugin respects the `timeout` field specified in your step configuration. If the query exceeds this duration, the execution fails and returns an error result. The timeout string accepts Go duration formats like `30s` or `2m`, or plain integers interpreted as seconds.