昨日、記事やGistから過去に書いたサンプル・コードを探すアプリケーションを作成したのですが、どうも使いにくいです。Gistに対象を絞って検索するページを作成してみました。
public gistであればgistが提供している検索を使えるのですが、今までprivate gistとして作成していたのと、private gistはpublic gistに変更できない(作り直し)ので仕方がありません。
作成したアプリの画面です。
https://apex.oracle.com/pls/apex/r/japancommunity/codesearch/code
少しだけ実装の解説をします。
ファセット検索は、クラシック・レポートを検索結果のリージョンとして使用している、一般的な実装です。クラシック・レポートのソースは以下です。
select
a.id
,d.title
,d.url
,a.raw_url
,a.raw_content
,a.file_name
,a.file_ext
,a.embedded_url
from cds_documents d join cds_attachments a
on d.id = a.post_id
ファイルタイプの選択であるファセットF6_FILE_EXTは、列FILE_EXTの個別値をチェックボックスで選択するように構成しています。
検索ボックスのP6_SEARCHは、検索のソースを列RAW_CONTENT(これは実際のコード)に限定しています。
検索されたコードを表示するリージョンはList Gist Snippetsとして作成しました。
タイプは動的コンテンツです。ソースは以下のPL/SQLコードです。
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_result clob; | |
begin | |
for r in ( | |
select | |
id | |
,title | |
,url | |
,embedded_url | |
from table(get_gist_faceted_search_data(:APP_PAGE_ID, 'searchresults')) | |
fetch first 10 rows only | |
) | |
loop | |
l_result := l_result || | |
'<b>ブログ記事:</b><a href="' || r.url || '" target="_codeview">' || r.title || '</a><br>'; | |
l_result := l_result || | |
'<script src="' || r.embedded_url || '"></script>'; | |
end loop; | |
return l_result; | |
end; |
ブログ記事に埋め込んでいるGist由来のスクリプトをscriptタグとで出力しています。
動的コンテンツからクラシック・レポートの検索結果を取得するために、パイプライン表関数get_gist_faceted_search_dataを作成しています。
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
CREATE OR REPLACE EDITIONABLE TYPE "T_GIST_ROW" as object( | |
id number | |
,title varchar2(4000) | |
,url varchar2(400) | |
,embedded_url varchar2(400) | |
) | |
/ | |
CREATE OR REPLACE EDITIONABLE TYPE "T_GIST_TABLE" as table of t_gist_row | |
/ | |
create or replace function get_gist_faceted_search_data( | |
p_page_id in number, | |
p_region_static_id in varchar2 ) | |
return t_gist_table pipelined | |
is | |
l_region_id number; | |
l_context apex_exec.t_context; | |
type t_col_index is table of pls_integer index by varchar2(255); | |
l_col_index t_col_index; | |
--------------------------------------------------------------------------- | |
procedure get_column_indexes( p_columns wwv_flow_t_varchar2 ) is | |
begin | |
for i in 1 .. p_columns.count loop | |
l_col_index( p_columns( i ) ) := apex_exec.get_column_position( | |
p_context => l_context, | |
p_column_name => p_columns( i ) ); | |
end loop; | |
end get_column_indexes; | |
begin | |
-- 1. get the region ID of the Faceted Search region | |
select region_id | |
into l_region_id | |
from apex_application_page_regions | |
where application_id = v('APP_ID') | |
and page_id = p_page_id | |
and static_id = p_region_static_id; | |
-- 2. Get a cursor (apex_exec.t_context) for the current region data | |
l_context := apex_region.open_query_context( | |
p_page_id => p_page_id, | |
p_region_id => l_region_id ); | |
get_column_indexes( wwv_flow_t_varchar2( 'ID', 'TITLE', 'URL', 'EMBEDDED_URL' ) ); | |
while apex_exec.next_row( p_context => l_context ) loop | |
pipe row( t_gist_row( | |
apex_exec.get_varchar2( p_context => l_context, p_column_idx => l_col_index( 'ID' ) ), | |
apex_exec.get_varchar2( p_context => l_context, p_column_idx => l_col_index( 'TITLE' ) ), | |
apex_exec.get_varchar2( p_context => l_context, p_column_idx => l_col_index( 'URL' ) ), | |
apex_exec.get_varchar2( p_context => l_context, p_column_idx => l_col_index( 'EMBEDDED_URL' ) ) | |
) ); | |
end loop; | |
apex_exec.close( l_context ); | |
return; | |
exception | |
when no_data_needed then | |
apex_exec.close( l_context ); | |
return; | |
when others then | |
apex_exec.close( l_context ); | |
raise; | |
end get_gist_faceted_search_data; | |
/ |
一般的にはファセットが変更されたときは、リージョンをリフレッシュします。今回は<script src="..."></script>を動的コンテンツで出力しています。Gist由来のコード中でDocument.writeが使われているため、リフレッシュでの画面更新時は出力が無視されます。
そのため、ファセット変更(Facet Change)で実行されるTRUEアクションとして、ページの送信を指定しています。
以上が、今回作成したアプリケーションの説明です。
自分のために作成したアプリですが、何かの役に立てば幸いです。
完