Skip to content

dbgo generates a database consumer package containing optimized Go code and SQL queries for your database and domain models.

License

Notifications You must be signed in to change notification settings

switchupcb/dbgo

Repository files navigation

Generate a database consumer module for your database based on domain types.

Go Doc License

Use dbgo to stop wasting time developing optimized SQL and Go code for your database and domain models.

NOTE: You can read the roadmap for a list of implemented features as this repository is under development.

What is dbgo?

dbgo generates a database consumer package containing optimized Go code and SQL queries for your database and domain models (i.e., Go types).

Why don't you use other database frameworks?

dbgo lets you use domain models as a source of truth for optimized code, while other database frameworks generate unoptimized code based on the database as a source of truth.

Here is an example of the difference between dbgo and other frameworks.

What is your workflow with dbgo?

Your workflow with dbgo involves defining Go types (e.g., domain models) and connecting to an existing database to generate a:

  1. Repository Go package (e.g., for a business domain) which transfers data from a datastore to your domain models.
  2. Datastore Go package (e.g., for a psql database) without unnecessary "data access objects" or "data transfer functionality" to reduce CPU usage and memory allocations.
    1. Database Go types for Read (Select) operations which do not use reflection during runtime.
    2. Database Driver Go code to call Create (Insert), Read (Select), Update, Delete operations in a single or batch statement.
    3. Database Query Manager to manage your SQL queries and Stored Procedures.
    4. Database Query Developer to develop custom type-safe SQL statements using Go type database models (e.g., tables, views).
    5. Database Query Generator to develop type-safe CRUD SQL statements using your database schema (e.g., tables, views).

So, you can immediately use the domain type with the database once your Go types are defined and your database is set up.

What is your workflow with other database frameworks?

Your workflow with other database frameworks involves:

  • Generators which generate Go and SQL code, but are impossible to customize when you need more than basic CRUD operations.
  • ORMs which use reflection to perform CRUD operations that fetch EVERY FIELD FROM A TABLE instead of only fetching data you need.
  • Query Builders which only help YOU CREATE SQL using Go types.

YOU WASTE TIME patching your repository on each database update using other database frameworks because no code is generated for your domain types.

Table of Contents

Topic Category
Using dbgo
with a domain 1. Define Go types, 2. Deploy Database, 3. Map Domain to Database
with a database 4. Configure setup file, 5. Generate SQL, 6. Generate Database Consumer
License What can I do?

How do you use dbgo?

This demonstration generates a database consumer package for an Account domain.

dbgo can generate a database consumer module without defining a domain. Skip to step 4 when this is your use case.

Step 1. Define Go types (domain models)

Go types are defined in a file.

./domain/domain.go

// Account represents a user's account.
type Account struct {
    ID int
    Username string
    Password string
    Name string
}

Step 2. Deploy Database

You must connect to an existing database to run dbgo.

Here is the database diagram for the database used in this example.

Database Diagram showing an Accounts and Users table.

Step 3. Map Domain Fields to Database

Map the domain's fields to database schema (e.g, table) fields.

./domain/domain.go

// Account represents a user's account.
type Account struct {
    ID int
    Username string `dbgo:"users.name"`
    Password string `dbgo:"users.password"`
    Name string     `dbgo:"accounts.name"`
}

Step 4. Configure the setup file

You set up dbgo with a YAML file.

setup.yml

generated:
    # Define the code generator inputs.
    input:
        # domain package containing Go types (relative to the setup file)
        dpkg: ./domain

        # database connection and schema (public by default).
        db: 
            # connection string or environment variable (e.g., `$VAR`)
            connection: postgresql://user:pass@localhost:5432/dbgo?sslmode=disable 
            schema: public

        # database query directory containing SQL query files (relative to the setup file).
        queries: datastore/psql/queries

    # Define where the code is generated (relative to the setup file).
    output:
        # domain repository package containing repository model functions.
        dpkg: datastore/domain

        # database package containing database model functions. 
        dbpkg: datastore/psql

        # Define the optional custom templates used to generate the file (.go supported).
        # template: ./generate.go

# Define custom options (which are passed to generator options) for customization.
custom:
  option: The possibilities are endless.

Step 5. Generate SQL statements

Use the dbgo query manager to save customized type-safe SQL statements or generate them.

1) Install the command line tool: sqlc.

go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest

2) Install the command line tool: dbgo.

go install github.com/switchupcb/dbgo@latest

3) Run the executable with the following options to add SQL to the queries directory.

Command Line Description
dbgo query schema -y path/to/yml Generates a schema.sql and schema.go file representing your database in the queries directory.
dbgo query gen -y path/to/yml Generates SQL queries for Read (Select) operations and Create (Insert), Update, Delete operations.
dbgo query template <name> -y path/to/yml Adds a name template to the queries templates directory. The template contains Go type database models you can use to return a type-safe SQL statement from the SQL() function in name.go which is called by dbgo query save.
dbgo query save <name> -y path/to/yml Saves an SQL file (with the same name as the template [e.g., name.sql]) containing an SQL statement (returned from the SQL() function in name.go) to the queries directory.

Here are additional command usage notes.

  • -y, --yml: The path to the YML file must be specified in reference to the current working directory.
  • dbgo query template: Every template is updated when this command is executed without a specified template.
  • dbgo query save: Every template is saved when this command is executed without a specified template.

How do you develop type-safe SQL?

Running dbgo query template <name> -y path/to/yml adds a name.go file with database models as Go types to your queries directory: You can use these Go types with jet to return an stmt.Sql() from SQL(), which cannot be interpreted unless the Go code referencing struct fields can be compiled.

Read "How quickly bugs are found" for more information about writing type-safe SQL with Go.

You should consider these interpreter usage notes while using templates.

  • You do not have to use jet to generate SQL programmatically.
  • You are not required to initialize a go.mod file to run templates, but using go get github.com/switchupcb/jet/v2@dbgo in a go.mod related to the template files helps you identify compiler errors in your template files while using jet.
  • dbgo query save <name> interprets schema.go before name.go. So, do not reference declarations from name.go in schema.go.

Step 6. Generate the database consumer package

Install the command line tool when you haven't already: dbgo.

go install github.com/switchupcb/dbgo@latest

Run the executable with given options.

dbgo gen -y path/to/yml

The path to the YML file must be specified in reference to the current working directory.

You can view the output and usage of this example here.

What is the License?

dbgo uses a AGPLv3 License.

What can you do with this license?

Code generated by dbgo can be used without restriction (including proprietary and commercial usage). However, modifications to the dbgo Software Source Code or implementing dbgo in a larger work programmatically requires you to to adhere to the AGPLv3 License.

What is a license exception?

A license exception lets you modify and use dbgo without restriction.

You can receive a license exception for dbgo by contacting SwitchUpCB using the dbgo License Exception Inquiry Form.

Contributing

You can contribute to this repository by viewing the Project Structure, Code Specifications, CI/CD, and Roadmap.

About

dbgo generates a database consumer package containing optimized Go code and SQL queries for your database and domain models.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages