Browse Source

[workerman] Remove globals vars in pgsql (#7313)

* [workerman] Remove globals vars in pgsql

* Delete 1 more global var
Joan Miquel 3 years ago
parent
commit
4698fc54e7

+ 118 - 0
frameworks/PHP/workerman/app-pg.php

@@ -0,0 +1,118 @@
+<?php
+use Workerman\Protocols\Http\Response;
+use Workerman\Protocols\Http\Request;
+
+include 'dbraw.php';
+
+
+function router(Request $request)
+{
+    return match($request->path()) {
+        '/plaintext' => text(),
+        '/json'      => json(), 
+        '/db'        => db(),
+        '/fortunes'  => fortune(),
+        '/query'     => query($request),
+        '/update'    => updateraw($request),
+        // '/info'      => info(),
+        default      => new Response(404, [], 'Error 404'),
+    };
+}
+
+function text()
+{
+    return new Response(200, [
+        'Content-Type' => 'text/plain',
+        'Date'         => Header::$date
+    ], 'Hello, World!');
+}
+
+function json()
+{
+    return new Response(200, [
+        'Content-Type' => 'application/json',
+        'Date'         => Header::$date
+    ], json_encode(['message' => 'Hello, World!']));
+}
+
+function db()
+{
+    DbRaw::$random->execute([mt_rand(1, 10000)]);
+
+    return new Response(200, [
+        'Content-Type' => 'application/json',
+        'Date'         => Header::$date
+    ], json_encode(DbRaw::$random->fetch()));
+}
+
+function query($request)
+{
+    $query_count = 1;
+    $q = (int) $request->get('q');
+    if ($q > 1) {
+        $query_count = min($q, 500);
+    }
+
+    while ($query_count--) {
+        DbRaw::$random->execute([mt_rand(1, 10000)]);
+        $arr[] = DbRaw::$random->fetch();
+    }
+
+    return new Response(200, [
+        'Content-Type' => 'application/json',
+        'Date'         => Header::$date
+    ], json_encode($arr));
+}
+
+function updateraw($request)
+{
+    $query_count = 1;
+    $q = (int) $request->get('q');
+    if ($q > 1) {
+        $query_count = min($q, 500);
+    }
+
+    while ($query_count--) {
+
+        DbRaw::$random->execute([mt_rand(1, 10000)]);
+        $row = DbRaw::$random->fetch();
+        $row['randomNumber'] = mt_rand(1, 10000);
+
+        $worlds[] = $row;
+    }
+
+    DbRaw::update($worlds);
+
+    return new Response(200, [
+        'Content-Type' => 'application/json',
+        'Date'         => Header::$date
+    ], json_encode($worlds));
+}
+
+function fortune()
+{
+    DbRaw::$fortune->execute();
+
+    $arr    = DbRaw::$fortune->fetchAll(PDO::FETCH_KEY_PAIR);
+    $arr[0] = 'Additional fortune added at request time.';
+    asort($arr);
+
+    $html = '';
+    foreach ($arr as $id => $message) {
+        $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
+        $html .= "<tr><td>$id</td><td>$message</td></tr>";
+    }
+
+    return new Response(200, [
+        'Date'         => Header::$date
+    ], "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>"
+    );
+}
+
+/* function info()
+{
+    ob_start();
+    phpinfo();
+    return new Response(200, ['Content-Type' => 'text/plain'], ob_get_clean());
+}
+ */

+ 88 - 0
frameworks/PHP/workerman/dbraw.php

@@ -0,0 +1,88 @@
+<?php
+
+class DbRaw
+{
+    private static PDO $instance;
+    public static PDOStatement $db;
+    public static PDOStatement $fortune;
+    public static PDOStatement $random;
+    /**
+     * @var []PDOStatement
+     */
+    private static $update;
+
+    public static function init()
+    {
+        $pdo = new PDO(
+            'pgsql:host=tfb-database;dbname=hello_world',
+            'benchmarkdbuser',
+            'benchmarkdbpass',
+            [
+                PDO::ATTR_DEFAULT_FETCH_MODE  => PDO::FETCH_ASSOC,
+                PDO::ATTR_ERRMODE             => PDO::ERRMODE_EXCEPTION,
+                PDO::ATTR_EMULATE_PREPARES    => false
+            ]
+        );
+
+        self::$fortune   = $pdo->prepare('SELECT id,message FROM Fortune');
+        self::$random    = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
+        self::$instance  = $pdo;
+    }
+
+    /**
+     * Postgres bulk update
+     *
+     * @param array $worlds
+     * @return void
+     */
+    public static function update(array $worlds)
+    {
+        $rows = count($worlds);
+
+        if (!isset(self::$update[$rows])) {
+            $sql = 'UPDATE world SET randomNumber = CASE id'
+                . str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $rows)
+                . 'END WHERE id IN ('
+                . str_repeat('?::INTEGER,', $rows - 1) . '?::INTEGER)';
+
+            self::$update[$rows] = self::$instance->prepare($sql);
+        }
+
+        $val = [];
+        $keys = [];
+        foreach ($worlds as $world) {
+            $val[] = $keys[] = $world['id'];
+            $val[] = $world['randomNumber'];
+        }
+
+        self::$update[$rows]->execute([...$val, ...$keys]);
+    }
+
+    /**
+     * Alternative bulk update in Postgres
+     *
+     * @param array $worlds
+     * @return void
+     */
+    public static function update2(array $worlds)
+    {
+        $rows = count($worlds);
+
+        if (!isset(self::$update[$rows])) {
+            $sql = 'UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES '
+                . implode(', ', array_fill(0, $rows, '(?::INTEGER, ?::INTEGER)')) .
+                ' ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id';
+
+            self::$update[$rows] = self::$instance->prepare($sql);
+        }
+
+        $val = [];
+        foreach ($worlds as $world) {
+            $val[] = $world['id'];
+            $val[] = $world['randomNumber'];
+            //$update->bindParam(++$i, $world['id'], PDO::PARAM_INT);
+        }
+
+        self::$update[$rows]->execute($val);
+    }
+}

+ 2 - 1
frameworks/PHP/workerman/workerman-pgsql.dockerfile

@@ -17,7 +17,8 @@ COPY php.ini /etc/php/8.1/cli/php.ini
 ADD ./ /workerman
 ADD ./ /workerman
 WORKDIR /workerman
 WORKDIR /workerman
 
 
-RUN sed -i "s|'mysql:host|'pgsql:host|g" app.php
+RUN sed -i "s|'/app.php|'/app-pg.php|g" server.php
+RUN sed -i "s|init()|DbRaw::init()|g" server.php
 
 
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet
 
 

+ 2 - 1
frameworks/PHP/workerman/workerman-php8-jit.dockerfile

@@ -17,7 +17,8 @@ COPY php-jit.ini /etc/php/8.1/cli/php.ini
 ADD ./ /workerman
 ADD ./ /workerman
 WORKDIR /workerman
 WORKDIR /workerman
 
 
-RUN sed -i "s|'mysql:host|'pgsql:host|g" app.php
+RUN sed -i "s|'/app.php|'/app-pg.php|g" server.php
+RUN sed -i "s|init()|DbRaw::init()|g" server.php
 
 
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet