|
| 1 | +============================== |
| 2 | +Tutorial |
| 3 | +============================== |
| 4 | + |
| 5 | +In this short tutorial you will learn the main functionalities of badaas-orm. |
| 6 | +The code to be executed in each step can be found in this `repository <https://github.com/ditrit/badaas-orm-tutorial>`_. |
| 7 | + |
| 8 | +Model and data |
| 9 | +----------------------- |
| 10 | + |
| 11 | +In the file `models/models.go` you find the definition of the following model: |
| 12 | + |
| 13 | +.. image:: /img/badaas-orm-tutorial-model.png |
| 14 | + :width: 700 |
| 15 | + :alt: badaas-orm tutorial model |
| 16 | + |
| 17 | +For details about the definition of models you can read :doc:`/badaas-orm/declaring_models`. |
| 18 | + |
| 19 | +In `sqlite:db` you will find a sqlite database with the following data: |
| 20 | + |
| 21 | +.. list-table:: Countries |
| 22 | + :header-rows: 1 |
| 23 | + |
| 24 | + * - ID |
| 25 | + - Name |
| 26 | + - CapitalID |
| 27 | + * - 3739a825-bc5c-4350-a2bc-6e77e22fe3f4 |
| 28 | + - France |
| 29 | + - eaa480a3-694e-4be3-9af5-ad935cdd57e2 |
| 30 | + * - 0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921 |
| 31 | + - United States of America |
| 32 | + - df44272e-c3db-4e18-876c-f9f579488716 |
| 33 | + |
| 34 | +.. list-table:: Cities |
| 35 | + :header-rows: 1 |
| 36 | + |
| 37 | + * - ID |
| 38 | + - Name |
| 39 | + - Population |
| 40 | + - CountryID |
| 41 | + * - eaa480a3-694e-4be3-9af5-ad935cdd57e2 |
| 42 | + - Paris |
| 43 | + - 2161000 |
| 44 | + - 3739a825-bc5c-4350-a2bc-6e77e22fe3f4 |
| 45 | + * - df44272e-c3db-4e18-876c-f9f579488716 |
| 46 | + - Washington D. C. |
| 47 | + - 689545 |
| 48 | + - 0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921 |
| 49 | + * - 8c3dfc38-1fc6-4ec9-a89b-e41018a54b4a |
| 50 | + - Paris |
| 51 | + - 25171 |
| 52 | + - 0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921 |
| 53 | + |
| 54 | +As you can see, there are two cities called Paris in this database: |
| 55 | +the well known Paris, capital of France and site of the iconic Eiffel tower, |
| 56 | +and Paris in the United States of America, site of the Eiffel tower with the cowboy hat |
| 57 | +(no joke, just search for paris texas eiffel tower in your favorite search engine). |
| 58 | + |
| 59 | +In this tutorial we will explore the badaas-orm functions that will allow us to differentiate these two Paris. |
| 60 | + |
| 61 | +Tutorial 1: simple query |
| 62 | +------------------------------- |
| 63 | + |
| 64 | +In this first tutorial we are going to perform a simple query to obtain all the cities called Paris. |
| 65 | + |
| 66 | +In the tutorial_1.go file you will find that we can perform this query as follows: |
| 67 | + |
| 68 | +.. code-block:: go |
| 69 | +
|
| 70 | + cities, err := orm.NewQuery[models.City]( |
| 71 | + db, |
| 72 | + conditions.City.NameIs().Eq("Paris"), |
| 73 | + ).Find() |
| 74 | +
|
| 75 | +We can run this tutorial with `make tutorial_1` and we will obtain the following result: |
| 76 | + |
| 77 | +.. code-block:: bash |
| 78 | +
|
| 79 | + Cities named 'Paris' are: |
| 80 | + 1: &{UUIDModel:{ID:eaa480a3-694e-4be3-9af5-ad935cdd57e2 CreatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:2161000 Country:<nil> CountryID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4} |
| 81 | + 2: &{UUIDModel:{ID:8c3dfc38-1fc6-4ec9-a89b-e41018a54b4a CreatedAt:2023-08-11 16:43:27.468149185 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.468149185 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:25171 Country:<nil> CountryID:0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921} |
| 82 | +
|
| 83 | +As you can see, in this case we will get both cities which we can differentiate by their population and the id of the country. |
| 84 | + |
| 85 | +In this first tutorial we have used the badaas-orm compilable queries system to get these cities, |
| 86 | +for more details you can read :ref:`badaas-orm/query:conditions`. |
| 87 | + |
| 88 | +Tutorial 2: operators |
| 89 | +------------------------------- |
| 90 | + |
| 91 | +Now we are going to try to obtain only the Paris of France and in a first |
| 92 | +approximation we could do it using its population: we will only look for the Paris |
| 93 | +whose population is greater than one million inhabitants. |
| 94 | + |
| 95 | +In the tutorial_2.go file you will find that we can perform this query as follows: |
| 96 | + |
| 97 | +.. code-block:: go |
| 98 | +
|
| 99 | + cities, err := orm.NewQuery[models.City]( |
| 100 | + db, |
| 101 | + conditions.City.NameIs().Eq("Paris"), |
| 102 | + conditions.City.PopulationIs().Gt(1000000), |
| 103 | + ).Find() |
| 104 | +
|
| 105 | +We can run this tutorial with `make tutorial_2` and we will obtain the following result: |
| 106 | + |
| 107 | +.. code-block:: bash |
| 108 | +
|
| 109 | + Cities named 'Paris' with a population bigger than 1.000.000 are: |
| 110 | + 1: &{UUIDModel:{ID:eaa480a3-694e-4be3-9af5-ad935cdd57e2 CreatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:2161000 Country:<nil> CountryID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4} |
| 111 | +
|
| 112 | +As you can see, in this case we only get one city, Paris in France. |
| 113 | + |
| 114 | +In this second tutorial we have used the operator Gt to obtain this city, |
| 115 | +for more details you can read :ref:`badaas-orm/query:Operators`. |
| 116 | + |
| 117 | +Tutorial 3: joins |
| 118 | +------------------------------- |
| 119 | + |
| 120 | +Although in the previous tutorial we achieved our goal of differentiating the two Paris, |
| 121 | +the way to do it is debatable since the population of the cities can evolve and, |
| 122 | +then, the result of this query can change. |
| 123 | +Therefore, we are now going to improve this query by obtaining the city called |
| 124 | +Paris whose country is called France. |
| 125 | + |
| 126 | +In the tutorial_3.go file you will find that we can perform this query as follows: |
| 127 | + |
| 128 | +.. code-block:: go |
| 129 | +
|
| 130 | + parisFrance, err := orm.NewQuery[models.City]( |
| 131 | + db, |
| 132 | + conditions.City.NameIs().Eq("Paris"), |
| 133 | + conditions.City.Country( |
| 134 | + conditions.Country.NameIs().Eq("France"), |
| 135 | + ), |
| 136 | + ).FindOne() |
| 137 | +
|
| 138 | +We can run this tutorial with `make tutorial_3` and we will obtain the following result: |
| 139 | + |
| 140 | +.. code-block:: bash |
| 141 | +
|
| 142 | + Cities named 'Paris' in 'France' are: |
| 143 | + 1: &{UUIDModel:{ID:eaa480a3-694e-4be3-9af5-ad935cdd57e2 CreatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:2161000 Country:<nil> CountryID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4} |
| 144 | +
|
| 145 | +As you can see, again we get only the Paris in France. |
| 146 | +As you may have noticed, in this case we have used the `FindOne` method instead of `Find`. |
| 147 | +This is because in this case we are sure that the result is a single model, |
| 148 | +so instead of getting a list we get a single city. |
| 149 | + |
| 150 | +In this third tutorial we have used a condition that performs a join, |
| 151 | +for more details you can read :ref:`badaas-orm/query:Use of the conditions`. |
| 152 | + |
| 153 | +Tutorial 4: preloading |
| 154 | +------------------------------- |
| 155 | + |
| 156 | +You may have noticed that in the results of the previous tutorials the Country field of the cities was null (Country:<nil>). |
| 157 | +This is because, to ensure performance, badaas-orm will retrieve only the attributes of the model |
| 158 | +you are querying (City in this case because the method used is orm.NewQuery[models.City]) |
| 159 | +but not of its relationships. If we also want to obtain this data, we must perform preloading. |
| 160 | + |
| 161 | +In the tutorial_4.go file you will find that we can perform this query as follows: |
| 162 | + |
| 163 | +.. code-block:: go |
| 164 | +
|
| 165 | + cities, err := orm.NewQuery[models.City]( |
| 166 | + db, |
| 167 | + conditions.City.NameIs().Eq("Paris"), |
| 168 | + conditions.City.PreloadCountry(), |
| 169 | + ).Find() |
| 170 | +
|
| 171 | +We can run this tutorial with `make tutorial_4` and we will obtain the following result: |
| 172 | + |
| 173 | +.. code-block:: bash |
| 174 | +
|
| 175 | + Cities named 'Paris' are: |
| 176 | + 1: &{UUIDModel:{ID:eaa480a3-694e-4be3-9af5-ad935cdd57e2 CreatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:2161000 Country:0xc0001d1600 CountryID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4} |
| 177 | + with country: &{UUIDModel:{ID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4 CreatedAt:2023-08-11 16:43:27.445202858 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.457191337 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:France Capital:<nil> CapitalID:eaa480a3-694e-4be3-9af5-ad935cdd57e2} |
| 178 | + 2: &{UUIDModel:{ID:8c3dfc38-1fc6-4ec9-a89b-e41018a54b4a CreatedAt:2023-08-11 16:43:27.468149185 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.468149185 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:25171 Country:0xc0001d1780 CountryID:0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921} |
| 179 | + with country: &{UUIDModel:{ID:0c4404f6-83c2-4bdf-93d5-a5ff2fe4f921 CreatedAt:2023-08-11 16:43:27.462357133 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.479800337 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:United States of America Capital:<nil> CapitalID:df44272e-c3db-4e18-876c-f9f579488716} |
| 180 | +
|
| 181 | +As you can see, now the country attribute is a valid pointer to a Country object (Country:0xc0001d1600). |
| 182 | +Then the Country object information is accessed with the `GetCountry` method. |
| 183 | +This method is not defined in the `models/models.go` file but is a :ref:`relation getter <badaas-orm/concepts:relation getter>` |
| 184 | +that is generated by badaas-cli together with the conditions. |
| 185 | +These methods allow us to differentiate null objects from objects not loaded from the database, |
| 186 | +since when trying to browse a relation that was not loaded we will get `errors.ErrRelationNotLoaded`. |
| 187 | + |
| 188 | +In this fourth tutorial we have used preloading and relation getters, |
| 189 | +for more details you can read :doc:`/badaas-orm/preloading`. |
| 190 | + |
| 191 | +Tutorial 5: dynamic operators |
| 192 | +------------------------------- |
| 193 | + |
| 194 | +So far we have performed operations that take as input a static value (equal to "Paris" or greater than 1000000) |
| 195 | +but what if now we would like to differentiate these two Paris from each other based on whether they |
| 196 | +are the capital of their country. |
| 197 | + |
| 198 | +In the tutorial_5.go file you will find that we can perform this query as follows: |
| 199 | + |
| 200 | +.. code-block:: go |
| 201 | +
|
| 202 | + cities, err := orm.NewQuery[models.City]( |
| 203 | + db, |
| 204 | + conditions.City.NameIs().Eq("Paris"), |
| 205 | + conditions.City.Country( |
| 206 | + conditions.Country.CapitalIdIs().Dynamic().Eq(conditions.City.ID), |
| 207 | + ), |
| 208 | + ).Find() |
| 209 | +
|
| 210 | +We can run this tutorial with `make tutorial_5` and we will obtain the following result: |
| 211 | + |
| 212 | +.. code-block:: bash |
| 213 | +
|
| 214 | + Cities named 'Paris' that are the capital of their country are: |
| 215 | + 1: &{UUIDModel:{ID:eaa480a3-694e-4be3-9af5-ad935cdd57e2 CreatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 UpdatedAt:2023-08-11 16:43:27.451393348 +0200 +0200 DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Paris Population:2161000 Country:<nil> CountryID:3739a825-bc5c-4350-a2bc-6e77e22fe3f4} |
| 216 | +
|
| 217 | +As you can see, again we only get the Paris in France. |
| 218 | + |
| 219 | +In this fifth tutorial we have used dynamic conditions, |
| 220 | +for more details you can read :ref:`badaas-orm/advanced_query:Dynamic operators`. |
0 commit comments