Skip to content
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

Use SQLite instead of bbolt #779

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Use SQLite instead of bbolt #779

wants to merge 17 commits into from

Conversation

adombeck
Copy link
Contributor

@adombeck adombeck commented Feb 6, 2025

Our database requirements are better met by a relational database than a key value store, so we now use SQLite instead of bbolt.

UDENG-4890

@adombeck adombeck force-pushed the UDENG-4890-use-sqlite branch from 763b8ed to 99bfaab Compare February 6, 2025 18:10
Comment on lines +65 to +73
// TODO: I don't see why we should fail here instead of just fixing the permissions.
fileInfo, err := os.Stat(dbPath)
if err != nil {
return nil, fmt.Errorf("can't stat database file: %v", err)
}
perm := fileInfo.Mode().Perm()
if perm != 0600 {
return nil, fmt.Errorf("wrong file permission for %s: %o", dbPath, perm)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the reviewer: I copied this from the old code but added this TODO comment:

	// TODO: I don't see why we should fail here instead of just fixing the permissions.

Is there a good reason for failing or should we just fix the permissions?

internal/users/db/users.go Outdated Show resolved Hide resolved
@adombeck adombeck changed the title Use SQLite Use SQLite instead of bbolt Feb 7, 2025
@adombeck adombeck force-pushed the UDENG-4890-use-sqlite branch from 99bfaab to 79ce337 Compare February 10, 2025 14:04
@3v1n0 3v1n0 linked an issue Feb 10, 2025 that may be closed by this pull request
2 tasks
@adombeck adombeck marked this pull request as ready for review February 10, 2025 17:21
@adombeck adombeck requested a review from a team as a code owner February 10, 2025 17:21
@adombeck adombeck force-pushed the UDENG-4890-use-sqlite branch from 79ce337 to 7f0d869 Compare February 10, 2025 17:22
Changes done by running:

   git rm "internal/*/testdata/golden/*"
   TESTS_UPDATE_GOLDEN=1 go test ./internal/...
   git add -A
We don't use our database as a cache anymore. It's time to reflect this
in the package name.
We can't use the "AAAAATIME" placeholders anymore when using SQLite,
because the schema only allows actual timestamps.
We don't store the current UID in golden files anymore since
3f81332.
These files were forgotten in 5555836.

Also simplify the testdata for the "pam_unix_non_existent" test case,
because we don't need multiple users and groups for that test case.
@adombeck adombeck force-pushed the UDENG-4890-use-sqlite branch from 7f0d869 to 143ef36 Compare February 11, 2025 11:45
Our database requirements are better met by a relational database than a key value store, so we now use SQLite instead of bbolt.
Some cases were not tested.
And inline the `userRow` struct into `UserDB`, because it now doesn't
have any additional fields anymore.
@adombeck adombeck force-pushed the UDENG-4890-use-sqlite branch from 143ef36 to 1c7b268 Compare February 11, 2025 12:06

func allUsersInternal(db queryable) ([]userRow, error) {
query := fmt.Sprintf(`SELECT %s FROM users`, allUserColumns)
rows, err := db.Query(query)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per what I've been reading, these calls shouldn't be happen concurrently, so maybe we should have a wrapper struct that manages the db locking via a mutex? So that we don't risk of accessing to it when it's locked? Or are we using another way to prevent this to happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's taken care of by the use of transactions. All functions which write to the database use transactions, which lock the database.

log.Debugf(context.Background(), "Inserting into %s: %s", table, vals)

//nolint:gosec // We don't care about SQL injection in our tests.
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", table, columns, values)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any potential string escaping that we may miss here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None that I know of. Is it worth spending time trying to find one? I don't see why we should care about the SQL injection warning here.

for _, record := range records {
columns := ""
values := ""
var vals []interface{}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[]any instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 27 to 31
defer func() {
if err := rows.Close(); err != nil {
log.Warningf(context.Background(), "failed to close rows: %v", err)
}
}()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've enough of these calls that maybe they can be in a separated function to be just called with defer closeRows(rows)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On:

Migrate all testdata to SQLite

It would have been nice if the json-like to yaml format for the db files would have happened before of switching to sqlite, so that it's easier to track if something changed.

Is it possible (e.g. to use the newer syntax for the golden files before changing the db to sqlite)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's not possible. It's not the format which has changed (it was YAML and still is YAML), it's the structure of the database which has changed. Before, we had 7 different buckets, now we have 3 tables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue: DB cache tests are randomly failing based depending on current time
4 participants