sqlset

package module
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Jan 12, 2026 License: MIT Imports: 8 Imported by: 0

README

SQLSet

Go Reference Portfolio

SQLSet is a simple Go library that provides a convenient way to manage and access SQL queries stored in .sql files. It allows you to separate your SQL code from your Go code, making it cleaner and more maintainable.

Features

  • Decouple SQL from Go code: Keep your SQL queries in separate .sql files.
  • Easy to use: A simple API to get your queries.
  • Flexible: Works with any fs.FS, including embed.FS for bundling queries with your application.
  • Query Metadata: Associate names and descriptions with your query sets.
  • Organized: Structure your queries into logical sets.

Installation

go get github.com/istovpets/sqlset

Usage

  1. Create your SQL files.

Create a directory (e.g., queries) and add your .sql files. Each file represents a "query set". The name of the file (without the .sql extension) becomes the query set ID.

Inside each file, define your queries using a special --META comment for metadata and --SQL: comments to mark the beginning of each query.

End the query or metadata block with a special comment --end

queries/users.sql

--META
{
    "name": "User Queries",
    "description": "A set of queries for user management."
}
--end

--SQL:GetUserByID
SELECT id, name, email FROM users WHERE id = ?;
--end

--SQL:CreateUser
INSERT INTO users (name, email) VALUES (?, ?);
--end
  1. Embed and load the queries in your Go application.

Use Go's embed package to bundle the SQL files directly into your application binary.

package main

import (
	"embed"
	"fmt"
	"log"

	"github.com/stoi/sqlset"
)

//go:embed queries
var queriesFS embed.FS

func main() {
	// Create a new SQLSet from the embedded filesystem.
	// We pass "queries" as the subdirectory to look into.
	sqlSet, err := sqlset.New(queriesFS)
	if err != nil {
		log.Fatalf("Failed to create SQL set: %v", err)
	}

	// Get a specific query
	query, err := sqlSet.Get("users", "GetUserByID")
	if err != nil {
		log.Fatalf("Failed to get query: %v", err)
	}
	fmt.Println("GetUserByID query:", query)

	// Or, panic if the query is not found
	query = sqlSet.MustGet("users", "CreateUser")
	fmt.Println("CreateUser query:", query)

	// You can also get a query with a single argument if there is only one query set
	query, err = sqlSet.Get("GetUserByID")
	if err != nil {
		log.Fatalf("Failed to get query with single argument: %v", err)
	}
	fmt.Println("GetUserByID query (single arg):", query)

	// Or using dot notation
	query, err = sqlSet.Get("users.GetUserByID")
	if err != nil {
		log.Fatalf("Failed to get query with dot notation: %v", err)
	}
	fmt.Println("GetUserByID query (dot notation):", query)

    // You can also retrieve metadata for all query sets
    metas := sqlSet.GetSetsMetas()
    for _, meta := range metas {
        fmt.Printf("Set ID: %s, Name: %s, Description: %s\n", meta.ID, meta.Name, meta.Description)
    }

    // You can get a list of all query IDs in a specific set
    queryIDs, err := sqlSet.GetQueryIDs("users")
    if err != nil {
        log.Fatalf("Failed to get query IDs: %v", err)
    }
    fmt.Println("Query IDs in 'users' set:", queryIDs) // Output: [CreateUser GetUserByID] (sorted)
}

Add to your project (e.g. queries/queries.go):

//go:generate go run github.com/istovpets/sqlset/cmd/sqlset-gen@latest --dir=queries --out=queries/constants.go --pkg=queries

Or recommended (fixed version in go.mod) — add to tools.go:

//go:build tools

package tools

import (
    _ "github.com/istovpets/sqlset/cmd/sqlset-gen"
)

And use:

//go:generate sqlset-gen --dir=queries --out=queries/constants.go --pkg=queries

Then run:

go generate ./...

This will create queries/constants.go with safe constants:

package consts

// Code generated by sqlset-gen. DO NOT EDIT.
// Source: github.com/istovpets/sqlset.

// Generated by this command:
// go run github.com/istovpets/sqlset/cmd/sqlset-gen --dir=../queries/ --out=queries-gen.go --pkg=consts

// users.sql
var Users = struct {
	CreateUser  string
	GetUserByID string
}{
	CreateUser:  "users.CreateUser",
	GetUserByID: "users.GetUserByID",
}

Using generated constants is type safe.

