orderby

package
v5.2.0 Latest Latest
Warning

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

Go to latest
Published: May 10, 2022 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrEmptyString is returned when parsing an orderby column and the string
	// was empty.
	ErrEmptyString = errors.New("empty ordering string")
	// ErrMissingDirection is returned when parsing an orderby column but the
	// direction was not found in the string.
	// 	"myfield desc" // OK
	// 	"myfield"      // err!
	ErrMissingDirection = errors.New("missing ordering direction, 'asc' or 'desc'")
	// ErrInvalidField is returned when parsing an orderby column against a map
	// of accepted values, and none matched.
	ErrInvalidField = errors.New("invalid or unsupported ordering field")
	// ErrNilParseMap is returned when parsing but the map that was passed was
	// nil.
	ErrNilParseMap = errors.New("field->column names map is nil")
)
View Source
var (
	// ErrInvalidDirection is returned when parsing an ordering direction where
	// the value did not fall into the valid values 'asc' or 'desc'.
	ErrInvalidDirection = errors.New("invalid direction, only 'asc' or 'desc' supported")
)

Functions

This section is empty.

Types

type Column

type Column struct {
	Name      database.SafeSQLName
	Direction Direction
}

Column specifies a column or field to be sorted and its sorting direction.

func Parse

func Parse(query string, fieldToColumnNames map[string]database.SafeSQLName) (Column, error)

Parse interprets an ordering/sorting definition and optionally translates the inputted field name using a map.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/model/database"
	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
)

func main() {
	fieldToColumnNames := map[string]database.SafeSQLName{
		"buildId": "build_id",
	}
	fields := []string{
		"buildId asc",
		"  buildId   desc  ",
		"foobar asc",
		"buildId foo",
	}
	for _, field := range fields {
		if order, err := orderby.Parse(field, fieldToColumnNames); err != nil {
			fmt.Printf("Invalid sort order: %v\n", err)
		} else {
			fmt.Printf("Sort by %q\n", order)
		}
	}
}
Output:

Sort by "build_id asc"
Sort by "build_id desc"
Invalid sort order: failed mapping field name to column name: "foobar": invalid or unsupported ordering field
Invalid sort order: failed parsing ordering direction: "foo": invalid direction, only 'asc' or 'desc' supported

func (Column) Clause

func (o Column) Clause() clause.Expression

Clause returns a GORM clause expression to apply the column ordering to the query. Meant to be used on the gorm.DB.Clauses function.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Project struct {
	ProjectID uint   `gorm:"primaryKey"`
	Name      string `gorm:"size:500;not null"`
	GroupName string `gorm:"size:500"`
}

func main() {
	db := dryRunDB()
	var projects []Project

	orderBy := orderby.Column{"group_name", orderby.Asc}
	printStmt(db.Model(&Project{}).Clauses(orderBy.Clause()).Find(&projects))

}

func printStmt(tx *gorm.DB) {
	fmt.Println(tx.Statement.SQL.String())
}

func dryRunDB() *gorm.DB {
	db, err := gorm.Open(postgres.New(postgres.Config{}), &gorm.Config{
		DryRun:               true,
		DisableAutomaticPing: true,
	})
	if err != nil {
		panic(fmt.Sprintf("error opening DB: %v", err))
	}
	return db
}
Output:

SELECT * FROM "projects" ORDER BY "group_name"

func (Column) String

func (o Column) String() string

String converts an ordering to a string representation. The result is meant to be parsable by the orderby.Parse function.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
)

func main() {
	fmt.Printf("1: %q\n", orderby.Column{"build_id", orderby.Asc})
	fmt.Printf("2: %q\n", orderby.Column{"build_id", orderby.Desc})
}
Output:

1: "build_id asc"
2: "build_id desc"

type Direction

type Direction byte

Direction tells if an ordering is in ascending order or descending order.

