<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ceres/model, branch exchange-format</title>
<subtitle>Recipe server for your favorite dishes</subtitle>
<id>https://cgit.xengineering.eu/ceres/atom?h=exchange-format</id>
<link rel='self' href='https://cgit.xengineering.eu/ceres/atom?h=exchange-format'/>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/'/>
<updated>2024-11-03T15:05:55Z</updated>
<entry>
<title>model: Implement favorite recipes</title>
<updated>2024-11-03T15:05:55Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-11-03T14:49:43Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=7cd3a096a975801a07fb3ff06b6fac70e17234ce'/>
<id>urn:sha1:7cd3a096a975801a07fb3ff06b6fac70e17234ce</id>
<content type='text'>
This adds the ability to store a flag `is_favorite` inside the database.
The corresponding SQL migration is part of this commit.

Furthermore the Go code in the model package is adapted.
</content>
</entry>
<entry>
<title>view: Order ingredient summary by ingredient name</title>
<updated>2024-10-24T18:14:14Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-24T15:24:00Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=9422e8194245c9cdbfa09b38c20173964349e2a2'/>
<id>urn:sha1:9422e8194245c9cdbfa09b38c20173964349e2a2</id>
<content type='text'>
This makes it easier to write a shopping list for the required
ingredients.
</content>
</entry>
<entry>
<title>Rework error handling of model.DB.Transaction()</title>
<updated>2024-10-24T15:01:24Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-24T15:01:24Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=dc37aaceea903fcc84144c7566a14b3c5378dcaf'/>
<id>urn:sha1:dc37aaceea903fcc84144c7566a14b3c5378dcaf</id>
<content type='text'>
The functions in the sub-packages model, view and controller should not
log too much. Instead they should return errors which can be extended by
fmt.Errorf("&lt;some mesage&gt;: %w", err).
</content>
</entry>
<entry>
<title>Fix unit tests</title>
<updated>2024-10-23T16:42:20Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-23T16:41:45Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=9704fcb5e98ff4cfee39b9754b8fb112998e4194'/>
<id>urn:sha1:9704fcb5e98ff4cfee39b9754b8fb112998e4194</id>
<content type='text'>
API changes were not adopted in the unit tests.
</content>
</entry>
<entry>
<title>model: Rename to db.go</title>
<updated>2024-10-21T19:37:54Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-21T19:37:54Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=f917bc9e1973bfc1c6ab56bf1362295f89d687c3'/>
<id>urn:sha1:f917bc9e1973bfc1c6ab56bf1362295f89d687c3</id>
<content type='text'>
The old name database.go did not match the type name DB.
</content>
</entry>
<entry>
<title>model: Refactor public API of DB</title>
<updated>2024-10-21T19:34:31Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-21T19:30:12Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=72601b87ef040a3c6882368ac85c12c1ae705cd2'/>
<id>urn:sha1:72601b87ef040a3c6882368ac85c12c1ae705cd2</id>
<content type='text'>
This commit makes not externally needed methods private and adds error
return values since something like log.Fatal() should be called outside
this package since it is control-flow-related.
</content>
</entry>
<entry>
<title>model: Save int-based schema version in DB</title>
<updated>2024-10-21T19:34:26Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-15T19:23:10Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=118e1c69057e4e7b6ab3e730d5628b4822ed4c4d'/>
<id>urn:sha1:118e1c69057e4e7b6ab3e730d5628b4822ed4c4d</id>
<content type='text'>
Ceres v0.4.0 used the `git describe` output as database schema and
enforced exactly matching versions between the database and the
executable.

This turned out to be not flexible enough. It is way easier to version
the database separately with a simple integer and require the same
database schema version integer between the application and the
database.

This commit implements this new approach.
</content>
</entry>
<entry>
<title>model: Handle schema versions internally by integers</title>
<updated>2024-10-15T18:25:38Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-13T18:34:29Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=1904f50084660ce587a67d49939fd0734fd8a582'/>
<id>urn:sha1:1904f50084660ce587a67d49939fd0734fd8a582</id>
<content type='text'>
This references the database schemas known from the past with integer
values internally. 0 is used for an empty database and 1 for what was
used in ceres version 0.4.0.

The old approach to write the `git describe` output into the database
worked well for released versions but was problematic during
development. A numerical and separate database schema versioning is
easier to handle.
</content>
</entry>
<entry>
<title>model: Simplify DB method signatures</title>
<updated>2024-10-13T18:21:00Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-13T18:21:00Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=5ca945112b5cd7c92eb3b9da81597fcba5256b56'/>
<id>urn:sha1:5ca945112b5cd7c92eb3b9da81597fcba5256b56</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Replace global db variable by custom type</title>
<updated>2024-10-13T17:55:38Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-13T17:52:28Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=473052ed8f2c83052ed5b47a7f4cec68ac2621a6'/>
<id>urn:sha1:473052ed8f2c83052ed5b47a7f4cec68ac2621a6</id>
<content type='text'>
Reducing global variables makes it easier to understand functions
independently of the rest of the code.

Adding the new model.DB type as a custom variant of the sql.DB type
makes it possible to write methods for the database which makes the code
way more readable.
</content>
</entry>
<entry>
<title>Introduce xengineering.eu/ceres/model/migrations</title>
<updated>2024-10-13T16:54:18Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-10-13T12:08:26Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=ed19b82335345833c5b8f5446237d559a3657a35'/>
<id>urn:sha1:ed19b82335345833c5b8f5446237d559a3657a35</id>
<content type='text'>
This new package is only for database migrations. All data for Ceres
should be stored inside the SQLite3 database. Thus migrations can always
be executed with functions with the following signature.

    func(tx *sql.Tx) error

Those migration functions should be stored inside the new package.
Bigger SQL code can be stored in *.sql files for better syntax
highlighting. This code is embedded into the final Go executable by
using the embed package.
</content>
</entry>
<entry>
<title>model: Fix direct access to database</title>
<updated>2024-10-12T13:24:33Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-17T20:49:15Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=9d3a5fb85dc02e87fab879855c4c3bace5f753f2'/>
<id>urn:sha1:9d3a5fb85dc02e87fab879855c4c3bace5f753f2</id>
<content type='text'>
Instead a database transaction has to be used. Each database interaction
should be wrapped into a transaction to make sure any possible change
(even side-effects) can be rolled back in case of errors.
</content>
</entry>
<entry>
<title>Apply go fmt to all source files</title>
<updated>2024-09-11T18:25:54Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-09-11T18:25:31Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=54029aac92f17ec87d3ef0bb73fcdac271b209c9'/>
<id>urn:sha1:54029aac92f17ec87d3ef0bb73fcdac271b209c9</id>
<content type='text'>
This applies default Go code style recommendations.
</content>
</entry>
<entry>
<title>model: Add strict Ingredient.Validate()</title>
<updated>2024-05-17T21:20:41Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-15T18:18:39Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=bc149ee58122effc9d4c035da2af3a7ec1f2f862'/>
<id>urn:sha1:bc149ee58122effc9d4c035da2af3a7ec1f2f862</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Add strict Step.Validate()</title>
<updated>2024-05-17T21:16:36Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-15T18:18:13Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=f8f5d296f218f79646a54d3aed8d54fa9f8704c1'/>
<id>urn:sha1:f8f5d296f218f79646a54d3aed8d54fa9f8704c1</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Fix another unhandled error</title>
<updated>2024-05-17T21:15:56Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-17T21:15:56Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=5194ea4b29ffef0fe5206899243339cf109af41d'/>
<id>urn:sha1:5194ea4b29ffef0fe5206899243339cf109af41d</id>
<content type='text'>
This could also lead to bugs.
</content>
</entry>
<entry>
<title>model: Fix ignored error</title>
<updated>2024-05-17T21:10:17Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-17T21:08:05Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=5d5580285a366e37ac00a4e1a6f2f1bda853ff28'/>
<id>urn:sha1:5d5580285a366e37ac00a4e1a6f2f1bda853ff28</id>
<content type='text'>
An ignored return value here caused a serious bug as soon as validation
for ingredients was tried. The validation could raise an error e.g. on a
negative amount for the ingredient. This error was ignored at the
changed line which resulted into deleted ingredients for the whole
recipe.
</content>
</entry>
<entry>
<title>model: Rework recipe validation</title>
<updated>2024-05-17T15:14:40Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-17T15:12:50Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=5eca3267d37cdc51f775b5452727efebbb7e7e9e'/>
<id>urn:sha1:5eca3267d37cdc51f775b5452727efebbb7e7e9e</id>
<content type='text'>
This reduces code duplication and enforces time stamps.
</content>
</entry>
<entry>
<title>model: Make Recipe.Validate() more strict</title>
<updated>2024-05-15T18:09:35Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-15T18:09:35Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=ae771a44c2ffe31dc1bd67a12b65849f7d7d2d11'/>
<id>urn:sha1:ae771a44c2ffe31dc1bd67a12b65849f7d7d2d11</id>
<content type='text'>
Before the next release this method should be as strict as possible to
avoid cases where actually invalid enters databases.
</content>
</entry>
<entry>
<title>view: Add ingredient overview to recipe read page</title>
<updated>2024-05-12T18:52:25Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-04-07T10:04:11Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=bf328dd38a28cf44cfa81c7f1dcd95936d2d0301'/>
<id>urn:sha1:bf328dd38a28cf44cfa81c7f1dcd95936d2d0301</id>
<content type='text'>
</content>
</entry>
<entry>
<title>view: Show ingredients on read page</title>
<updated>2024-05-12T18:52:25Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-04-07T09:56:20Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=01d97189d245300d65ca31d650dd868d1d1fc0d8'/>
<id>urn:sha1:01d97189d245300d65ca31d650dd868d1d1fc0d8</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Add per-step ingredients</title>
<updated>2024-05-12T18:52:25Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-04-04T12:54:21Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=87ae71413e47ef34da57bc1e0b8dddbf84b0c66a'/>
<id>urn:sha1:87ae71413e47ef34da57bc1e0b8dddbf84b0c66a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Inject examples only with new --example flag</title>
<updated>2024-05-09T20:37:03Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T20:33:42Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=0ac3cc76b4b6c824c4b3f7a357d40b487984abfb'/>
<id>urn:sha1:0ac3cc76b4b6c824c4b3f7a357d40b487984abfb</id>
<content type='text'>
The default use case should be to not inject example recipes.
</content>
</entry>
<entry>
<title>model: Fix unit tests</title>
<updated>2024-05-09T20:23:28Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T20:23:28Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=0142af99aba36241c276a56a088e7aac10c62f86'/>
<id>urn:sha1:0142af99aba36241c276a56a088e7aac10c62f86</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Rename version to execVersion</title>
<updated>2024-05-09T20:12:54Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T20:12:54Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=f7fca11c47224ff28b10a7f41fb76ce0404a0236'/>
<id>urn:sha1:f7fca11c47224ff28b10a7f41fb76ce0404a0236</id>
<content type='text'>
This makes the code easier to understand because there is an executable
version and a database version handled inside that file.
</content>
</entry>
<entry>
<title>model: Require same version for executable and DB</title>
<updated>2024-05-09T20:04:06Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T20:04:06Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=0e8a199d6144fcfab05eb0c8a793073bc53783be'/>
<id>urn:sha1:0e8a199d6144fcfab05eb0c8a793073bc53783be</id>
<content type='text'>
Currently only an empty database and an existing database with the same
version are supported.

Support for migrations based on semantic versioning will be added in
future versions of Ceres.
</content>
</entry>
<entry>
<title>model: Migrate only in empty databases</title>
<updated>2024-05-09T19:59:01Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T19:59:01Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=e5d57f2c4a9f01ac7a2b11c04b932311bd240611'/>
<id>urn:sha1:e5d57f2c4a9f01ac7a2b11c04b932311bd240611</id>
<content type='text'>
</content>
</entry>
<entry>
<title>model: Initial database version injection</title>
<updated>2024-05-09T19:48:56Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T19:48:56Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=ca96df29085f9ca6567cd474d0920e48c6410b42'/>
<id>urn:sha1:ca96df29085f9ca6567cd474d0920e48c6410b42</id>
<content type='text'>
If the database was empty on startup a metadata table with a key and
value row is created.

In addition the Ceres executable version is inserted as value under the
key 'version'.

This allows to detect on not-empty databases which Ceres version was
used before which is the starting point to implement migrations.
</content>
</entry>
<entry>
<title>model: Detect if database is empty</title>
<updated>2024-05-09T19:31:19Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T19:31:19Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=ca19c73b305932a4ef41d31787eabb25f9417a05'/>
<id>urn:sha1:ca19c73b305932a4ef41d31787eabb25f9417a05</id>
<content type='text'>
An empty database requires to add the metadata table with the version
entry to make migrations possible. Thus this detection will be required.
</content>
</entry>
<entry>
<title>model: Wrap migration completely in transaction</title>
<updated>2024-05-09T19:10:50Z</updated>
<author>
<name>xengineering</name>
<email>me@xengineering.eu</email>
</author>
<published>2024-05-09T19:10:15Z</published>
<link rel='alternate' type='text/html' href='https://cgit.xengineering.eu/ceres/commit/?id=2db08f564ddb38e80c79c9338047f4e8f3a977e8'/>
<id>urn:sha1:2db08f564ddb38e80c79c9338047f4e8f3a977e8</id>
<content type='text'>
This makes it more clear that the full migration will be rolled back on
errors.
</content>
</entry>
</feed>
