gormite_query_builders

package
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2025 License: LGPL-3.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExecOrErr

func ExecOrErr[ResultType any](
	qb *QueryBuilder[ResultType],
	v ResultType,
) (*ResultType, error)

Types

type QueryBuilder

type QueryBuilder[ResultType any] struct {
	D gormite_databases.PostgresDatabaseInterface
	// contains filtered or unexported fields
}

QueryBuilder - struct is responsible to dynamically create SQL queries.

Important: Verify that every feature you use will work with your database vendor. SQL Query Builder does not attempt to validate the generated SQL at all.

The query builder does no validation whatsoever if certain features even work with the underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements even if some vendors such as MySQL support it.

func NewQueryBuilder

func NewQueryBuilder[ResultType any](d gormite_databases.PostgresDatabaseInterface) *QueryBuilder[ResultType]

NewQueryBuilder - Initializes a new <tt>QueryBuilder</tt>.

func (*QueryBuilder[ResultType]) AddGroupBy

func (qb *QueryBuilder[ResultType]) AddGroupBy(
	expression string,
	expressions ...string,
) *QueryBuilder[ResultType]

AddGroupBy - Adds one or more grouping expressions to the query. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .groupBy('u.lastLogin')
    .addGroupBy('u.createdAt');

</code> @param string expression The grouping expression @param string ...expressions Additional grouping expressions

func (*QueryBuilder[ResultType]) AddOrderBy

func (qb *QueryBuilder[ResultType]) AddOrderBy(
	sort string,
	order *string,
) *QueryBuilder[ResultType]

AddOrderBy - Adds an ordering to the query results. @param string sort The ordering expression. @param string order The ordering direction.

func (*QueryBuilder[ResultType]) AddReturning

func (qb *QueryBuilder[ResultType]) AddReturning(expressions ...string) *QueryBuilder[ResultType]

func (*QueryBuilder[ResultType]) AddSelect

func (qb *QueryBuilder[ResultType]) AddSelect(
	expression string,
	expressions ...string,
) *QueryBuilder[ResultType]

AddSelect - Adds an item that is to be returned in the query result. <code>

qb = conn.createQueryBuilder()
    .select('u.id')
    .addSelect('p.id')
    .from('users', 'u')
    .leftJoin('u', 'phonenumbers', 'u.id = p.user_id');

</code> @param string expression The selection expression. @param string ...expressions Additional selection expressions.

func (*QueryBuilder[ResultType]) AddUnion

func (qb *QueryBuilder[ResultType]) AddUnion(
	part *dtos.QueryBuilderOrString,
	unionType enums.UnionType,
) *QueryBuilder[ResultType]

AddUnion - Add parts to be used to build a UNION query. <code>

qb = conn.createQueryBuilder()
    .union('SELECT 1 AS field1')
    .addUnion('SELECT 2 AS field1', 'SELECT 3 AS field1')

</code> unionType - by default UnionTypeDistinct

func (*QueryBuilder[ResultType]) AndHaving

func (qb *QueryBuilder[ResultType]) AndHaving(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

AndHaving - Adds a restriction over the groups of the query, forming a logical conjunction with any existing having restrictions. @param string|CompositeExpression predicate The predicate to append. @param string|CompositeExpression ...predicates Additional predicates to append.

func (*QueryBuilder[ResultType]) AndWhere

func (qb *QueryBuilder[ResultType]) AndWhere(
	predicate string,
	predicates ...string,
) *QueryBuilder[ResultType]

AndWhere - Adds one or more restrictions to the query results, forming a logical conjunction with any previously specified restrictions. <code>

qb = conn.createQueryBuilder()
    .select('u')
    .from('users', 'u')
    .where('u.username LIKE ?')
    .andWhere('u.is_active = 1');

</code> @see where() @param string|CompositeExpression predicate The predicate to append. @param string|CompositeExpression ...predicates Additional predicates to append.

func (*QueryBuilder[ResultType]) AndWhereViaExpr

func (qb *QueryBuilder[ResultType]) AndWhereViaExpr(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

func (*QueryBuilder[ResultType]) Clone

func (qb *QueryBuilder[ResultType]) Clone() *QueryBuilder[ResultType]

Clone - Deep clone of all expression objects in the SQL parts.

func (*QueryBuilder[ResultType]) CreateNamedParameter

func (qb *QueryBuilder[ResultType]) CreateNamedParameter(
	value interface{},
	paramType enums.ParameterType,
	placeHolder *string,
) string

CreateNamedParameter - Creates a new named parameter and bind the value value to it. This method provides a shortcut for {@see Statement::bindValue()} when using prepared statements. The parameter value specifies the value that you want to bind. If placeholder is not provided createNamedParameter() will automatically create a placeholder for you. An automatic placeholder will be of the name ':dcValue1', ':dcValue2' etc. Example: <code> value = 2; q.eq( 'id', q.createNamedParameter( value ) ); stmt = q.executeQuery(); // executed with 'id = 2' </code> @link http://www.zetacomponents.org @param string|null placeHolder The name to bind with. The string must start with a colon ':'. @return string the placeholder name used.

func (*QueryBuilder[ResultType]) CreatePositionalParameter

func (qb *QueryBuilder[ResultType]) CreatePositionalParameter(
	value interface{},
	paramType ...enums.ParameterType,
) string

CreatePositionalParameter - Creates a new positional parameter and bind the given value to it. Attention: If you are using positional parameters with the query builder you have to be very careful to bind all parameters in the order they appear in the SQL statement , otherwise they get bound in the wrong order which can lead to serious bugs in your code. Example: qb = conn.createQueryBuilder(); qb.select('u.*').from('users', 'u').where('u.username = ' . qb.createPositionalParameter('Foo', ParameterType::STRING)).orWhere('u.username = ' . qb.createPositionalParameter('Bar', ParameterType::STRING))

func (*QueryBuilder[ResultType]) Delete

func (qb *QueryBuilder[ResultType]) Delete(table string) *QueryBuilder[ResultType]

Delete - Turns the query being built into a bulk delete query that ranges over a certain table. <code>

qb = conn.createQueryBuilder()
    .delete('users u')
    .where('u.id = :user_id')
    .setParameter(':user_id', 1);

</code> @param string table The table whose rows are subject to the deletion.

func (*QueryBuilder[ResultType]) Distinct

func (qb *QueryBuilder[ResultType]) Distinct(distinct bool) *QueryBuilder[ResultType]

Distinct - Adds or removes DISTINCT to/from the query. <code>

qb = conn.createQueryBuilder()
    .select('u.id')
    .distinct()
    .from('users', 'u')

</code>

func (*QueryBuilder[ResultType]) Exec

func (qb *QueryBuilder[ResultType]) Exec() error

func (*QueryBuilder[ResultType]) ExecScan

func (qb *QueryBuilder[ResultType]) ExecScan(v interface{}) error

func (*QueryBuilder[ResultType]) ExecScanCol

func (qb *QueryBuilder[ResultType]) ExecScanCol(v interface{}) error

func (*QueryBuilder[ResultType]) Expr

func (qb *QueryBuilder[ResultType]) Expr() *expression_builders.ExpressionBuilder

Expr - Gets an ExpressionBuilder used for object-oriented construction of query expressions. This producer method is intended for convenient inline usage. Example: <code>

qb = conn.createQueryBuilder()
    .select('u')
    .from('users', 'u')
    .where(qb.expr().eq('u.id', 1));

</code> For more complex expression construction, consider storing the expression builder object in a local variable.

func (*QueryBuilder[ResultType]) ForUpdate

func (qb *QueryBuilder[ResultType]) ForUpdate(conflictResolutionMode enums.ConflictResolutionMode) *QueryBuilder[ResultType]

ForUpdate - Locks the queried rows for a subsequent update. Default: ConflictResolutionModeOrdinary

func (*QueryBuilder[ResultType]) From

func (qb *QueryBuilder[ResultType]) From(
	table string,
	alias ...string,
) *QueryBuilder[ResultType]

From - Creates and adds a query root corresponding to the table identified by the given alias, forming a cartesian product with any existing query roots. <code>

qb = conn.createQueryBuilder()
    .select('u.id')
    .from('users', 'u')

</code> @param string table The table. @param string|null alias The alias of the table.

func (*QueryBuilder[ResultType]) GetFirstResult

func (qb *QueryBuilder[ResultType]) GetFirstResult() int

GetFirstResult - Gets the position of the first result the query object was set to retrieve (the "offset").

func (*QueryBuilder[ResultType]) GetLiteralResult

func (qb *QueryBuilder[ResultType]) GetLiteralResult() ([]ResultType, error)

func (*QueryBuilder[ResultType]) GetMaxResults

func (qb *QueryBuilder[ResultType]) GetMaxResults() *int

GetMaxResults - Gets the maximum number of results the query object was set to retrieve (the "limit"). Returns NULL if all results will be returned.

func (*QueryBuilder[ResultType]) GetNamedArgs

func (qb *QueryBuilder[ResultType]) GetNamedArgs() pgx.StrictNamedArgs

GetNamedArgs - Gets all defined query parameters of the query being constructed indexed by parameter name.

func (*QueryBuilder[ResultType]) GetOneOrNilLiteralResult

func (qb *QueryBuilder[ResultType]) GetOneOrNilLiteralResult() (
	*ResultType,
	error,
)

func (*QueryBuilder[ResultType]) GetOneOrNilResult

func (qb *QueryBuilder[ResultType]) GetOneOrNilResult() (*ResultType, error)

func (*QueryBuilder[ResultType]) GetParameter

func (qb *QueryBuilder[ResultType]) GetParameter(key string) interface{}

GetParameter - Gets a (previously set) query parameter of the query being constructed. @param string|int key The key (index or name) of the bound parameter. @return mixed The value of the bound parameter.

func (*QueryBuilder[ResultType]) GetParameterType

func (qb *QueryBuilder[ResultType]) GetParameterType(key string) string

GetParameterType - Gets a (previously set) query parameter type of the query being constructed. @param int|string key The key of the bound parameter type

func (*QueryBuilder[ResultType]) GetParameterTypes

func (qb *QueryBuilder[ResultType]) GetParameterTypes() map[string]string

GetParameterTypes - Gets all defined query parameter types for the query being constructed indexed by parameter index or name. @psalm-return WrapperParameterTypeArray

func (*QueryBuilder[ResultType]) GetResult

func (qb *QueryBuilder[ResultType]) GetResult() ([]*ResultType, error)

func (*QueryBuilder[ResultType]) GetRootAliases

func (qb *QueryBuilder[ResultType]) GetRootAliases() []string

func (*QueryBuilder[ResultType]) GetSQL

func (qb *QueryBuilder[ResultType]) GetSQL() (string, error)

GetSQL - Gets the complete SQL string formed by the current specifications of this QueryBuilder. <code>

qb = em.createQueryBuilder()
    .select('u')
    .from('User', 'u')
echo qb.getSQL(); // SELECT u FROM User u

</code> @return string The SQL query string.

func (*QueryBuilder[ResultType]) GetSQLForDelete

func (qb *QueryBuilder[ResultType]) GetSQLForDelete() string

GetSQLForDelete - Converts this instance into a DELETE string in SQL.

func (*QueryBuilder[ResultType]) GetSQLForJoins

func (qb *QueryBuilder[ResultType]) GetSQLForJoins(
	fromAlias string,
	knownAliases map[string]bool,
) (string, error)

GetSQLForJoins generates SQL for the JOIN clauses.

func (*QueryBuilder[ResultType]) GetSQLForSelect

func (qb *QueryBuilder[ResultType]) GetSQLForSelect() (string, error)

GetSQLForSelect generates SQL for a SELECT query.

func (*QueryBuilder[ResultType]) GetSQLForUnion

func (qb *QueryBuilder[ResultType]) GetSQLForUnion() (string, error)

GetSQLForUnion generates a SQL string for a UNION query.

func (*QueryBuilder[ResultType]) GetSQLForUpdate

func (qb *QueryBuilder[ResultType]) GetSQLForUpdate() string

GetSQLForUpdate - Converts this instance into an UPDATE string in SQL.

func (*QueryBuilder[ResultType]) GroupBy

func (qb *QueryBuilder[ResultType]) GroupBy(
	expression string,
	expressions ...string,
) *QueryBuilder[ResultType]

GroupBy - Specifies one or more grouping expressions over the results of the query. Replaces any previously specified groupings, if any. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .groupBy('u.id');

</code> @param string expression The grouping expression @param string ...expressions Additional grouping expressions

func (*QueryBuilder[ResultType]) Having

func (qb *QueryBuilder[ResultType]) Having(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

Having - Specifies a restriction over the groups of the query. Replaces any previous having restrictions, if any. @param string|CompositeExpression predicate The HAVING clause predicate. @param string|CompositeExpression ...predicates Additional HAVING clause predicates.

func (*QueryBuilder[ResultType]) InnerJoin

func (qb *QueryBuilder[ResultType]) InnerJoin(fromAlias, join, alias, condition string) *QueryBuilder[ResultType]

InnerJoin - Creates and adds a join to the query. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');

</code> @param string fromAlias The alias that points to a from clause. @param string join The table name to join. @param string alias The alias of the join table. @param string condition The condition for the join.

func (*QueryBuilder[ResultType]) Insert

func (qb *QueryBuilder[ResultType]) Insert(table string) *QueryBuilder[ResultType]

Insert - Turns the query being built into an insert query that inserts into a certain table <code>

qb = conn.createQueryBuilder()
    .insert('users')
    .values(
        array(
            'name' => '?',
            'password' => '?'
        )
    );

</code> @param string table The table into which the rows should be inserted.

func (*QueryBuilder[ResultType]) Join

func (qb *QueryBuilder[ResultType]) Join(fromAlias, join, alias, condition string) *QueryBuilder[ResultType]

Join - Creates and adds a join to the query. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .join('u', 'phonenumbers', 'p', 'p.is_primary = 1');

</code> @param string fromAlias The alias that points to a from clause. @param string join The table name to join. @param string alias The alias of the join table. @param string condition The condition for the join.

func (*QueryBuilder[ResultType]) LeftJoin

func (qb *QueryBuilder[ResultType]) LeftJoin(fromAlias, join, alias, condition string) *QueryBuilder[ResultType]

LeftJoin - Creates and adds a left join to the query. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');

</code> @param string fromAlias The alias that points to a from clause. @param string join The table name to join. @param string alias The alias of the join table. @param string condition The condition for the join.

func (*QueryBuilder[ResultType]) MustGetSQL

func (qb *QueryBuilder[ResultType]) MustGetSQL() string

func (*QueryBuilder[ResultType]) OrHaving

func (qb *QueryBuilder[ResultType]) OrHaving(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

OrHaving - Adds a restriction over the groups of the query, forming a logical disjunction with any existing having restrictions. @param string|CompositeExpression predicate The predicate to append. @param string|CompositeExpression ...predicates Additional predicates to append.

func (*QueryBuilder[ResultType]) OrWhere

func (qb *QueryBuilder[ResultType]) OrWhere(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

OrWhere - Adds one or more restrictions to the query results, forming a logical disjunction with any previously specified restrictions. <code>

qb = em.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .where('u.id = 1')
    .orWhere('u.id = 2');

</code> @see where() @param string|CompositeExpression predicate The predicate to append. @param string|CompositeExpression ...predicates Additional predicates to append.

func (*QueryBuilder[ResultType]) OrderBy

func (qb *QueryBuilder[ResultType]) OrderBy(
	sort string,
	order ...string,
) *QueryBuilder[ResultType]

OrderBy - Specifies an ordering for the query results. Replaces any previously specified orderings, if any. @param string sort The ordering expression. @param string order The ordering direction.

func (*QueryBuilder[ResultType]) PrepareIN

func (qb *QueryBuilder[ResultType]) PrepareIN(args []string) string

PrepareIN - Creates a string of named parameters for the IN clause of the query. https://stackoverflow.com/questions/56074423/how-to-use-where-id-in-clauses-with-jackc-pgx

func (*QueryBuilder[ResultType]) PrepareInArgs

func (qb *QueryBuilder[ResultType]) PrepareInArgs(argsAny any) []string

func (*QueryBuilder[ResultType]) ResetGroupBy

func (qb *QueryBuilder[ResultType]) ResetGroupBy() *QueryBuilder[ResultType]

ResetGroupBy - Resets the grouping for the query.

func (*QueryBuilder[ResultType]) ResetHaving

func (qb *QueryBuilder[ResultType]) ResetHaving() *QueryBuilder[ResultType]

ResetHaving - Resets the HAVING conditions for the query.

func (*QueryBuilder[ResultType]) ResetOrderBy

func (qb *QueryBuilder[ResultType]) ResetOrderBy() *QueryBuilder[ResultType]

ResetOrderBy - Resets the ordering for the query.

func (*QueryBuilder[ResultType]) ResetWhere

func (qb *QueryBuilder[ResultType]) ResetWhere() *QueryBuilder[ResultType]

ResetWhere - Resets the WHERE conditions for the query.

func (*QueryBuilder[ResultType]) Returning

func (qb *QueryBuilder[ResultType]) Returning(expressions ...string) *QueryBuilder[ResultType]

func (*QueryBuilder[ResultType]) RightJoin

func (qb *QueryBuilder[ResultType]) RightJoin(fromAlias, join, alias, condition string) *QueryBuilder[ResultType]

RightJoin - Creates and adds a right join to the query. <code>

qb = conn.createQueryBuilder()
    .select('u.name')
    .from('users', 'u')
    .rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');

</code> @param string fromAlias The alias that points to a from clause. @param string join The table name to join. @param string alias The alias of the join table. @param string condition The condition for the join.

func (*QueryBuilder[ResultType]) ScanOneLiteralResult

func (qb *QueryBuilder[ResultType]) ScanOneLiteralResult(target *ResultType) error

func (*QueryBuilder[ResultType]) Select

func (qb *QueryBuilder[ResultType]) Select(expressions ...string) *QueryBuilder[ResultType]

Select - Specifies an item that is to be returned in the query result. Replaces any previously specified selections, if any. <code>

qb = conn.createQueryBuilder()
    .select('u.id', 'p.id')
    .from('users', 'u')
    .leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');

</code> @param string ...expressions The selection expressions.

func (*QueryBuilder[ResultType]) Set

func (qb *QueryBuilder[ResultType]) Set(key, value string) *QueryBuilder[ResultType]

Set - Sets a new value for a column in a bulk update query. <code>

qb = conn.createQueryBuilder()
    .update('counters c')
    .set('c.value', 'c.value + 1')
    .where('c.id = ?');

</code> @param string key The column to set. @param string value The value, expression, placeholder, etc.

func (*QueryBuilder[ResultType]) SetFirstResult

func (qb *QueryBuilder[ResultType]) SetFirstResult(firstResult int) *QueryBuilder[ResultType]

SetFirstResult - Sets the position of the first result to retrieve (the "offset").

func (*QueryBuilder[ResultType]) SetMaxResults

func (qb *QueryBuilder[ResultType]) SetMaxResults(maxResults int) *QueryBuilder[ResultType]

SetMaxResults - Sets the maximum number of results to retrieve (the "limit").

func (*QueryBuilder[ResultType]) SetParameter

func (qb *QueryBuilder[ResultType]) SetParameter(
	key string,
	value interface{},
	paramType ...enums.ParameterType,
) *QueryBuilder[ResultType]

SetParameter - Sets a query parameter for the query being constructed.

qb = conn.createQueryBuilder().select('u').from('users', 'u').where('u.id = :user_id').setParameter('user_id', 1);

func (*QueryBuilder[ResultType]) SetParameters

func (qb *QueryBuilder[ResultType]) SetParameters(
	params map[string]interface{},
	types ...map[string]string,
) *QueryBuilder[ResultType]

SetParameters - Sets a collection of query parameters for the query being constructed. <code>

qb = conn.createQueryBuilder()
    .select('u')
    .from('users', 'u')
    .where('u.id = :user_id1 OR u.id = :user_id2')
    .setParameters(array(
        'user_id1' => 1,
        'user_id2' => 2
    ));

</code>

func (*QueryBuilder[ResultType]) SetValue

func (qb *QueryBuilder[ResultType]) SetValue(column, value string) *QueryBuilder[ResultType]

SetValue - Sets a value for a column in an insert query. <code>

qb = conn.createQueryBuilder()
    .insert('users')
    .values(
        array(
            'name' => '?'
        )
    )
    .setValue('password', '?');

</code> @param string column The column into which the value should be inserted. @param string value The value that should be inserted into the column.

func (*QueryBuilder[ResultType]) ToString

func (qb *QueryBuilder[ResultType]) ToString() string

ToString - Gets a string representation of this QueryBuilder which corresponds to the final SQL query being constructed. @return string The string representation of this QueryBuilder.

func (*QueryBuilder[ResultType]) Union

func (qb *QueryBuilder[ResultType]) Union(part *dtos.QueryBuilderOrString) *QueryBuilder[ResultType]

Union - Specifies union parts to be used to build a UNION query. Replaces any previously specified parts. <code>

qb = conn.createQueryBuilder()
    .union('SELECT 1 AS field1', 'SELECT 2 AS field1');

</code>

func (*QueryBuilder[ResultType]) Update

func (qb *QueryBuilder[ResultType]) Update(table string) *QueryBuilder[ResultType]

Update - Turns the query being built into a bulk update query that ranges over a certain table <code>

qb = conn.createQueryBuilder()
    .update('counters c')
    .set('c.value', 'c.value + 1')
    .where('c.id = ?');

</code> @param string table The table whose rows are subject to the update.

func (*QueryBuilder[ResultType]) Values

func (qb *QueryBuilder[ResultType]) Values(values map[string]string) *QueryBuilder[ResultType]

Values - Specifies values for an insert query indexed by column names. Replaces any previous values, if any. <code>

qb = conn.createQueryBuilder()
    .insert('users')
    .values(
        array(
            'name' => '?',
            'password' => '?'
        )
    );

</code> @param array<string, mixed> values The values to specify for the insert query indexed by column names.

func (*QueryBuilder[ResultType]) Where

func (qb *QueryBuilder[ResultType]) Where(
	predicate string,
	predicates ...string,
) *QueryBuilder[ResultType]

Where - Specifies one or more restrictions to the query result. Replaces any previously specified restrictions, if any. <code>

qb = conn.createQueryBuilder()
    .select('c.value')
    .from('counters', 'c')
    .where('c.id = ?');
// You can optionally programmatically build and/or expressions
qb = conn.createQueryBuilder();
or = qb.expr().orx();
or.add(qb.expr().eq('c.id', 1));
or.add(qb.expr().eq('c.id', 2));
qb.update('counters c')
    .set('c.value', 'c.value + 1')
    .where(or);

</code> @param string|CompositeExpression predicate The WHERE clause predicate. @param string|CompositeExpression ...predicates Additional WHERE clause predicates.

func (*QueryBuilder[ResultType]) WhereViaExpr

func (qb *QueryBuilder[ResultType]) WhereViaExpr(
	predicate *dtos.CompositeExpressionOrString,
	predicates ...*dtos.CompositeExpressionOrString,
) *QueryBuilder[ResultType]

Jump to

Keyboard shortcuts

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