norm

command module
v0.0.0-...-1e29435 Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2020 License: MIT Imports: 11 Imported by: 0

README

norm

norm is a Golang DB layer generator. It generates code that doesn't make any assumptions about the intermediate model structs. It can bind to user provided structs, or generate code that doesn't depend on these. You write SQL, with some comment annotations. These annotations are used to generate the Golang code.

Example

Suppose you have the following SQL query which selects a given user from a users table.

-- !read GetUserListNoModel
-- !input limit int
-- !input offset int
-- !output ID int
-- !output Email *string
-- !doc Retrieves all emails from the users table
SELECT id, email
FROM users
LIMIT $1
OFFSET $2

norm will generate the following API for the above declaration. Note that it allows you to do a custom bind by generating low-level scanning code. In addition, it provides an optional convenience method that returns a wrapper struct for the output.

type GetUserListNoModelResult struct {
	stmt *sql.Stmt
	rows *sql.Rows
}

func (res GetUserListNoModelResult) Next() bool {
	return res.rows.Next()
}

func (res GetUserListNoModelResult) Scan(ID *int, Email **string) error {
	return res.rows.Scan(ID, Email)
}

func (res GetUserListNoModelResult) Close() {
	if res.rows != nil {
		res.rows.Close()
	}
	if res.stmt != nil {
		res.stmt.Close()
	}
}

// Retrieves all emails from the users table
func GetUserListNoModelScan(db *sql.DB, limit int, offset int) (*GetUserListNoModelResult, error) {
	result := GetUserListNoModelResult{}
	var err error
	result.stmt, err = db.Prepare(`SELECT id, email
FROM users
LIMIT $1
OFFSET $2`)
	if err != nil {
		return nil, err
	}
	result.rows, err = result.stmt.Query(limit, offset)
	if err != nil {
		defer result.stmt.Close()
		return nil, err
	}
	return &result, nil
}

type GetUserListNoModelOutput struct {
	ID    int
	Email *string
}

func GetUserListNoModel(db *sql.DB, limit int, offset int) ([]GetUserListNoModelOutput, error) {
	res, err := GetUserListNoModelScan(db, limit, offset)
	if err != nil {
		return nil, err
	}
	defer res.Close()
	var ret []GetUserListNoModelOutput
	for res.Next() {
		var o GetUserListNoModelOutput
		if err := res.Scan(&o.ID, &o.Email); err != nil {
			return ret, err
		}
		ret = append(ret, o)
	}
	return ret, nil
}

Documentation

Overview

* `norm` can be used with `go generate` to create a simple API for programs. It does not force a object structure, which can be decided outside of this layer. This allows consumers to not have leaky DB related fluff in their models.

This executable must be called with one argument - the input file.

Todo: - Create a backup and restore when this command fails

Directories

Path Synopsis
Code generated by norm.
Code generated by norm.

Jump to

Keyboard shortcuts

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