# Getting started Okay, enough hype, let's see it in action. First you pass the following SQL to `sqlc generate`: ```sql CREATE TABLE authors ( id BIGSERIAL PRIMARY KEY, name text NOT NULL, bio text ); -- name: GetAuthor :one SELECT * FROM authors WHERE id = $1 LIMIT 1; -- name: ListAuthors :many SELECT * FROM authors ORDER BY name; -- name: CreateAuthor :one INSERT INTO authors ( name, bio ) VALUES ( $1, $2 ) RETURNING *; -- name: DeleteAuthor :exec DELETE FROM authors WHERE id = $1; ``` And then in your application code you'd write: ```go // list all authors authors, err := db.ListAuthors(ctx) if err != nil { return err } fmt.Println(authors) // create an author insertedAuthor, err := db.CreateAuthor(ctx, db.CreateAuthorParams{ Name: "Brian Kernighan", Bio: sql.NullString{String: "Co-author of The C Programming Language and The Go Programming Language", Valid: true}, }) if err != nil { return err } fmt.Println(insertedAuthor) // get the author we just inserted fetchedAuthor, err := db.GetAuthor(ctx, insertedAuthor.ID) if err != nil { return err } // prints true fmt.Println(reflect.DeepEqual(insertedAuthor, fetchedAuthor)) ``` To make that possible, sqlc generates readable, **idiomatic** Go code that you otherwise would have had to write yourself. Take a look: ```go package db import ( "context" "database/sql" ) type Author struct { ID int64 Name string Bio sql.NullString } const createAuthor = `-- name: CreateAuthor :one INSERT INTO authors ( name, bio ) VALUES ( $1, $2 ) RETURNING id, name, bio ` type CreateAuthorParams struct { Name string Bio sql.NullString } func (q *Queries) CreateAuthor(ctx context.Context, arg CreateAuthorParams) (Author, error) { row := q.db.QueryRowContext(ctx, createAuthor, arg.Name, arg.Bio) var i Author err := row.Scan(&i.ID, &i.Name, &i.Bio) return i, err } const deleteAuthor = `-- name: DeleteAuthor :exec DELETE FROM authors WHERE id = $1 ` func (q *Queries) DeleteAuthor(ctx context.Context, id int64) error { _, err := q.db.ExecContext(ctx, deleteAuthor, id) return err } const getAuthor = `-- name: GetAuthor :one SELECT id, name, bio FROM authors WHERE id = $1 LIMIT 1 ` func (q *Queries) GetAuthor(ctx context.Context, id int64) (Author, error) { row := q.db.QueryRowContext(ctx, getAuthor, id) var i Author err := row.Scan(&i.ID, &i.Name, &i.Bio) return i, err } const listAuthors = `-- name: ListAuthors :many SELECT id, name, bio FROM authors ORDER BY name ` func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { rows, err := q.db.QueryContext(ctx, listAuthors) if err != nil { return nil, err } defer rows.Close() var items []Author for rows.Next() { var i Author if err := rows.Scan(&i.ID, &i.Name, &i.Bio); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } type DBTX interface { ExecContext(context.Context, string, ...interface{}) (sql.Result, error) PrepareContext(context.Context, string) (*sql.Stmt, error) QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) QueryRowContext(context.Context, string, ...interface{}) *sql.Row } func New(db DBTX) *Queries { return &Queries{db: db} } type Queries struct { db DBTX } func (q *Queries) WithTx(tx *sql.Tx) *Queries { return &Queries{ db: tx, } } ```