Audit items #17 and #21. #17 — DayOfWeekSignal and StickinessSignal each had their own isSqlite ternary picking between SQLite (strftime/julianday) and MySQL (DAYOFWEEK/DATEDIFF) date expressions. Centralised in App\Services\Prediction\Signals\DbDialect. #21 — ProfileValidationRules was a trait with one consumer (CreateNewUser); inlined the rules into the action and deleted the trait. Also dropped PasswordValidationRules::currentPasswordRules() which was unused. PasswordValidationRules trait stays (two consumers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
41 lines
1.2 KiB
PHP
41 lines
1.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Prediction\Signals;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
/**
|
|
* SQL dialect helpers for the small set of MySQL/SQLite differences the
|
|
* signal classes care about. Centralises the isSqlite ternaries that were
|
|
* duplicated across DayOfWeekSignal and StickinessSignal.
|
|
*/
|
|
final class DbDialect
|
|
{
|
|
private static function isSqlite(): bool
|
|
{
|
|
return DB::connection()->getDriverName() === 'sqlite';
|
|
}
|
|
|
|
/**
|
|
* Day-of-week expression returning 1=Sun..7=Sat (MySQL DAYOFWEEK convention).
|
|
* Targets a column on the queried table.
|
|
*/
|
|
public static function dayOfWeekExpr(string $column): string
|
|
{
|
|
return self::isSqlite()
|
|
? "(CAST(strftime('%w', {$column}) AS INTEGER) + 1)"
|
|
: "DAYOFWEEK({$column})";
|
|
}
|
|
|
|
/**
|
|
* Whole-day difference between MAX and MIN of a datetime column, suitable
|
|
* for use in an aggregate selectRaw.
|
|
*/
|
|
public static function maxMinDayDiffExpr(string $column): string
|
|
{
|
|
return self::isSqlite()
|
|
? "CAST((julianday(MAX({$column})) - julianday(MIN({$column}))) AS INTEGER)"
|
|
: "DATEDIFF(MAX({$column}), MIN({$column}))";
|
|
}
|
|
}
|