const (
	// Asc means "ascending sorting order". For example the numbers 1, 2, 3, 4
	// are in ascending order, as well as the letters A, B, C, D.
	Asc Direction = iota + 1
	// Desc means "descending sorting order". For example the numbers 4, 3, 2, 1
	// are in descending order, as well as the letters D, C, B, A.
	Desc
)

func ParseDirection

func ParseDirection(direction string) (Direction, error)

ParseDirection interprets a string value as the equivalent direction enum value, or an error if parsing failed. Valid input values are 'asc' and 'desc'.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
)

func main() {
	for _, str := range []string{"asc", "desc", "foo"} {
		if d, err := orderby.ParseDirection(str); err != nil {
			fmt.Println("Error:", err)
		} else {
			fmt.Println("Direction:", d)
		}
	}
}
Output:

Direction: asc
Direction: desc
Error: "foo": invalid direction, only 'asc' or 'desc' supported

func (Direction) String

func (d Direction) String() string

type Slice

type Slice []Column

Slice is a Go slice of column orderings, meant to represent multiple orderings to apply in order.

func ParseSlice

func ParseSlice(queries []string, fieldToColumnNames map[string]database.SafeSQLName) (Slice, error)

ParseSlice returns a new slice where each element has been interpreted by the Parse function, or the error of the first failed parsing.

func (Slice) Clause

func (slice Slice) Clause() clause.Expression

Clause returns a GORM clause expression to apply the list of column orderings to the query. Meant to be used on the gorm.DB.Clauses function.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Project struct {
	ProjectID uint   `gorm:"primaryKey"`
	Name      string `gorm:"size:500;not null"`
	GroupName string `gorm:"size:500"`
}

func main() {
	db := dryRunDB()
	var projects []Project

	orderBySlice := orderby.Slice{{"group_name", orderby.Asc}, {"name", orderby.Desc}}
	multiOrderByQuery := db.Model(&Project{}).Clauses(orderBySlice.Clause())
	printStmt(multiOrderByQuery.Find(&projects))

}

func printStmt(tx *gorm.DB) {
	fmt.Println(tx.Statement.SQL.String())
}

func dryRunDB() *gorm.DB {
	db, err := gorm.Open(postgres.New(postgres.Config{}), &gorm.Config{
		DryRun:               true,
		DisableAutomaticPing: true,
	})
	if err != nil {
		panic(fmt.Sprintf("error opening DB: %v", err))
	}
	return db
}
Output:

SELECT * FROM "projects" ORDER BY "group_name","name" DESC

func (Slice) ClauseIfNone

func (slice Slice) ClauseIfNone(ifNone Column) clause.Expression

ClauseIfNone returns a GORM clause expression to apply the list of column orderings to the query, or a fallback ordering if the list is empty. Meant to be used on the gorm.DB.Clauses function.

Example
package main

import (
	"fmt"

	"github.com/iver-wharf/wharf-api/v5/pkg/orderby"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Project struct {
	ProjectID uint   `gorm:"primaryKey"`
	Name      string `gorm:"size:500;not null"`
	GroupName string `gorm:"size:500"`
}

func main() {
	db := dryRunDB()
	var projects []Project

	fallbackOrderBy := orderby.Column{"project_id", orderby.Asc}
	orderBySlice := orderby.Slice{} // intentionally empty
	fallbackQuery := db.Model(&Project{}).Clauses(orderBySlice.ClauseIfNone(fallbackOrderBy))
	printStmt(fallbackQuery.Find(&projects))

}

func printStmt(tx *gorm.DB) {
	fmt.Println(tx.Statement.SQL.String())
}

func dryRunDB() *gorm.DB {
	db, err := gorm.Open(postgres.New(postgres.Config{}), &gorm.Config{
		DryRun:               true,
		DisableAutomaticPing: true,
	})
	if err != nil {
		panic(fmt.Sprintf("error opening DB: %v", err))
	}
	return db
}
Output:

SELECT * FROM "projects" ORDER BY "project_id"

func (Slice) String

func (slice Slice) String() string

String converts a slice of orderings.

Jump to

Keyboard shortcuts

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