diff --git a/app/Jobs/StatServerJob.php b/app/Jobs/StatServerJob.php index 9c822cc..e8460a6 100644 --- a/app/Jobs/StatServerJob.php +++ b/app/Jobs/StatServerJob.php @@ -67,8 +67,11 @@ class StatServerJob implements ShouldQueue protected function processServerStat(int $u, int $d, int $recordAt): void { - if (config('database.default') === 'sqlite') { + $driver = config('database.default'); + if ($driver === 'sqlite') { $this->processServerStatForSqlite($u, $d, $recordAt); + } elseif ($driver === 'pgsql') { + $this->processServerStatForPostgres($u, $d, $recordAt); } else { $this->processServerStatForOtherDatabases($u, $d, $recordAt); } @@ -126,4 +129,33 @@ class StatServerJob implements ShouldQueue ] ); } + + /** + * PostgreSQL upsert with arithmetic increments using ON CONFLICT ... DO UPDATE + */ + protected function processServerStatForPostgres(int $u, int $d, int $recordAt): void + { + $table = (new StatServer())->getTable(); + $now = time(); + + // Use parameter binding to avoid SQL injection and keep maintainability + $sql = "INSERT INTO {$table} (record_at, server_id, server_type, record_type, u, d, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (server_id, server_type, record_at) + DO UPDATE SET + u = {$table}.u + EXCLUDED.u, + d = {$table}.d + EXCLUDED.d, + updated_at = EXCLUDED.updated_at"; + + DB::statement($sql, [ + $recordAt, + $this->server['id'], + $this->protocol, + $this->recordType, + $u, + $d, + $now, + $now, + ]); + } } diff --git a/app/Jobs/StatUserJob.php b/app/Jobs/StatUserJob.php index db00882..4e3b81c 100644 --- a/app/Jobs/StatUserJob.php +++ b/app/Jobs/StatUserJob.php @@ -63,8 +63,11 @@ class StatUserJob implements ShouldQueue protected function processUserStat(int $uid, array $v, int $recordAt): void { - if (config('database.default') === 'sqlite') { + $driver = config('database.default'); + if ($driver === 'sqlite') { $this->processUserStatForSqlite($uid, $v, $recordAt); + } elseif ($driver === 'pgsql') { + $this->processUserStatForPostgres($uid, $v, $recordAt); } else { $this->processUserStatForOtherDatabases($uid, $v, $recordAt); } @@ -122,4 +125,34 @@ class StatUserJob implements ShouldQueue ] ); } + + /** + * PostgreSQL upsert with arithmetic increments using ON CONFLICT ... DO UPDATE + */ + protected function processUserStatForPostgres(int $uid, array $v, int $recordAt): void + { + $table = (new StatUser())->getTable(); + $now = time(); + $u = ($v[0] * $this->server['rate']); + $d = ($v[1] * $this->server['rate']); + + $sql = "INSERT INTO {$table} (user_id, server_rate, record_at, record_type, u, d, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (user_id, server_rate, record_at) + DO UPDATE SET + u = {$table}.u + EXCLUDED.u, + d = {$table}.d + EXCLUDED.d, + updated_at = EXCLUDED.updated_at"; + + DB::statement($sql, [ + $uid, + $this->server['rate'], + $recordAt, + $this->recordType, + $u, + $d, + $now, + $now, + ]); + } } \ No newline at end of file