- split off files from tutorial.txt into lib/*.php
[m6w6/ext-http] / lib / PgLobStream.php
diff --git a/lib/PgLobStream.php b/lib/PgLobStream.php
new file mode 100644 (file)
index 0000000..b6927bf
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * PostgreSQL LOB stream
+ * $Id$
+ * 
+ * Usage:
+ * <code>
+ * // GET /image.php?image=1234
+ * if (PgLobStream::$loId = (int) $_GET['image']) {
+ *     if ($lob = fopen('pglob: dbname=database user=mike', 'r')) {
+ *         HttpResponse::setContentType('image/jpeg');
+ *         HttpResponse::setStream($lob);
+ *         HttpResponse::send();
+ *     }
+ * }
+ * </code>
+ * 
+ * @copyright   Michael Wallner, <mike@iworks.at>
+ * @license     BSD, revised
+ * @package     pecl/http
+ * @version     $Revision$
+ */
+class PgLobStream
+{
+    private $dbh;
+    private $loh;
+    private $lon;
+    private $size = 0;
+    
+    public static $loId;
+
+    function stream_open($path, $mode)
+    {
+        $path = trim(parse_url($path, URL_PATH));
+        
+        if ($path) {
+            if ($this->dbh = pg_connect($path)) {
+                if (pg_query($this->dbh, 'BEGIN')) {
+                    if (is_resource($this->loh = pg_lo_open($this->dbh, $this->lon = self::$loId, $mode))) {
+                        pg_lo_seek($this->loh, 0, PGSQL_SEEK_END);
+                        $this->size = (int) pg_lo_tell($this->loh);
+                        pg_lo_seek($this->loh, 0, PGSSQL_SEEK_SET);
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+    
+    function stream_read($length)
+    {
+        return pg_lo_read($this->loh, $length);
+    }
+    
+    function stream_seek($offset, $whence = SEEK_SET)
+    {
+        return pg_lo_seek($this->loh, $offset, $whence);
+    }
+    
+    function stream_tell()
+    {
+        return pg_lo_tell($this->loh);
+    }
+    
+    function stream_eof()
+    {
+        return pg_lo_tell($this->loh) >= $this->size;
+    }
+    
+    function stream_flush()
+    {
+        return true;
+    }
+    
+    function stream_stat()
+    {
+        return array('size' => $this->size, 'ino' => $this->lon);
+    }
+    
+    function stream_write($data)
+    {
+        return pg_lo_write($this->loh, $data);
+    }
+    
+    function stream_close()
+    {
+        if (pg_lo_close($this->loh)) {
+            return pg_query($this->dbh, 'COMMIT');
+        } else {
+            pg_query($this->dbh, 'ROLLBACK');
+            return false;
+        }
+    }
+}
+
+stream_register_wrapper('pglob', 'PgLobStream');
+
+?>