Query
Read (query) operations are provided by cql via its compiled query system.
Query creation
To create a query you must use the cql.Query[models.MyModel] method, where models.MyModel is the model you expect this query to answer. This function takes as parameters the transaction on which to execute the query and the Conditions.
Transactions
To execute transactions, cql provides the function cql.Transaction. The function passed by parameter will be executed inside a gorm transaction (for more information visit https://gorm.io/docs/transactions.html). Using this method will also allow the transaction execution time to be logged.
Query methods
The object obtained using cql.Query has different methods that will allow you to obtain the results of the query:
Modifier methods
Modifier methods are those that modify the query in a certain way, affecting the results obtained: - Limit: specifies the number of models to be retrieved. - Offset: specifies the number of models to skip before starting to return the results. - Ascending: specifies an ascending order when retrieving models. - Descending: specifies a descending order when retrieving models from database.
Finishing methods
Finishing methods are those that cause the query to be executed and the result(s) of the query to be returned:
Count: returns the amount of models that fulfill the conditions.
First: finds the first model ordered by primary key.
Take: finds the first model returned by the database in no specified order.
Last: finds the last model ordered by primary key.
FindOne: finds the only one model that matches given conditions or returns error if 0 or more than 1 are found.
Find: finds list of models that meet the conditions.
Conditions
The set of conditions that are received by the cql.Query method form the cql compiled query system. It is so named because the conditions will verify at compile time that the query to be executed is correct.
These conditions are objects of type Condition that contain the necessary information to perform the queries in a safe way. They are generated from the definition of your models using cql-gen.
Examples
Filter by an attribute
In this example we query all MyModel that has “a_string” in the Name attribute.
type MyModel struct {
model.UUIDModel
Name string
}
myModels, err := cql.Query[MyModel](
gormDB,
conditions.MyModel.Name.Is().Eq("a_string"),
).Find()
Filter by an attribute of a related model
In this example we query all MyModels whose related MyOtherModel has “a_string” in its Name attribute.
type MyOtherModel struct {
model.UUIDModel
Name string
}
type MyModel struct {
model.UUIDModel
Related MyOtherModel
RelatedID model.UUID
}
myModels, err := cql.Query[MyModel](
gormDB,
conditions.MyModel.Related(
conditions.MyOtherModel.Name.Is().Eq("a_string"),
),
).Find()
Multiple conditions
In this example we query all MyModels that has a 4 in the Code attribute and whose related MyOtherModel has “a_string” in its Name attribute.
type MyOtherModel struct {
model.UUIDModel
Name string
}
type MyModel struct {
model.UUIDModel
Code int
Related MyOtherModel
RelatedID model.UUID
}
myModels, err := cql.Query[MyModel](
gormDB,
conditions.MyModel.Code.Is().Eq(4),
conditions.MyModel.Related(
conditions.MyOtherModel.Name.Is().Eq("a_string"),
),
).Find()
Operators
The different operators to use inside your queries are defined by the methods of the FieldIs type, which is returned when calling the Is() method. Below you will find the complete list of available operators:
Eq(value): Equal to
NotEq(value): Not equal to
Lt(value): Less than
LtOrEq(value): Less than or equal to
Gt(value): Greater than
GtOrEq(value): Greater than or equal to
Null()
NotNull()
Between(v1, v2): Equivalent to v1 < attribute < v2
NotBetween(v1, v2): Equivalent to NOT (v1 < attribute < v2)
Distinct(value)
NotDistinct(value)
In(values)
NotIn(values)
For boolean attributes:
True()
NotTrue()
False()
NotFalse()
Unknown(): unknown is null for booleans
NotUnknown(): unknown is null for booleans
For string attributes:
Like(pattern)
In addition to these, cql gives the possibility to use operators that are only supported by a certain database (outside the standard). For doing it, you must use the Custom method and give the operator as argument, for example:
conditions.MyModel.Code.Is().Custom(psql.ILike("_a%")),
These operators can be found in <https://pkg.go.dev/github.com/FrancoLiberali/cql/mysql>, <https://pkg.go.dev/github.com/FrancoLiberali/cql/sqlserver>, <https://pkg.go.dev/github.com/FrancoLiberali/cql/psql> and <https://pkg.go.dev/github.com/FrancoLiberali/cql/sqlite>.
You can also define your own operators following the condition.Operator interface.