Raw.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. namespace db;
  3. use PDO;
  4. use PDOStatement;
  5. class Raw
  6. {
  7. private static PDO $instance;
  8. public static PDOStatement $db;
  9. public static PDOStatement $fortune;
  10. public static PDOStatement $random;
  11. /**
  12. * @var []PDOStatement
  13. */
  14. private static $update;
  15. public static function init()
  16. {
  17. $pdo = new PDO(
  18. 'pgsql:host=tfb-database;dbname=hello_world',
  19. 'benchmarkdbuser',
  20. 'benchmarkdbpass',
  21. [
  22. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  23. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  24. PDO::ATTR_EMULATE_PREPARES => false
  25. ]
  26. );
  27. self::$fortune = $pdo->prepare('SELECT id,message FROM Fortune');
  28. self::$random = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
  29. self::$instance = $pdo;
  30. }
  31. /**
  32. * Postgres bulk update
  33. *
  34. * @param array $worlds
  35. * @return void
  36. */
  37. public static function update(array $worlds)
  38. {
  39. $rows = count($worlds);
  40. if (!isset(self::$update[$rows])) {
  41. $sql = 'UPDATE world SET randomNumber = CASE id'
  42. . str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $rows)
  43. . 'END WHERE id IN ('
  44. . str_repeat('?::INTEGER,', $rows - 1) . '?::INTEGER)';
  45. self::$update[$rows] = self::$instance->prepare($sql);
  46. }
  47. $val = [];
  48. $keys = [];
  49. foreach ($worlds as $world) {
  50. $val[] = $keys[] = $world['id'];
  51. $val[] = $world['randomNumber'];
  52. }
  53. self::$update[$rows]->execute([...$val, ...$keys]);
  54. }
  55. /**
  56. * Alternative bulk update in Postgres
  57. *
  58. * @param array $worlds
  59. * @return void
  60. */
  61. public static function update2(array $worlds)
  62. {
  63. $rows = count($worlds);
  64. if (!isset(self::$update[$rows])) {
  65. $sql = 'UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES '
  66. . implode(', ', array_fill(0, $rows, '(?::INTEGER, ?::INTEGER)')) .
  67. ' ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id';
  68. self::$update[$rows] = self::$instance->prepare($sql);
  69. }
  70. $val = [];
  71. foreach ($worlds as $world) {
  72. $val[] = $world['id'];
  73. $val[] = $world['randomNumber'];
  74. //$update->bindParam(++$i, $world['id'], PDO::PARAM_INT);
  75. }
  76. self::$update[$rows]->execute($val);
  77. }
  78. }