Skip to content

Commit

Permalink
Fix DB prefixing for Postgres and SQLite (#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
jessarcher authored Jun 4, 2024
1 parent d5fc21c commit 7e32ed4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
32 changes: 24 additions & 8 deletions src/Storage/DatabaseStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ protected function upsertCount(array $values): int
[
'value' => match ($driver = $this->connection()->getDriverName()) {
'mariadb', 'mysql' => new Expression('`value` + values(`value`)'),
'pgsql', 'sqlite' => new Expression('"pulse_aggregates"."value" + "excluded"."value"'),
'pgsql', 'sqlite' => new Expression(<<<SQL
{$this->wrap('pulse_aggregates.value')} + "excluded"."value"
SQL),
default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
},
]
Expand All @@ -199,8 +201,12 @@ protected function upsertMin(array $values): int
[
'value' => match ($driver = $this->connection()->getDriverName()) {
'mariadb', 'mysql' => new Expression('least(`value`, values(`value`))'),
'pgsql' => new Expression('least("pulse_aggregates"."value", "excluded"."value")'),
'sqlite' => new Expression('min("pulse_aggregates"."value", "excluded"."value")'),
'pgsql' => new Expression(<<<SQL
least({$this->wrap('pulse_aggregates.value')}, "excluded"."value")
SQL),
'sqlite' => new Expression(<<<SQL
min({$this->wrap('pulse_aggregates.value')}, "excluded"."value")
SQL),
default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
},
]
Expand All @@ -220,8 +226,12 @@ protected function upsertMax(array $values): int
[
'value' => match ($driver = $this->connection()->getDriverName()) {
'mariadb', 'mysql' => new Expression('greatest(`value`, values(`value`))'),
'pgsql' => new Expression('greatest("pulse_aggregates"."value", "excluded"."value")'),
'sqlite' => new Expression('max("pulse_aggregates"."value", "excluded"."value")'),
'pgsql' => new Expression(<<<SQL
greatest({$this->wrap('pulse_aggregates.value')}, "excluded"."value")
SQL),
'sqlite' => new Expression(<<<SQL
max({$this->wrap('pulse_aggregates.value')}, "excluded"."value")
SQL),
default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
},
]
Expand All @@ -241,7 +251,9 @@ protected function upsertSum(array $values): int
[
'value' => match ($driver = $this->connection()->getDriverName()) {
'mariadb', 'mysql' => new Expression('`value` + values(`value`)'),
'pgsql', 'sqlite' => new Expression('"pulse_aggregates"."value" + "excluded"."value"'),
'pgsql', 'sqlite' => new Expression(<<<SQL
{$this->wrap('pulse_aggregates.value')} + "excluded"."value"
SQL),
default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
},
]
Expand All @@ -264,8 +276,12 @@ protected function upsertAvg(array $values): int
'count' => new Expression('`count` + values(`count`)'),
],
'pgsql', 'sqlite' => [
'value' => new Expression('("pulse_aggregates"."value" * "pulse_aggregates"."count" + ("excluded"."value" * "excluded"."count")) / ("pulse_aggregates"."count" + "excluded"."count")'),
'count' => new Expression('"pulse_aggregates"."count" + "excluded"."count"'),
'value' => new Expression(<<<SQL
({$this->wrap('pulse_aggregates.value')} * {$this->wrap('pulse_aggregates.count')} + ("excluded"."value" * "excluded"."count")) / ({$this->wrap('pulse_aggregates.count')} + "excluded"."count")
SQL),
'count' => new Expression(<<<SQL
{$this->wrap('pulse_aggregates.count')} + "excluded"."count"
SQL),
],
default => throw new RuntimeException("Unsupported database driver [{$driver}]"),
}
Expand Down
19 changes: 10 additions & 9 deletions tests/Feature/Recorders/SlowQueriesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
$event->time = 5000;
});

DB::connection()->statement('select * from users');
DB::connection()->statement($sql = 'select * from '.DB::getTablePrefix().'users');

Pulse::ingest();

Expand All @@ -26,7 +26,7 @@
'value' => 5000,
]);
$key = json_decode($entries[0]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->not->toBeNull();
$aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('period')->orderBy('aggregate')->get());
expect($aggregates)->toHaveCount(8);
Expand All @@ -38,7 +38,7 @@
'value' => 1,
]);
$key = json_decode($aggregates[0]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->not->toBeNull();
expect($aggregates[1])->toHaveProperties([
'bucket' => (int) (floor((now()->timestamp - 5) / 60) * 60),
Expand All @@ -48,7 +48,7 @@
'value' => 5000,
]);
$key = json_decode($aggregates[1]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->not->toBeNull();
});

Expand All @@ -59,7 +59,8 @@
$event->time = 5000;
});

DB::connection()->statement('select * from users');
DB::connection()->statement($sql = 'select * from '.DB::getTablePrefix().'users');

Pulse::ingest();

$entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
Expand All @@ -70,7 +71,7 @@
'value' => 5000,
]);
$key = json_decode($entries[0]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->toBeNull();
$aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('period')->orderBy('aggregate')->get());
expect($aggregates)->toHaveCount(8);
Expand All @@ -82,7 +83,7 @@
'value' => 1,
]);
$key = json_decode($aggregates[0]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->toBeNull();
expect($aggregates[1])->toHaveProperties([
'bucket' => (int) (floor((now()->timestamp - 5) / 60) * 60),
Expand All @@ -92,7 +93,7 @@
'value' => 5000,
]);
$key = json_decode($aggregates[1]->key);
expect($key[0])->toBe('select * from users');
expect($key[0])->toBe($sql);
expect($key[1])->toBeNull();
});

Expand Down Expand Up @@ -130,7 +131,7 @@
expect($entries[0]->key)->toContain('one_second_threshold');
expect($entries[0]->value)->toBe(1_000);

DB::table('pulse_entries')->delete();
Pulse::ignore(fn () => DB::table('pulse_entries')->delete());

$queryDuration = 2_000;
DB::pretend(function () {
Expand Down

0 comments on commit 7e32ed4

Please sign in to comment.