mod_plsqlを使用したWebアプリケーションにおけるファイルアップロード

mod_plsqlにおけるアップロードの処理概要

mod_plsqlを使った環境におけるファイルアップロードでは、dads.confの「PlsqlDocumentTablename」ディレクティブに指定した表(形式が決められている)にアップロードされたファイルの内容がBLOBとして格納される。FORMのACTIONに指定されたプロシージャに渡されるのは、「PlsqlDocumentTablename」に格納した時に生成される行のname列の値であり、ファイル本体ではない。
「PlsqlDocumentTablename UPLOADED_FILES」を使用した場合の概要は以下の様な感じだ。ダウンロードは前回作成したDOWNLOAD_BLOBプロシージャとの連携を想定。

アップロード用の表作成

「PlsqlDocumentTablename UPLOADED_FILES」を指定するために、UPLOADED_FILES表を以下の通り作成する。

CREATE TABLE UPLOADED_FILES (
    name          VARCHAR2(256) unique not null,
    mime_type     VARCHAR2(128),
    doc_size      NUMBER,
    dad_charset   VARCHAR2(128),
    last_updated  DATE,
    content_type  VARCHAR2(128),
    blob_content  BLOB
)
LOB (blob_content) STORE AS BASICFILE;

dads.confは以下の様になる。

<Location /management>
    SetHandler pls_handler
    Order allow,deny
    Allow from All
    PlsqlDatabaseUsername MANAGEMENTUSER
    PlsqlDatabasePassword password
    PlsqlDatabaseConnectString MANAGEMENTDB
    PlsqlDefaultPage TOP
    PlsqlDocumentTablename UPLOADED_FILES
    PlsqlNLSLanguage Japanese_Japan.AL32UTF8
</Location>

ファイルアップロード後に呼び出されるUPLOADプロシージャを作成

ファイルアップロード用の画面表示、およびアップロード後の画面表示を行うUPLOADプロシージャを作成する。
UPLOADED_FILES表はやはり一時的なアップロード領域とみるべきだろう。よって、BLOB_REPOSITORYにBLOBをコピーし、UPLOADED_FILES表からは削除している。

CREATE OR REPLACE
PROCEDURE UPLOAD( name VARCHAR2 := NULL, file VARCHAR2 := NULL ) AS
    localname VARCHAR2(256);
BEGIN
    HTP.p('
    <html>
    <head>
    <title>UPLOAD</title>
    </head>
    <body>');

    IF file IS NOT NULL THEN
        localname := name;
        INSERT INTO BLOB_REPOSITORY SELECT localname, mime_type, blob_content FROM UPLOADED_FILES WHERE name = file;
        DELETE FROM UPLOADED_FILES WHERE name = file;
        COMMIT;

        HTP.p('<div style="border: solid 2px gold; background-color: beige;">UPLOADED! '||name||'</div>');
    END IF;

    HTP.p('
        <form action="UPLOAD" enctype="multipart/form-data" method="POST">
        <p>File name: <input type="text" name="name"></p>
        <p>File to upload: <input type="file" name="file"></p>
        <p><input type="submit" value="start upload"></p>
        </form>');

    HTP.p('
        <div>Uploaded files</div>
        <ul>');
    FOR r IN (SELECT * FROM BLOB_REPOSITORY)
    LOOP
        HTP.p('<li><a href="DOWNLOAD_BLOB?filename='||r.name||'">'||r.name||'</a></li>');
    END LOOP;
    HTP.p('
        </ul>');

    HTP.p('
    </body>
    </html>');
END;

動作確認

UPLOADページにアクセス

ファイルアップロード用のフォームを表示。BLOB_REPOSITORYの中にあるファイルについてはDOWNLOAD_BLOBを使用してダウンロードできるように一覧を表示。

ファイルアップロード後の画面

UPLOADED! 表示をしてアップロード完了を通知。一覧に「louvre.jpg」が追加される。

DOWNLOAD_BLOB確認

一覧から「louvre.jpg」を表示。