Skip to content

Import Icinga Notifications internal/utils #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 8, 2025

Conversation

oxzi
Copy link
Member

@oxzi oxzi commented Apr 28, 2025

This PR imports the internal/utils package from Icinga Notifications into utils for general purpose functions and into database for database-related utility functions. The commit history was kept, but messages were slightly altered since the original messages often referred changes outside the internal/utils package.

My motivation for this merge was to use a utility function already implemented, but residing in the wrong project's utility package. Since the IGL is the place for common code, I would like to get rid of utility packages outside this repository.

Steps performed to create this PR

Create Patches

Within the icinga-notifications repository.

$ cd internal/utils
$ git format-patch --relative --root -- ./
0001-Introduce-utils-package.patch
0002-Move-helper-function-to-utils-package.patch
0003-Implement-incremental-config-updates-for-rules.patch
0004-Add-utils-ToDBInt-function.patch
0005-Use-sqlx.Tx-for-event-processing.patch
0006-Use-ctx-everywhere-cache-object-only-when-the-tx-suc.patch
0007-Trigger-time-based-escalations.patch
0008-Rename-and-simplify-restoreAttrsFor-function.patch
0009-Make-sure-to-release-semaphore-in-utils-ForEachRow.patch
0010-utils.IterateOrderedMap-for-plugin.FormatMessage.patch
0011-Switch-to-icinga-go-library.patch
0012-Drop-unused-Remove-utils-functions.patch
0013-Restore-all-muted-objects-without-an-incident-on-dae.patch
0014-Make-logging-more-consistent.patch
0015-Use-utils.IterateOrderedMap-as-intended-via-for-rang.patch
$ cd -
$ mv internal/utils/*.patch .
$ ls *.patch

Apply Patches

Within this repository.

First, create a githook(5) to verify each applied patch works.
Plot twist: each patch will fail now.

$ cat .git/hooks/pre-applypatch
#!/usr/bin/env bash
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}

go build
go test -race -count=1 ./...

Start applying patches:

$ git am -3 --directory utils/ ../icinga-notifications/*.patch

Each patch now requires some manual intervention, e.g., making it compile or manually move some code to ./database/util.go.

If the current patch works, build it manually once and continue afterwards.

$ git add utils/ database/ && git am --continue

The 0011-Switch-to-icinga-go-library.patch patch was skipped since it does not made sense in this context.

Verifying Methods

To make sure that nothing was lost, I have manually diffed each function.

@@ -1,5 +1,5 @@
 // BuildInsertStmtWithout builds an insert stmt without the provided column.
-func BuildInsertStmtWithout(db *database.DB, into interface{}, withoutColumn string) string {
+func BuildInsertStmtWithout(db *DB, into interface{}, withoutColumn string) string {
        columns := db.BuildColumns(into)
        for i, column := range columns {
                if column == withoutColumn {
@@ -11,7 +11,7 @@

        return fmt.Sprintf(
                `INSERT INTO "%s" ("%s") VALUES (%s)`,
-               database.TableName(into), strings.Join(columns, `", "`),
+               TableName(into), strings.Join(columns, `", "`),
                fmt.Sprintf(":%s", strings.Join(columns, ", :")),
        )
 }
@@ -3,7 +3,7 @@
 // A new transaction is started on db which is then passed to fn. After fn returns, the transaction is
 // committed unless an error was returned. If fn returns an error, that error is returned, otherwise an
 // error is returned if a database operation fails.
-func RunInTx(ctx context.Context, db *database.DB, fn func(tx *sqlx.Tx) error) error {
+func RunInTx(ctx context.Context, db *DB, fn func(tx *sqlx.Tx) error) error {
        tx, err := db.BeginTxx(ctx, nil)
        if err != nil {
                return err
@@ -1,7 +1,7 @@
 // InsertAndFetchId executes the given query and fetches the last inserted ID.
 func InsertAndFetchId(ctx context.Context, tx *sqlx.Tx, stmt string, args any) (int64, error) {
        var lastInsertId int64
-       if tx.DriverName() == database.PostgreSQL {
+       if tx.DriverName() == PostgreSQL {
                preparedStmt, err := tx.PrepareNamedContext(ctx, stmt+" RETURNING id")
                if err != nil {
                        return 0, err
@@ -1,7 +1,7 @@
 // ExecAndApply applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
 // Returns error on any database failure or fails to acquire the table semaphore.
-func ExecAndApply[Row any](ctx context.Context, db *database.DB, stmt string, args []interface{}, restoreFunc func(*Row)) error {
-       table := database.TableName(new(Row))
+func ExecAndApply[Row any](ctx context.Context, db *DB, stmt string, args []interface{}, restoreFunc func(*Row)) error {
+       table := TableName(new(Row))
        sem := db.GetSemaphoreForTable(table)
        if err := sem.Acquire(ctx, 1); err != nil {
                return errors.Wrapf(err, "cannot acquire semaphore for table %q", table)
@@ -1,7 +1,7 @@
 // ForEachRow applies the provided restoreFunc callback for each successfully retrieved row of the specified type.
 // It will bulk SELECT the data from the database scoped to the specified ids and scans into the provided Row type.
 // Returns error on any database failure or fails to acquire the table semaphore.
-func ForEachRow[Row, Id any](ctx context.Context, db *database.DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
+func ForEachRow[Row, Id any](ctx context.Context, db *DB, idColumn string, ids []Id, restoreFunc func(*Row)) error {
        subject := new(Row)
        query := fmt.Sprintf("%s WHERE %q IN (?)", db.BuildSelectStmt(subject, subject), idColumn)
        stmt, args, err := sqlx.In(query, ids)

No diff for ToDBString, ToDBInt, and IterateOrderedMap.

Reword Commit Messages

Since most commit messages referred a certain change and the changes in the util.go file was a drive-by change, I have reworded each commit message and linked the original commit on GitHub.

Cleanup

As further specified in #127 (comment), some functions and commits were dropped again.

@oxzi oxzi requested a review from julianbrost April 28, 2025 14:13
@cla-bot cla-bot bot added the cla/signed CLA is signed by all contributors of a PR label Apr 28, 2025
oxzi added a commit to Icinga/icinga-notifications that referenced this pull request Apr 28, 2025
With Icinga/icinga-go-library#127 being merged,
the internal/utils package will be moved to the IGL and can be removed
here. This is another step to unify our Go codebase.
@oxzi oxzi marked this pull request as draft April 28, 2025 14:53
@oxzi oxzi marked this pull request as ready for review April 28, 2025 14:53
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch from 7fc3dce to 944fc74 Compare April 29, 2025 06:04
@oxzi oxzi marked this pull request as draft April 29, 2025 09:40
@oxzi
Copy link
Member Author

oxzi commented Apr 29, 2025

Additional changes after a note from @lippserd:

Furthermore, I have removed the two commits adding Remove{If,Nils} and removing them again.

@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch 3 times, most recently from ee2d0e0 to 05bc544 Compare April 29, 2025 13:06
@oxzi oxzi marked this pull request as ready for review April 29, 2025 13:07
@oxzi oxzi modified the milestones: 0.7.0, 0.6.4 Apr 29, 2025
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch from 05bc544 to fa35896 Compare April 29, 2025 13:15
@oxzi oxzi requested a review from lippserd April 29, 2025 13:20
oxzi added a commit to Icinga/icinga-notifications that referenced this pull request Apr 29, 2025
With Icinga/icinga-go-library#64 and
Icinga/icinga-go-library#127 being merged,
the internal/utils package is moved to the IGL and can be removed
here. This is another step to unify our Go codebase.
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch from fa35896 to c8349a9 Compare April 30, 2025 12:21
@oxzi oxzi requested a review from lippserd April 30, 2025 12:24
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch from c8349a9 to 67cd647 Compare April 30, 2025 12:47
oxzi added a commit to Icinga/icinga-notifications that referenced this pull request Apr 30, 2025
With Icinga/icinga-go-library#64 and
Icinga/icinga-go-library#127 being merged,
the internal/utils package is moved to the IGL and can be removed
here. This is another step to unify our Go codebase.
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch 2 times, most recently from 61f2a44 to ec0f388 Compare May 7, 2025 11:42
oxzi and others added 4 commits May 7, 2025 14:10
This change was the result of investigating Go's new rangefunc
experiment[0]. The utilization of this novel language feature - which can
also be indirectly used in the absence of `GOEXPERIMENT=rangefunc` - ensures
that the map is traversed in key order.

[0]: https://go.dev/wiki/RangefuncExperiment

Imported from Icinga/icinga-notifications@e371553
Doing so allows multiple columns to be excluded without breaking the API
compatibility. Recently added slices functions even shortens the code.
The MakeString function got another variadic parameter, allowing
multiple transformers against the newly created String. As one example,
the newly introduced TransformEmptyStringToNull function can be used,
mimicking Icinga Notifications' ToDBString behavior.

To replace Icinga Notifications' ToDBInt utility function, a similar
MakeInt function and TransformZeroIntToNull was introduced.

Inspired by:
- ToDBInt, Icinga/icinga-notifications@f0b39f0
- ToDBString, Icinga/icinga-notifications@8183344
@oxzi oxzi force-pushed the import-utils-from-icinga-notifications branch from ec0f388 to 41e23b6 Compare May 7, 2025 12:15
@oxzi oxzi requested a review from lippserd May 7, 2025 12:15
oxzi added a commit to Icinga/icinga-notifications that referenced this pull request May 8, 2025
With Icinga/icinga-go-library#64 and
Icinga/icinga-go-library#127 being merged, most
of the internal/utils package is moved to the IGL and can be removed
here. This is another step to unify our Go codebase.
@oxzi
Copy link
Member Author

oxzi commented May 8, 2025

I have successfully tested Icinga Notifications with this changes in Icinga/icinga-notifications#310 and a replace statement in the go.mod file.

@oxzi oxzi merged commit d262a5e into main May 8, 2025
15 checks passed
@oxzi oxzi deleted the import-utils-from-icinga-notifications branch May 8, 2025 07:36
@lippserd lippserd removed the request for review from julianbrost May 8, 2025 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla/signed CLA is signed by all contributors of a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants