Skip to content

Commit

Permalink
add docs of new cqllint detections
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoLiberali committed Jan 13, 2024
1 parent a641c8e commit 750fc5c
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 12 deletions.
2 changes: 1 addition & 1 deletion cqllint/pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func findRepeatedFields(call *ast.CallExpr, selectorExpr *ast.SelectorExpr) {
if comparedFieldName == fieldName {
passG.Reportf(
comparedField.Sel.NamePos,
"%s is set to the same value",
"%s is set to itself",
comparedFieldName,
)
}
Expand Down
2 changes: 1 addition & 1 deletion cqllint/pkg/analyzer/testdata/src/repeated/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ func testSetDynamicSameValue() {
db,
conditions.Product.Int.Is().Eq(0),
).Set(
conditions.Product.Int.Set().Dynamic(conditions.Product.Int.Value()), // want "conditions.Product.Int is set to the same value"
conditions.Product.Int.Set().Dynamic(conditions.Product.Int.Value()), // want "conditions.Product.Int is set to itself"
)
}
2 changes: 1 addition & 1 deletion docs/cql/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ The set of conditions that are received by the
`cql.Query`, `cql.Update` and `cql.Delete` methods 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.

For details visit :ref:`cql/query:conditions` and :doc:`/cql/compile_time_safety`.
For details visit :ref:`cql/query:conditions` and :doc:`/cql/type_safety`.

Conditions generation
----------------------------
Expand Down
81 changes: 75 additions & 6 deletions docs/cql/cqllint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ cqllint
While, in most cases, queries created using cql are checked at compile time,
there are still some cases that can generate run-time errors (see :ref:`cql/type_safety:Runtime errors`).

cqllint analyses the Go code written to detect these cases and fix them without the need to execute the query.
cqllint analyses the Go code written to detect these cases and fix them without the need to execute the query.
It also adds other detections that would not generate runtime errors but are possible misuses of cql.

.. note::

At the moment, only the error cql.ErrFieldModelNotConcerned is detected.
At the moment, only the errors cql.ErrFieldModelNotConcerned and cql.ErrFieldIsRepeated are detected.

We recommend integrating cqllint into your CI so that the use of cql ensures 100% that your queries will be executed correctly.

Expand Down Expand Up @@ -45,10 +46,13 @@ or using `go vet`:
go vet -vettool=$(which cqllint) ./...
Example
----------------------------
Errors
-------------------------------

ErrFieldModelNotConcerned
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The simplest example of an error case is trying to make a comparison
The simplest example this error case is trying to make a comparison
with an attribute of a model that is not joined by the query:

.. code-block:: go
Expand All @@ -75,4 +79,69 @@ Now, if we run cqllint we will see the following report:
$ cqllint ./...
example.go:3: models.City is not joined by the query
In this way, we will be able to correct this error without having to execute the query.
In this way, we will be able to correct this error without having to execute the query.

ErrFieldIsRepeated
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The simplest example this error case is trying to set the value of an attribute twice:

.. code-block:: go
:caption: example.go
:class: with-errors
:emphasize-lines: 5,6
:linenos:
_, err := cql.Update[models.Brand](
db,
conditions.Brand.Name.Is().Eq("nike"),
).Set(
conditions.Brand.Name.Set().Eq("adidas"),
conditions.Brand.Name.Set().Eq("puma"),
)
If we execute this query we will obtain an error of type `cql.ErrFieldIsRepeated` with the following message:

.. code-block:: none
field is repeated; field: models.Brand.Name; method: Set
Now, if we run cqllint we will see the following report:

.. code-block:: none
$ cqllint ./...
example.go:5: conditions.Brand.Name is repeated
example.go:6: conditions.Brand.Name is repeated
In this way, we will be able to correct this error without having to execute the query.

Misuses
-------------------------

Although some cases would not generate runtime errors, cqllint will detect them as they are possible misuses of cql.

Set the same value
^^^^^^^^^^^^^^^^^^^^^^^^^

This case occurs when making a Set of exactly the same value:

.. code-block:: go
:caption: example.go
:class: with-errors
:emphasize-lines: 5
:linenos:
_, err := cql.Update[models.Brand](
db,
conditions.Brand.Name.Is().Eq("nike"),
).Set(
conditions.Brand.Name.Set().Dynamic(conditions.Brand.Name.Value()),
)
If we run cqllint we will see the following report:

.. code-block:: none
$ cqllint ./...
example.go:5: conditions.Brand.Name is set to itself
3 changes: 1 addition & 2 deletions docs/cql/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,7 @@ We can run this tutorial with `make tutorial_4` and we will obtain the following
As you can see, again we get only the Paris in France.

In this tutorial we have used a condition that performs a join,
for more details you can read :ref:`cql/query:Use of the conditions`.
In this tutorial we have used a condition that performs a join.

Tutorial 5: preloading
-------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/cql/type_safety.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ there are still some possible cases that generate the following run-time errors:
to the rest of the query (not joined).
- cql.ErrJoinMustBeSelected: generated when you try to use a model that is included
(joined) more than once in the query without selecting which one you want to use (see :ref:`cql/advanced_query:select join`).
- cql.ErrFieldIsRepeated: generated when a field is repeated inside a Set call (see :doc:`/cql/update`).
- cql.ErrFieldIsRepeated **(1)**: generated when a field is repeated inside a Set call (see :doc:`/cql/update`).
- cql.ErrOnlyPreloadsAllowed: generated when trying to use conditions within a preload of collections (see :ref:`cql/advanced_query:collections`).
- cql.ErrUnsupportedByDatabase: generated when an attempt is made to use a method or function that is not supported by the database engine used.
- cql.ErrOrderByMustBeCalled: generated when in MySQL you try to do a delete/update with Limit but without using OrderBy.
Expand Down

0 comments on commit 750fc5c

Please sign in to comment.