これからオブジェクトの操作を実装していきます。バケットの実装と同様にパイプライン表関数の実装、レポートとフォームの作成、フォームを処理するプロセスの記述を行います。
バケット内のオブジェクトの一覧を取得するパイプライン表関数list_objectsを定義します。コードは以下になります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop type t_object_tbl; | |
drop type t_object_row; | |
create or replace type t_object_row as object | |
( | |
id varchar2(4000) | |
, name varchar2(4000) | |
, l_size number | |
, md5 varchar2(4000) | |
, time_created timestamp(6) with time zone | |
, etag varchar2(4000) | |
, time_modified timestamp(6) with time zone | |
) | |
/ | |
create or replace type t_object_tbl as table of t_object_row | |
/ | |
/* | |
* ネームスペース、バケット、リージョンを指定して、そこに含まれるオブジェクトの一覧を取得する。 | |
*/ | |
create or replace function list_objects | |
( | |
p_namespace_name in varchar2 | |
, p_bucket_name in varchar2 | |
, p_region in varchar2 | |
, p_credential_name in varchar2 | |
) | |
return t_object_tbl pipelined | |
as | |
response dbms_cloud_oci_obs_object_storage_list_objects_response_t; | |
object dbms_cloud_oci_object_storage_object_summary_t; | |
l_object t_object_row; | |
plsql_sdk_error exception; | |
begin | |
response := dbms_cloud_oci_obs_object_storage.list_objects( | |
namespace_name => p_namespace_name | |
, bucket_name => p_bucket_name | |
, region => p_region | |
, credential_name => p_credential_name | |
); | |
if response.status_code != 200 then | |
raise plsql_sdk_error; | |
end if; | |
for i in 1 .. response.response_body.objects.count | |
loop | |
object := response.response_body.objects(i); | |
l_object := t_object_row( | |
object.name -- nameが一意なのでnameをidとする | |
, object.name | |
, object.l_size | |
, object.md5 | |
, object.time_created | |
, object.etag | |
, object.time_modified | |
); | |
pipe row(l_object); | |
end loop; | |
end; | |
/ |
これをSQLワークショップのSQLスクリプトに登録し、実行します。実行手順はバケットを一覧するファンクションlist_bucketsで行ったものと同じです。
list_bucketsと同様に初回実行時は先頭の2行はエラーになります。残りの3行成功していれば、ファンクションlist_objectsが作成できています。
続いて、作成したパイプライン表関数を使ったレポートとフォームのページを作成します。作成しているアプリケーションを開き、ページの作成を実行します。
対話モード・レポートを選択します。
ページ定義の名前はオブジェクト一覧とします。フォーム・ページを含めるをONに変更し、フォーム・ページ名はオブジェクト操作とします。フォーム・ページ・モードとしてモーダル・ダイアログを選択します。
データ・ソースのソース・タイプにSQL問合せを選択し、以下のSELECT文を記述します。
select * from list_objects
(
p_namespace_name => :G_NAMESPACE_NAME
, p_bucket_name => :P4_BUCKET_NAME
, p_region => :G_REGION
, p_credential_name => :G_CREDENTIAL_NAME
)
P4_BUCKET_NAMEはページを作成した後、ページ・アイテムとして作成します。
ナビゲーションのブレッドクラムの使用、ナビゲーションの使用はともにONにします。
以上を設定し、次へ進みます。
主キー列1としてID (Varchar2)を選択し、ページの作成を実行します。
ページが作成された後、対話モード・レポートのリージョンにページ・アイテムを作成します。
ページ・アイテムP4_BUCKET_NAMEを作成します。ページ・アイテムの作成を実行し、作成されたページ・アイテムの識別の名前をP4_BUCKET_NAME、タイプを表示のみ、ラベルはBucket Nameとします。
バケット名はバケット一覧から引き継ぎます。バケット一覧を表示するレポートに、オブジェクト一覧をレポートするページへのリンクを作成します。
バケット一覧のページをページ・デザイナで開きます。
列NAMEのタイプをプレーン・テキストからリンクへ変更し、ターゲットを設定します。リンク・テキストは#NAME#とします。
リンクのターゲットとして、オブジェクト一覧のページを指定します。ターゲットのタイプはこのアプリケーションのページ、ページは4です。アイテムの設定として、ページ・アイテムのP4_BUCKET_NAMEは列NAME、P4_NAMESPACEには列NAMESPACEの値が渡されるよう設定します。OKをクリックします。
以上でオブジェクトの一覧を表示する設定が完了したので、バケット一覧のページを実行して指定したバケットに含まれるオブジェクトの一覧をリストしてみます。
バケット一覧のページの列Nameがリンクに変わっています。これをクリックします。
選択したバケットに含まれるオブジェクトの一覧画面に遷移します。登録されたオブジェクトが存在しないと、データが見つかりません。と表示されますが、オブジェクトの一覧画面はこれで完成しています。
続いてオブジェクト操作の画面を変更し、オブジェクトの作成/更新/
削除ができるようにします。
ページ・デザイナにてオブジェクト操作のページを開き、オブジェクトの操作に必要なページ・アイテムを2つ作成します。
最初に、バケット名を保持するページ・アイテムP5_BUCKET_NAMEを作成します。アイテムの作成を実行し、識別の名前をP5_BUCKET_NAMEとし、タイプは非表示にします。
次に、オブジェクト・ストレージにアップロードするファイルを指定するページ・アイテムP5_FILEを作成します。識別の名前をP5_FILEとし、タイプにファイル参照...を選択します。ラベルはFilename、それ以外はデフォルトですが、特に記憶域タイプについては、Table APEX_APPLICATION_TEMP_FILESであることを確認します。アップロードされたファイルは、こちらの表より取得します。
必要なページ・アイテムが登録されたので、プロセスを変更します。
左ペインよりプロセス・ビューを開き、プロセス・フォームオブジェクトの操作を選択します。設定のターゲット・タイプをPL/SQL Codeに変更し、挿入/更新/削除するPL/SQLコードに以下を記述します。失われた更新の防止はOFF、行のロックはNoにします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_rename_object_details dbms_cloud_oci_object_storage_rename_object_details_t; | |
l_put_response dbms_cloud_oci_obs_object_storage_put_object_response_t; | |
l_rename_response dbms_cloud_oci_obs_object_storage_rename_object_response_t; | |
l_delete_response dbms_cloud_oci_obs_object_storage_delete_object_response_t; | |
l_status_code integer; | |
l_filename varchar2(4000); | |
l_content_type varchar2(4000); | |
l_blob blob; | |
l_loc number; | |
plsql_sdk_error exception; | |
-- 日本語に対応させる | |
function cs_workaround(str varchar2) | |
return varchar2 | |
as | |
begin | |
return utl_url.escape(str, false, 'AL32UTF8'); | |
end cs_workaround; | |
begin | |
case | |
when :APEX$ROW_STATUS = 'C' then | |
begin | |
select filename, mime_type, blob_content into l_filename, l_content_type, l_blob | |
from apex_application_temp_files | |
where name = :P5_FILE; | |
exception | |
when no_data_found then | |
l_blob := null; | |
end; | |
if lengthb(:P5_NAME) > 0 then | |
l_filename := :P5_NAME; | |
end if; | |
l_filename := cs_workaround(l_filename); | |
l_put_response := dbms_cloud_oci_obs_object_storage.put_object | |
( | |
namespace_name => :G_NAMESPACE_NAME | |
, bucket_name => :P5_BUCKET_NAME | |
, object_name => l_filename | |
, content_type => l_content_type | |
, put_object_body => l_blob | |
, region => :G_REGION | |
, credential_name => :G_CREDENTIAL_NAME | |
); | |
l_status_code := l_put_response.status_code; | |
when :APEX$ROW_STATUS = 'U' then | |
l_rename_object_details := new | |
dbms_cloud_oci_object_storage_rename_object_details_t; | |
l_rename_object_details.source_name := :P5_ID; | |
l_rename_object_details.new_name := :P5_NAME; | |
l_rename_response := dbms_cloud_oci_obs_object_storage.rename_object | |
( | |
namespace_name => :G_NAMESPACE_NAME | |
, bucket_name => :P5_BUCKET_NAME | |
, rename_object_details => l_rename_object_details | |
, region => :G_REGION | |
, credential_name => :G_CREDENTIAL_NAME | |
); | |
l_status_code := l_put_response.status_code; | |
when :APEX$ROW_STATUS = 'D' then | |
l_delete_response := dbms_cloud_oci_obs_object_storage.delete_object | |
( | |
namespace_name => :G_NAMESPACE_NAME | |
,bucket_name => :P5_BUCKET_NAME | |
,object_name => cs_workaround(:P5_NAME) | |
, region => :G_REGION | |
, credential_name => :G_CREDENTIAL_NAME | |
); | |
l_status_code := l_put_response.status_code; | |
end case; | |
if l_status_code != 200 then | |
raise plsql_sdk_error; | |
end if; | |
end; |
作成のときは、ビューAPEX_APPLICATION_TEMP_FILESよりアップロードされたファイルをBLOBとして取り出し、そのBLOBをオブジェクト・ストレージに登録しています。オブジェクト名の入力がなければ、ファイル名をオブジェクト名にしています。オブジェクト名に日本語が含まれている場合に対応するため、ファイル名のエンコードをUTL_URL.ESCAPEファンクションで実施しています。更新では、オブジェクト名の変更のみが可能です。オブジェクトの削除も実装しています。
ページ・デザイナでオブジェクト一覧のページを開きます。
ボタンCREATEのクリックの際に、バケット名がフォームに渡されるようにターゲットの設定を変更します。
アイテムの設定に、名前をP5_BUCKET_NAME、値を&P4_BUCKET_NAME.とした行を追加します。
OKをクリックし、保存します。
これでファイルをオブジェクト・ストレージにアップロードする部分の実装はできました。ページを実行して、ファイルをアップロードしてみます。
ファイルを選択し、作成をクリックします。
ファイルがアップロードされたことが確認できます。
OKをクリックします。
以上で削除と変更の適用も実装ができました。
先程アップロードしたファイルを削除してみます。
この削除処理を実行しますか。と表示されるのでOKをクリックします。
オブジェクトが削除されたことが確認できます。
これからオブジェクトのダウンロードを実装するので、ファイルをひとつアップロードしておきましょう。
続く