From a4a228b368e0eaea9806aa7c8b154e1c510ef6bc Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Mon, 20 Jan 2025 14:16:00 +0200 Subject: [PATCH] replaced exists bool db scans with int for broader drivers compatibility --- CHANGELOG.md | 4 +++- apis/realtime.go | 4 ++-- apis/record_crud.go | 8 ++++---- apis/record_helpers.go | 4 ++-- core/collection_model.go | 4 ++-- core/db.go | 4 ++-- core/db_table.go | 4 ++-- core/field_text.go | 4 ++-- core/migrations_runner.go | 4 ++-- core/migrations_runner_test.go | 4 ++-- core/record_query.go | 4 ++-- 11 files changed, 25 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a28981bc..f819f7f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,14 @@ - Added JSVM `new Timezone(name)` binding for constructing `time.Location` value ([#6219](https://github.com/pocketbase/pocketbase/discussions/6219)). -- Soft-deprecated `Record.GetUploadedFiles` in favour of `Record.GetUnsavedFiles` to minimize the ambiguities what the method do ([#6269](https://github.com/pocketbase/pocketbase/discussions/6269)). +- Soft-deprecated `Record.GetUploadedFiles` in favor of `Record.GetUnsavedFiles` to minimize the ambiguities what the method do ([#6269](https://github.com/pocketbase/pocketbase/discussions/6269)). (@todo update docs to reflect the `:unsaved` getter change) - Enforced `when_required` for the new AWS SDK request and response checksum validations to allow other non-AWS vendors to catch up with new AWS SDK changes (see [#6313](https://github.com/pocketbase/pocketbase/discussions/6313) and [aws/aws-sdk-go-v2#2960](https://github.com/aws/aws-sdk-go-v2/discussions/2960)). _You can set the environment variables `AWS_REQUEST_CHECKSUM_CALCULATION` and `AWS_RESPONSE_CHECKSUM_VALIDATION` to `when_supported` if your S3 vendor supports the new [new default integrity protections](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html)._ +- Other minor improvements (_replaced all `bool` exists db scans with `int` for broader drivers compatibility, use the non-transactional app instance during realtime records delete access checks to ensure that cascade deleted records with API rules relying on the parent will be resolved, updated UI dependencies, etc._) + ## v0.24.4 diff --git a/apis/realtime.go b/apis/realtime.go index 7d201ced..dc7ccc66 100644 --- a/apis/realtime.go +++ b/apis/realtime.go @@ -734,7 +734,7 @@ func realtimeCanAccessRecord( return false } - var exists bool + var exists int q := app.DB().Select("(1)"). From(record.Collection().Name). @@ -751,5 +751,5 @@ func realtimeCanAccessRecord( err = q.Limit(1).Row(&exists) - return err == nil && exists + return err == nil && exists > 0 } diff --git a/apis/record_crud.go b/apis/record_crud.go index ea6b60fa..4f6421c6 100644 --- a/apis/record_crud.go +++ b/apis/record_crud.go @@ -314,9 +314,9 @@ func recordCreate(optFinalizer func(data any) error) func(e *core.RequestEvent) resolver.UpdateQuery(ruleQuery) - var exists bool + var exists int err = ruleQuery.Limit(1).Row(&exists) - if err != nil || !exists { + if err != nil || exists == 0 { return e.BadRequestError("Failed to create record", fmt.Errorf("create rule failure: %w", err)) } } @@ -720,9 +720,9 @@ func hasAuthManageAccess(app core.App, requestInfo *core.RequestInfo, collection resolver.UpdateQuery(query) - var exists bool + var exists int err = query.Limit(1).Row(&exists) - return err == nil && exists + return err == nil && exists > 0 } diff --git a/apis/record_helpers.go b/apis/record_helpers.go index 10fec926..de5ff5b5 100644 --- a/apis/record_helpers.go +++ b/apis/record_helpers.go @@ -146,7 +146,7 @@ func wantsMFA(e *core.RequestEvent, record *core.Record) (bool, error) { return true, err } - var exists bool + var exists int query := e.App.RecordQuery(record.Collection()). Select("(1)"). @@ -165,7 +165,7 @@ func wantsMFA(e *core.RequestEvent, record *core.Record) (bool, error) { return true, err } - return exists, nil + return exists > 0, nil } // checkMFA handles any MFA auth checks that needs to be performed for the specified request event. diff --git a/core/collection_model.go b/core/collection_model.go index c8551129..3841231e 100644 --- a/core/collection_model.go +++ b/core/collection_model.go @@ -762,9 +762,9 @@ func (c *Collection) updateGeneratedIdIfExists(app App) { // add a number to the current id (if already exists) for i := 2; i < 1000; i++ { - var exists bool + var exists int _ = app.CollectionQuery().Select("(1)").AndWhere(dbx.HashExp{"id": newId}).Limit(1).Row(&exists) - if !exists { + if exists == 0 { break } newId = c.idChecksum() + strconv.Itoa(i) diff --git a/core/db.go b/core/db.go index 5d961e28..455a70c0 100644 --- a/core/db.go +++ b/core/db.go @@ -483,7 +483,7 @@ func validateRecordId(app App, collectionNameOrId string) validation.RuleFunc { return validation.NewError("validation_invalid_collection", "Missing or invalid collection.") } - var exists bool + var exists int rowErr := app.DB().Select("(1)"). From(collection.Name). @@ -491,7 +491,7 @@ func validateRecordId(app App, collectionNameOrId string) validation.RuleFunc { Limit(1). Row(&exists) - if rowErr != nil || !exists { + if rowErr != nil || exists == 0 { return validation.NewError("validation_invalid_record", "Missing or invalid record.") } diff --git a/core/db_table.go b/core/db_table.go index a6318982..332984b4 100644 --- a/core/db_table.go +++ b/core/db_table.go @@ -108,7 +108,7 @@ func (app *BaseApp) AuxHasTable(tableName string) bool { } func (app *BaseApp) hasTable(db dbx.Builder, tableName string) bool { - var exists bool + var exists int err := db.Select("(1)"). From("sqlite_schema"). @@ -117,7 +117,7 @@ func (app *BaseApp) hasTable(db dbx.Builder, tableName string) bool { Limit(1). Row(&exists) - return err == nil && exists + return err == nil && exists > 0 } // Vacuum executes VACUUM on the current app.DB() instance diff --git a/core/field_text.go b/core/field_text.go index e30d299c..af683ffa 100644 --- a/core/field_text.go +++ b/core/field_text.go @@ -193,14 +193,14 @@ func (f *TextField) ValidateValue(ctx context.Context, app App, record *Record) // // (@todo eventually may get replaced in the future with a system unique constraint to avoid races or wrapping the request in a transaction) if f.Pattern != defaultLowercaseRecordIdPattern { - var exists bool + var exists int err := app.DB(). Select("(1)"). From(record.TableName()). Where(dbx.NewExp("id = {:id} COLLATE NOCASE", dbx.Params{"id": strings.ToLower(newVal)})). Limit(1). Row(&exists) - if exists || (err != nil && !errors.Is(err, sql.ErrNoRows)) { + if exists > 0 || (err != nil && !errors.Is(err, sql.ErrNoRows)) { return validation.NewError("validation_pk_invalid", "The record primary key is invalid or already exists.") } } diff --git a/core/migrations_runner.go b/core/migrations_runner.go index b5258675..76aac1dd 100644 --- a/core/migrations_runner.go +++ b/core/migrations_runner.go @@ -267,7 +267,7 @@ func (r *MigrationsRunner) initMigrationsTable() error { } func (r *MigrationsRunner) isMigrationApplied(txApp App, file string) bool { - var exists bool + var exists int err := txApp.DB().Select("(1)"). From(r.tableName). @@ -275,7 +275,7 @@ func (r *MigrationsRunner) isMigrationApplied(txApp App, file string) bool { Limit(1). Row(&exists) - return err == nil && exists + return err == nil && exists > 0 } func (r *MigrationsRunner) saveAppliedMigration(txApp App, file string) error { diff --git a/core/migrations_runner_test.go b/core/migrations_runner_test.go index a42cdee8..a4c0c93f 100644 --- a/core/migrations_runner_test.go +++ b/core/migrations_runner_test.go @@ -200,7 +200,7 @@ func TestMigrationsRunnerRemoveMissingAppliedMigrations(t *testing.T) { } func isMigrationApplied(app core.App, file string) bool { - var exists bool + var exists int err := app.DB().Select("(1)"). From(core.DefaultMigrationsTable). @@ -208,5 +208,5 @@ func isMigrationApplied(app core.App, file string) bool { Limit(1). Row(&exists) - return err == nil && exists + return err == nil && exists > 0 } diff --git a/core/record_query.go b/core/record_query.go index 8f20d8ee..98fd8e09 100644 --- a/core/record_query.go +++ b/core/record_query.go @@ -584,7 +584,7 @@ func (app *BaseApp) CanAccessRecord(record *Record, requestInfo *RequestInfo, ac return true, nil } - var exists bool + var exists int query := app.RecordQuery(record.Collection()). Select("(1)"). @@ -603,5 +603,5 @@ func (app *BaseApp) CanAccessRecord(record *Record, requestInfo *RequestInfo, ac return false, err } - return exists, nil + return exists > 0, nil }