File Format Specification
  • Metadata Block (Optional):

    • Starts with --META.
    • Followed by a JSON object containing id (string, optional), name (string, optional) and description (string, optional).
    • There can be only one metadata block per file.
    • End with --end.
  • Query Block (Required):

    • Starts with --SQL:<query_id>, where <query_id> is the unique identifier for the query within the file.
    • The SQL statement follows on the next lines.
    • All text until the next --end block is considered part of the query.

Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you want to contribute code, please open a pull request.

  1. Fork the repository.
  2. Create a new branch (git checkout -b feature/your-feature).
  3. Make your changes.
  4. Commit your changes (git commit -am 'Add some feature').
  5. Push to the branch (git push origin feature/your-feature).
  6. Create a new Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package sqlset is a way to store SQL queries separated from the go code. Query sets are stored in the .sql files, every filename without extension is an SQL set ID. Every file contains queries, marked with query IDs using special syntax, see `testdata/valid/*.sql` files for examples. Also file may contain JSON-encoded query set metadata with name and description.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrEmpty is the base error for when an object is empty.
	ErrEmpty = errors.New("empty")
	// ErrArgumentEmpty indicates that a argument is empty.
	ErrArgumentEmpty = fmt.Errorf("argument %w", ErrEmpty)
	// ErrQuerySetsEmpty indicates that a query sets is empty.
	ErrQuerySetsEmpty = fmt.Errorf("query sets %w", ErrEmpty)
	// ErrQuerySetEmpty indicates that a query sets is empty.
	ErrQuerySetEmpty = fmt.Errorf("query set %w", ErrEmpty)
	// ErrNotFound is the base error for when an item is not found.
	ErrNotFound = errors.New("not found")
	// ErrQuerySetNotFound indicates that a specific query set was not found.
	ErrQuerySetNotFound = fmt.Errorf("query set %w", ErrNotFound)
	// ErrQueryNotFound indicates that a specific query was not found within a set.
	ErrQueryNotFound = fmt.Errorf("query %w", ErrNotFound)
	// ErrInvalidSyntax is returned when the parser encounters a syntax error in a .sql file.
	ErrInvalidSyntax = errors.New("invalid SQLSetList syntax")
	// ErrMaxLineLenExceeded is returned when a line in a .sql file is too long,
	// which may indicate a corrupted file.
	ErrMaxLineLenExceeded = errors.New("line too long, possible line corruption")
	// ErrInvalidArgCount is returned when a function is called
	// with an invalid number of arguments.
	ErrInvalidArgCount = errors.New("invalid number of arguments")
	// ErrRequiredArgMissing is returned when a required argument is not specified.
	ErrRequiredArgMissing = errors.New("required argument not specified")
)

Functions

This section is empty.

Types

type QuerySet

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

QuerySet represents a single set of queries, usually from a single .sql file.

func (*QuerySet) GetMeta

func (qs *QuerySet) GetMeta() QuerySetMeta

GetMeta returns the metadata associated with the query set.

type QuerySetMeta

type QuerySetMeta struct {
	// ID is the unique identifier for the set, derived from the filename.
	ID string `json:"id"`
	// Name is a human-readable name for the query set, from the metadata block.
	Name string `json:"name"`
	// Description provides more details about the query set, from the metadata block.
	Description string `json:"description,omitempty"`
}

QuerySetMeta holds the metadata for a query set.

type SQLQueriesProvider

type SQLQueriesProvider interface {
	// Get returns a query by set ID and query ID.
	// If the set or query is not found, it returns an error.
	Get(ids ...string) (string, error)
	// MustGet returns a query by set ID and query ID.
	// It panics if the set or query is not found.
	MustGet(ids ...string) string
}

SQLQueriesProvider is the interface for getting SQL queries.

type SQLSet

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

SQLSet is a container for multiple query sets, organized by set ID. It provides methods to access SQL queries and metadata. Use New to create a new instance.

func New

func New(fsys fs.FS) (*SQLSet, error)

New creates a new SQLSet by walking the directory tree of the provided fsys. It parses all .sql files it finds and adds them to the SQLSet. The walk starts from the root of the fsys. If you are using embed.FS and your queries are in a subdirectory, you should create a sub-filesystem using fs.Sub.

Example with embed.FS:

//go:embed queries
var queriesFS embed.FS

sqlSet, err := sqlset.New(queriesFS)

func (*SQLSet) Get

func (s *SQLSet) Get(ids ...string) (string, error)

Get returns an SQL query by its identifiers.

Supported forms:

  • Get(setID, queryID) Returns the query identified by queryID from the query set setID.

  • Get("setID.queryID") Equivalent to Get(setID, queryID).

  • Get(queryID) Returns the query identified by queryID from the only available query set. If there is more than one query set, an error is returned.

An error is returned if:

  • the number of arguments is invalid,
  • any identifier is empty,
  • the query set or query cannot be found.

func (*SQLSet) GetQueryIDs

func (s *SQLSet) GetQueryIDs(setID string) ([]string, error)

GetQueryIDs returns a sorted slice of all query IDs within a specific query set.

func (*SQLSet) GetSetsMetas

func (s *SQLSet) GetSetsMetas() []QuerySetMeta

GetSetsMetas returns a slice of metadata for all the query sets loaded. The order of the returned slice is not guaranteed.

func (*SQLSet) MustGet

func (s *SQLSet) MustGet(ids ...string) string

MustGet is like Get but panics if the query set or query is not found. This is useful for cases where the query is expected to exist and its absence is a critical error.

type SQLSetsProvider

type SQLSetsProvider interface {
	// GetSetsMetas returns metadata for all registered query sets.
	GetSetsMetas() []QuerySetMeta
	// GetQueryIDs returns a slice of all query IDs.
	GetQueryIDs(setID string) ([]string, error)
}

SQLSetsProvider is the interface for getting information about query sets.

Directories

Path Synopsis
cmd
sqlset-gen command

Jump to

Keyboard shortcuts

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