Index: openacs-4/packages/intermedia-driver/intermedia-driver.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/intermedia-driver.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/intermedia-driver.info 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,25 @@ + + + + + Intermedia Driver + Intermedia Driver + f + t + + + David Bauer + Dirk Gomez + Search package callback implementation for Oracle Intermedia. + Implemented the search package callback interface for search engine driver using Oracle Intermedia. + + + + + + + + + + + Index: openacs-4/packages/intermedia-driver/sql/oracle/load-site-wide-search =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/load-site-wide-search,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/load-site-wide-search 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,52 @@ +# +# Copyright (C) 2005 MIT +# +# This file is part of dotLRN. +# +# dotLRN is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# + +# +# This is the script to create the site-wide-search package for .LRN +# +# @author openacs@dirkgomez.de +# @version $Id: load-site-wide-search,v 1.1 2006/01/27 16:03:57 daveb Exp $ +# @creation-date 13-May-2005 +# +# Ported from ACES. +# +# prerequisites: + +# Oracle 8.1.7.4 (I have not tried .LRN search with Oracle 9i, but +# it'll probably work, it won't work with Oracle 10g.) +# Also consider this Oracle bug.: +# http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=261880.1 + +# Call with load-site-wide-search dbuser passwd ctxsyspasswd. + +USERNAME=$1 +PASSWORD=$2 +CTXSYS_PASSWORD=$3 + +# For programming convenience just drop everything +sqlplus ${USERNAME}/${PASSWORD} @search-tables-drop.sql +sqlplus ${USERNAME}/${PASSWORD} @search-packages-drop.sql +sqlplus ${USERNAME}/${PASSWORD} @search-sc-drop.sql +sqlplus ${USERNAME}/${PASSWORD} @search-index-drop.sql ${USERNAME} ${PASSWORD} + +sqlplus ${USERNAME}/${PASSWORD} @search-tables-create.sql +sqlplus ${USERNAME}/${PASSWORD} @search-packages-create.sql +sqlplus ${USERNAME}/${PASSWORD} @search-sc-create.sql +sqlplus ${USERNAME}/${PASSWORD} @syndication-create.sql + +sqlplus ctxsys/${CTXSYS_PASSWORD} @search-ctxsys.sql ${USERNAME} ${PASSWORD} +sqlplus ${USERNAME}/${PASSWORD} @search-index-create.sql ${USERNAME} ${PASSWORD} +sqlplus ${USERNAME}/${PASSWORD} @search-from-scratch.sql Index: openacs-4/packages/intermedia-driver/sql/oracle/search-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,3 @@ +@@ search-tables-create.sql +@@ search-packages-create.sql +@@ search-sc-create.sql Index: openacs-4/packages/intermedia-driver/sql/oracle/search-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,3 @@ +@@ search-sc-drop.sql +@@ search-packages-drop.sql +@@ search-tables-drop.sql Index: openacs-4/packages/intermedia-driver/sql/oracle/search-from-scratch.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-from-scratch.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-from-scratch.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,62 @@ +-- +-- Copyright (C) 2005 MIT +-- +-- This file is part of dotLRN. +-- +-- dotLRN is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 2 of the License, or (at your option) any later +-- version. +-- +-- dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- + +-- +-- Populate .LRN's intermedia index +-- +-- @author Dirk Gomez +-- @version $Id: search-from-scratch.sql,v 1.1 2006/01/27 16:03:57 daveb Exp $ +-- @creation-date 13-May-2005 +-- + +truncate table search_observer_queue; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('cal_item') ; +commit; + + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects, cr_items where object_id=live_revision and object_type in ('file_storage_object') ; +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('static_portal_content'); +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('forums_message') ; +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('forums_forums') ; +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects, cr_items where object_id=live_revision and object_type in ('news'); +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('faq') ; +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects where object_type in ('survey'); +commit; + +insert into search_observer_queue (object_id, event) select object_id, 'INSERT' from acs_objects,cr_items where object_type in ('phb_person') and object_id=live_revision ; +commit; + + +--alter index swi_index rebuild parameters ('sync') ; + + +exit; + + + Index: openacs-4/packages/intermedia-driver/sql/oracle/search-index-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-index-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-index-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,52 @@ +-- +-- Copyright (C) 2005 MIT +-- +-- This file is part of dotLRN. +-- +-- dotLRN is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 2 of the License, or (at your option) any later +-- version. +-- +-- dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- + +-- +-- Create the intermedia index for .LRN site-wide search +-- +-- @author openacs@dirkgomez.de +-- @version $Id: search-index-create.sql,v 1.1 2006/01/27 16:03:57 daveb Exp $ +-- @creation-date 13-May-2005 +-- +-- Partly ported from ACES. + +-- create section groups for within clauses +begin + ctx_ddl.create_section_group('swsgroup', 'basic_section_group'); + ctx_ddl.add_field_section('swsgroup', 'oneline', 'oneline', TRUE); +end; +/ create index swi_index on site_wide_index (indexed_content) +indextype is ctxsys.context parameters ('datastore ctxsys.default_datastore memory 250M'); + + +-- create intermedia index for site wide index +begin + ctx_ddl.create_preference('sws_user_datastore', 'user_datastore'); + ctx_ddl.set_attribute('sws_user_datastore', 'procedure', 'sws_user_proc_&1'); +end; +/ + +--create index swi_ctx_index on site_wide_index (datastore) +--indextype is ctxsys.context parameters ('datastore sws_user_datastore memory 250M section group swsgroup'); + + +--create index swi_ctx_index on site_wide_index (datastore) +--indextype is ctxsys.context parameters ('datastore ctxsys.default_datastore memory 250M'); + +create index swi_index on site_wide_index (indexed_content) +indextype is ctxsys.context parameters ('datastore ctxsys.default_datastore memory 250M'); + +exit; \ No newline at end of file Index: openacs-4/packages/intermedia-driver/sql/oracle/search-index-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-index-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-index-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,32 @@ +-- +-- Copyright (C) 2005 MIT +-- +-- This file is part of dotLRN. +-- +-- dotLRN is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 2 of the License, or (at your option) any later +-- version. +-- +-- dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- + +-- +-- Drop the intermedia index for .LRN site-wide search +-- +-- @author Dirk Gomez +-- @version $Id: search-index-drop.sql,v 1.1 2006/01/27 16:03:57 daveb Exp $ +-- @creation-date 13-May-2005 + +begin + ctx_ddl.drop_section_group('swsgroup'); + ctx_ddl.drop_preference('sws_user_datastore'); +end; +/ + +drop index swi_ctx_index; + +exit; Index: openacs-4/packages/intermedia-driver/sql/oracle/search-packages-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-packages-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-packages-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,487 @@ +-- +-- Copyright (C) 2005 MIT +-- +-- This file is part of dotLRN. +-- +-- dotLRN is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 2 of the License, or (at your option) any later +-- version. +-- +-- dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- + +-- +-- Create database packages for .LRN site-wide search +-- +-- @author Dirk Gomez +-- @version $Id: search-packages-create.sql,v 1.1 2006/01/27 16:03:57 daveb Exp $ +-- @creation-date 13-May-2005 + +-- Partly ported from ACES. + +-- The site_wide_search packages holds generally useful +-- PL/SQL procedures and functions. + +create or replace package search_observer +as + procedure enqueue ( + object_id acs_objects.object_id%TYPE, + event search_observer_queue.event%TYPE +); + procedure dequeue ( + object_id acs_objects.object_id%TYPE, event + search_observer_queue.event%TYPE, event_date + search_observer_queue.event_date%TYPE +); +end search_observer; +/ +show errors + +create or replace package body search_observer +as + procedure enqueue ( + object_id acs_objects.object_id%TYPE, + event search_observer_queue.event%TYPE +) is +begin + insert into search_observer_queue ( + object_id, + event + ) values ( + enqueue.object_id, + enqueue.event + ); + + end enqueue; + + procedure dequeue ( + object_id acs_objects.object_id%TYPE, + event search_observer_queue.event%TYPE, + event_date search_observer_queue.event_date%TYPE +) is + begin + + + delete from search_observer_queue + where object_id = dequeue.object_id + and event = dequeue.event + and to_char(dequeue.event_date,'yyyy-mm-dd hh24:mi:ss') = to_char(dequeue.event_date,'yyyy-mm-dd hh24:mi:ss'); + + end dequeue; +end search_observer; +/ +show errors + + +create or replace package site_wide_search +as + procedure register_event (p_object_id search_observer_queue.object_id%TYPE, + p_event search_observer_queue.event%TYPE); + + procedure logger (p_logmessage varchar); + + function im_convert( + query in varchar2 default null + ) return varchar2; + +end site_wide_search; +/ +show errors + +create or replace package body site_wide_search +as + procedure register_event (p_object_id search_observer_queue.object_id%TYPE, + p_event search_observer_queue.event%TYPE) is + begin + insert into search_observer_queue + (object_id, event) + values + (p_object_id, p_event); + end register_event; + + procedure logger (p_logmessage varchar) is + begin + insert into sws_log_messages (logmessage) values (p_logmessage); + end logger; + + -- Query to take free text user entered query and frob it into something + -- that will make interMedia happy. Provided by Oracle. + function im_convert( + query in varchar2 default null + ) return varchar2 + is + i number :=0; + len number :=0; + char varchar2(1); + minusString varchar2(256); + plusString varchar2(256); + mainString varchar2(256); + mainAboutString varchar2(500); + finalString varchar2(500); + hasMain number :=0; + hasPlus number :=0; + hasMinus number :=0; + token varchar2(256); + tokenStart number :=1; + tokenFinish number :=0; + inPhrase number :=0; + inPlus number :=0; + inWord number :=0; + inMinus number :=0; + completePhrase number :=0; + completeWord number :=0; + code number :=0; + begin + + len := length(query); + + -- we iterate over the string to find special web operators + for i in 1..len loop + char := substr(query,i,1); + if(char = '"') then + if(inPhrase = 0) then + inPhrase := 1; + tokenStart := i; + else + inPhrase := 0; + completePhrase := 1; + tokenFinish := i-1; + end if; + elsif(char = ' ') then + if(inPhrase = 0) then + completeWord := 1; + tokenFinish := i-1; + end if; + elsif(char = '+') then + inPlus := 1; + tokenStart := i+1; + elsif((char = '-') and (i = tokenStart)) then + inMinus :=1; + tokenStart := i+1; + end if; + + if(completeWord=1) then + token := '{ '||substr(query,tokenStart,tokenFinish-tokenStart+1)||' }'; + if(inPlus=1) then + plusString := plusString||','||token||'*10'; + hasPlus :=1; + elsif(inMinus=1) then + minusString := minusString||'OR '||token||' '; + hasMinus :=1; + else + mainString := mainString||' NEAR '||token; + mainAboutString := mainAboutString||' '||token; + hasMain :=1; + end if; + tokenStart :=i+1; + tokenFinish :=0; + inPlus := 0; + inMinus :=0; + end if; + completePhrase := 0; + completeWord :=0; + end loop; + + -- find the last token + token := '{ '||substr(query,tokenStart,len-tokenStart+1)||' }'; + if(inPlus=1) then + plusString := plusString||','||token||'*10'; + hasPlus :=1; + elsif(inMinus=1) then + minusString := minusString||'OR '||token||' '; + hasMinus :=1; + else + mainString := mainString||' NEAR '||token; + mainAboutString := mainAboutString||' '||token; + hasMain :=1; + end if; + + + mainString := substr(mainString,6,length(mainString)-5); + mainAboutString := replace(mainAboutString,'{',' '); + mainAboutString := replace(mainAboutString,'}',' '); + mainAboutString := replace(mainAboutString,')',' '); + mainAboutString := replace(mainAboutString,'(',' '); + plusString := substr(plusString,2,length(plusString)-1); + minusString := substr(minusString,4,length(minusString)-4); + + -- we find the components present and then process them based on the specific combinations + code := hasMain*4+hasPlus*2+hasMinus; + if(code = 7) then + finalString := '('||plusString||','||mainString||'*2.0,about('||mainAboutString||')*0.5) NOT ('||minusString||')'; + elsif (code = 6) then + finalString := plusString||','||mainString||'*2.0'||',about('||mainAboutString||')*0.5'; + elsif (code = 5) then + finalString := '('||mainString||',about('||mainAboutString||')) NOT ('||minusString||')'; + elsif (code = 4) then + finalString := mainString; + finalString := replace(finalString,'*1,',NULL); + finalString := '('||finalString||')*2.0,about('||mainAboutString||')'; + elsif (code = 3) then + finalString := '('||plusString||') NOT ('||minusString||')'; + elsif (code = 2) then + finalString := plusString; + elsif (code = 1) then + -- not is a binary operator for intermedia text + finalString := 'totallyImpossibleString'||' NOT ('||minusString||')'; + elsif (code = 0) then + finalString := ''; + end if; + + return finalString; + end; + +end site_wide_search; +/ +show errors + +-------------------------------------------------------- +-- Forum triggers and procedures + +create or replace trigger forums_messages_sws_insert_tr + after insert on forums_messages for each row +begin + site_wide_search.register_event (:new.message_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger forums_messages_sws_update_tr + after update on forums_messages for each row +begin + site_wide_search.register_event (:new.message_id, 'UPDATE'); +end; +/ +show errors + +create or replace trigger forums_messages_sws_delete_tr + after delete on forums_messages for each row +begin + site_wide_search.register_event (:new.message_id, 'DELETE'); +end; +/ +show errors + + +-------------------------------------------------------- +-- static-portal triggers and procedures + +create or replace trigger static_portal_sws_insert_tr + after insert on static_portal_content for each row +begin + site_wide_search.register_event (:new.content_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger static_portal_sws_update_tr + after update on static_portal_content for each row +begin + site_wide_search.register_event (:new.content_id, 'UPDATE'); +end; +/ +show errors + +create or replace trigger static_portal_sws_delete_tr + after delete on static_portal_content for each row +begin + site_wide_search.register_event (:new.content_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- ACS-events triggers and procedures +-- I think only calendar makes use of the acs-events tables. + +create or replace trigger acs_events_sws_insert_tr + after insert on acs_events for each row +begin + site_wide_search.register_event (:new.event_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger acs_events_sws_update_tr + after update on acs_events for each row +begin + site_wide_search.register_event (:new.event_id, 'UPDATE'); +end; +/ +show errors + +create or replace trigger acs_events_sws_delete_tr + after delete on acs_events for each row +begin + site_wide_search.register_event (:new.event_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- FAQ triggers and procedures + +create or replace trigger faq_q_and_as_sws_insert_tr + after insert on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.entry_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger faq_q_and_as_sws_update_tr + after update on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.entry_id, 'UPDATE'); +end; +/ +show errors + +create or replace trigger faq_q_and_as_sws_delete_tr + after delete on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.entry_id, 'DELETE'); +end; +/ +show errors + + +-------------------------------------------------------- +-- Survey Procs + +create or replace trigger surveys_sws_insert_tr + after insert on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger surveys_sws_update_tr + after update on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'UPDATE'); +end; +/ +show errors + + +create or replace trigger surveys_sws_delete_tr + after delete on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- Photobook Procs + +create or replace trigger phb_person_sws_insert_tr + after insert on phb_person for each row +begin + site_wide_search.register_event (:new.person_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger phb_person_sws_update_tr + after update on phb_person for each row +begin + site_wide_search.register_event (:new.person_id, 'UPDATE'); +end; +/ +show errors + + +create or replace trigger phb_person_sws_delete_tr + after delete on phb_person for each row +begin + site_wide_search.register_event (:new.person_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- FAQ Procs + +create or replace trigger faq_q_and_as_sws_insert_tr + after insert on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.faq_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger faq_q_and_as_sws_update_tr + after update on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.faq_id, 'UPDATE'); +end; +/ +show errors + + +create or replace trigger faq_q_and_as_sws_delete_tr + after delete on faq_q_and_as for each row +begin + site_wide_search.register_event (:new.faq_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- Survey Procs + +create or replace trigger surveys_sws_insert_tr + after insert on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'INSERT'); +end; +/ +show errors + +create or replace trigger surveys_sws_update_tr + after update on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'UPDATE'); +end; +/ +show errors + + +create or replace trigger surveys_sws_delete_tr + after delete on surveys for each row +begin + site_wide_search.register_event (:new.survey_id, 'DELETE'); +end; +/ +show errors + +-------------------------------------------------------- +-- The user_datastore proc which is called on every change of the datastore. + +create or replace procedure sws_user_datastore_proc ( p_rid in rowid, p_tlob in out nocopy clob ) +is + v_object_id site_wide_index.object_id%type; +begin + site_wide_search.logger ('entered sws_user_datastore_proc'); + + select indexed_content + into p_tlob + from site_wide_index swi, acs_objects ao + where swi.object_id = ao.object_id + and p_rid = swi.rowid; + + site_wide_search.logger ('in sws_user_datastore_proc with type ' || v_object_id); + +end; +/ +show errors; + + +exit; Index: openacs-4/packages/intermedia-driver/sql/oracle/search-packages-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-packages-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-packages-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,2 @@ +drop package body search_observer; +drop package search_observer; Index: openacs-4/packages/intermedia-driver/sql/oracle/search-sc-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-sc-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-sc-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,187 @@ +declare + foo integer; +begin + + -- + -- ACS-SC Contract: FtsEngineDriver + -- + + foo := acs_sc_contract.new( + contract_name => 'FtsEngineDriver', + contract_desc => 'Full Text Search Engine Driver' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Search.InputType', + msg_type_spec => 'query:string,offset:integer,limit:integer,user_id:integer,df:timestamp,dt:timestamp' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Search.OutputType', + msg_type_spec => 'ids:integer[],stopwords:string[]' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'search', + operation_desc => 'Search', + operation_iscachable_p => 'f', + operation_nargs => 6, + operation_inputtype => 'FtsEngineDriver.Search.InputType', + operation_outputtype => 'FtsEngineDriver.Search.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Index.InputType', + msg_type_spec => 'object_id:integer,txt:string,title:string,keywords:string' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Index.OutputType', + msg_type_spec => '' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'index', + operation_desc => 'Index', + operation_iscachable_p => 'f', + operation_nargs => 4, + operation_inputtype => 'FtsEngineDriver.Index.InputType', + operation_outputtype => 'FtsEngineDriver.Index.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Unindex.InputType', + msg_type_spec => 'object_id:integer' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Unindex.OutputType', + msg_type_spec => '' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'unindex', + operation_desc => 'Unindex', + operation_iscachable_p => 'f', + operation_nargs => 1, + operation_inputtype => 'FtsEngineDriver.Unindex.InputType', + operation_outputtype => 'FtsEngineDriver.Unindex.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.UpdateIndex.InputType', + msg_type_spec => 'object_id:integer,txt:string,title:string,keywords:string' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.UpdateIndex.OutputType', + msg_type_spec => '' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'update_index', + operation_desc => 'Update Index', + operation_iscachable_p => 'f', + operation_nargs => 4, + operation_inputtype => 'FtsEngineDriver.UpdateIndex.InputType', + operation_outputtype => 'FtsEngineDriver.UpdateIndex.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Summary.InputType', + msg_type_spec => 'query:string,txt:string' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Summary.OutputType', + msg_type_spec => 'summary:string' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'summary', + operation_desc => 'Summary', + operation_iscachable_p => 'f', + operation_nargs => 2, + operation_inputtype => 'FtsEngineDriver.Summary.InputType', + operation_outputtype => 'FtsEngineDriver.Summary.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Info.InputType', + msg_type_spec => '' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsEngineDriver.Info.OutputType', + msg_type_spec => 'package_key:string,version:version,automatic_and_queries_p:boolean,stopwords_p:boolean' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsEngineDriver', + operation_name => 'info', + operation_desc => 'Information about the driver', + operation_iscachable_p => 'f', + operation_nargs => 1, + operation_inputtype => 'FtsEngineDriver.Info.InputType', + operation_outputtype => 'FtsEngineDriver.Info.OutputType' + ); + + -- + -- ACS-SC Contract: FtsContentProvider + -- + + foo := acs_sc_contract.new( + contract_name => 'FtsContentProvider', + contract_desc => 'Full Text Search Content Provider' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsContentProvider.Datasource.InputType', + msg_type_spec => 'object_id:integer' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsContentProvider.Datasource.OutputType', + msg_type_spec => 'object_id:integer,title:string,content:string,mime:string,storage_type:string' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsContentProvider', + operation_name => 'datasource', + operation_desc => 'Data Source', + operation_iscachable_p => 'f', + operation_nargs => 1, + operation_inputtype => 'FtsContentProvider.Datasource.InputType', + operation_outputtype => 'FtsContentProvider.Datasource.OutputType' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsContentProvider.Url.InputType', + msg_type_spec => 'object_id:integer' + ); + + foo := acs_sc_msg_type.new( + msg_type_name => 'FtsContentProvider.Url.OutputType', + msg_type_spec => 'url:uri' + ); + + foo := acs_sc_operation.new( + contract_name => 'FtsContentProvider', + operation_name => 'url', + operation_desc => 'URL', + operation_iscachable_p => 'f', + operation_nargs => 1, + operation_inputtype => 'FtsContentProvider.Url.InputType', + operation_outputtype => 'FtsContentProvider.Url.OutputType' + ); + +end; +/ +show errors + +exit; \ No newline at end of file Index: openacs-4/packages/intermedia-driver/sql/oracle/search-sc-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-sc-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-sc-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,26 @@ +declare +begin + + acs_sc_contract.del(contract_name => 'FtsContentProvider'); + acs_sc_msg_type.del(msg_type_name => 'FtsContentProvider.Datasource.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsContentProvider.Datasource.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsContentProvider.Url.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsContentProvider.Url.OutputType'); + + acs_sc_contract.del(contract_name => 'FtsEngineDriver'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Search.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Search.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Index.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Index.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Unindex.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Unindex.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.UpdateIndex.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.UpdateIndex.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Summary.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Summary.OutputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Info.InputType'); + acs_sc_msg_type.del(msg_type_name => 'FtsEngineDriver.Info.OutputType'); + +end; +/ +show errors Index: openacs-4/packages/intermedia-driver/sql/oracle/search-tables-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-tables-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-tables-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,75 @@ +-- +-- Copyright (C) 2005 MIT +-- +-- This file is part of dotLRN. +-- +-- dotLRN is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 2 of the License, or (at your option) any later +-- version. +-- +-- dotLRN is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +-- details. +-- + +-- +-- Create database tables for .LRN site-wide search +-- +-- @author openacs@dirkgomez.de +-- @version $Id: search-tables-create.sql,v 1.1 2006/01/27 16:03:57 daveb Exp $ +-- @creation-date 13-May-2005 +-- +-- Partly ported from ACES. + +-- Central table for site-wide search. +create table site_wide_index ( + object_id integer + constraint sws_index_pk primary key + constraint sws_index_fk references acs_objects(object_id) on delete cascade, + object_name varchar(4000), + indexed_content clob, + -- Dirk Gomez: no not null constraint because we also want to + -- be able to index objects which are not tied to an object, + -- in particular people. + package_id integer + constraint swi_package_id_fk + references apm_packages + on delete cascade, + -- Dirk Gomez: This is a .LRNism. It looks like .LRN has not + -- only object-granular permiissions, but also + -- community-granular ones. In search we need not only check + -- whether a user has the right to view this object, but also + -- its community. In pure OpenACS this should always be a + -- null column and it should have no referential integrity. + community_id integer + constraint swi_community_id_fk + references dotlrn_communities_all + on delete cascade, + -- Dirk Gomez: That's the place to put an object's relevant + -- date which is part of the ranking function. In calendar + -- this is the item date, in forum it could be the last reply + -- date to a thread etc. + relevant_date date +); + +create table search_observer_queue ( + object_id integer, + event_date date + default sysdate, + event varchar(6) + constraint search_observer_queue_event_ck + check (event in ('INSERT','DELETE','UPDATE')) +); + +-- Intermedia sometimes is painful to debug, so I added a logging +-- mechanism which relies on Oracle's autonomous transactions: DML +-- statements are committed immediately so you can access this data +-- from a different session right away. + +create table sws_log_messages ( + logmessage varchar2(4000), + logtime date default sysdate); + +exit; Index: openacs-4/packages/intermedia-driver/sql/oracle/search-tables-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/search-tables-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/search-tables-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1 @@ +drop table search_observer_queue; Index: openacs-4/packages/intermedia-driver/sql/oracle/syndication-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/syndication-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/syndication-create.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,17 @@ +create table syndication ( + object_id integer + constraint syndication_object_id_fk + references acs_objects (object_id) on delete cascade + constraint syndication_pk + primary key, + last_updated date default sysdate not null, + rss_xml_frag blob, + body blob, + url blob +); + + +comment on table syndication is 'stores xml fragments for consolidating into rss feeds. Also stores an html version of the content item + and it''s url from the link field of the rss'; + +exit; Index: openacs-4/packages/intermedia-driver/sql/oracle/syndication-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/sql/oracle/Attic/syndication-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/sql/oracle/syndication-drop.sql 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,3 @@ +drop table syndication; + +exit; Index: openacs-4/packages/intermedia-driver/tcl/intermedia-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/intermedia-driver/tcl/intermedia-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/intermedia-driver/tcl/intermedia-procs.tcl 27 Jan 2006 16:03:57 -0000 1.1 @@ -0,0 +1,315 @@ +ad_library { + procedures to support intermedia search engine for Oracle +} + +ad_proc -public -callback search::index -impl intermedia-driver {} { + Search Index Callback for Oracle Intermedia + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-06-12 + +} { + # we want the datasource array reference in case we want to do something clever + if {![string equal "" $datasource]} { + upvar $datasource _datasource + } + set content "${title} ${content}" + # if storage type is file, store the text in the site_wide_index table + if {![db_string index_exists "select 1 from site_wide_index where object_id=:object_id" -default 0]} { + db_dml index "insert into site_wide_index + (object_id, object_name, package_id, relevant_date, community_id, indexed_content) + values + (:object_id, :title, :package_id, :relevant_date, :community_id, empty_clob() ) + returning indexed_content into :1" -clobs [list $content] + + + } else { + # call the update index proc since this object is already indexed + callback -impl intermedia-driver search::update_index \ + -object_id $object_id \ + -content $content \ + -title $title \ + -keywords $keywords \ + -community_id $community_id \ + -relevant_date $relevant_date \ + -description $description \ + -datasource $datasource \ + -package_id $package_id + + } + +} + +ad_proc -public -callback search::update_index -impl intermedia-driver {} { + Update item in the index + @author Dave Bauer (dave@thedesignexperience.org + @creation-date 2005-08-01 +} { + if {![string equal "" $datasource]} { + upvar $datasource _datasource + } + if {![db_string index_exists "select 1 from site_wide_index where object_id=:object_id" -default 0]} { + callback -impl intermedia-driver search::index \ + -object_id $object_id \ + -content $content \ + -title $title \ + -keywords $keywords \ + -community_id $community_id \ + -relevant_date $relevant_date \ + -description $description \ + -datasource $datasource \ + -package_id $package_id + return + } else { + db_dml index "update site_wide_index + set object_name=:title, + package_id=:package_id, + community_id=:community_id, + relevant_date=:relevant_date, + indexed_content=empty_clob() + where object_id=:object_id + returning indexed_content into :1" -clobs [list $content] + } +} + +ad_proc -public -callback search::unindex -impl intermedia-driver {} { + Remove item from search index + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-06-12 +} { + db_dml unindex "delete from site_wide_index where object_id=:object_id" +} + +ad_proc -public -callback search::search -impl intermedia-driver {} { + Search full text index + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + @param query + @param offset + @param limit + @param user_id + @param df + @param dt + @param package_ids + @param object_type +} { + if {[info exists package_ids] && [llength $package_ids]} { + set package_ids_clause " and swi.package_id in ([template::util::tcl_to_sql_list $package_ids]) " + } else { + set package_ids_clause "" + } + + if {[info exists object_type] && [string equal $object_type "forums"]} { + set object_type_clause " and o.object_type in ('forums_forum', 'forums_message') " + } elseif {[info exists object_type] && ![string equal $object_type "all"]} { + set object_type_clause " and o.object_type = :object_type " + } else { + set object_type_clause "" + } + + set weighted_score "score(10) - case when object_type='faq' + then nvl(months_between(sysdate,relevant_date)/4,20) + when object_type='forums' + then nvl(months_between(sysdate,relevant_date)*1.5,20) + when object_type='phb_person' + then 0 + when object_type='news' + then nvl(months_between(sysdate,relevant_date)*2,20) + when object_type='cal_item' + then nvl(months_between(sysdate,relevant_date)*2,20) + when object_type='file_storage_object' + then nvl(months_between(sysdate,relevant_date)*1.5,20) + when object_type='survey' + then nvl(months_between(sysdate,relevant_date)*1.5,20) + when object_type='static_portal_content' + then nvl(months_between(sysdate,relevant_date)*1.5,20) + end" + + set is_guest_p [search::is_guest_p] + if {!$is_guest_p} { + set people_search_clause { o.object_type = 'phb_person' or } + } else { + set people_search_clause { and } + } + + set results_ids [db_list search "select s.object_id from + (select rownum as r,o.object_id + + from site_wide_index swi, acs_objects o + where swi.object_id= o.object_id + $object_type_clause + and contains (swi.indexed_content,:query, 10)> 0 + and ( + $people_search_clause + (exists (select 1 + from acs_object_party_privilege_map m + where m.object_id = o.object_id + and m.party_id = :user_id + and m.privilege = 'read') + and (swi.community_id is null + or exists ( select 1 + from dotlrn_member_rels_approved + where community_id = swi.community_id + and user_id = :user_id)))) + $package_ids_clause + order by $weighted_score desc) s where r > $offset and r <= $offset + $limit"] + # TODO implement stopwords reporting for user query + + set count [db_string count "select count(swi.object_id) from site_wide_index swi, acs_objects o where o.object_id=swi.object_id $object_type_clause and contains (swi.indexed_content,:query)> 0 + and ( + $people_search_clause + (exists (select 1 + from acs_object_party_privilege_map m + where m.object_id = o.object_id + and m.party_id = :user_id + and m.privilege = 'read') + and exists (select 1 + from dotlrn_member_rels_approved + where community_id = swi.community_id + and user_id = :user_id))) + $package_ids_clause "] + set stop_words "" + ns_log notice " +----------------------------------------------------------------------------- +DAVEB99 intermedia::search +query = '{$query}' +package_ids = '${package_ids}' +return = '[list ids $results_ids stopwords $stop_words count $count]' +----------------------------------------------------------------------------- +" + return [list ids $results_ids stopwords $stop_words count $count] +} + +ad_proc -public -callback search::summary -impl intermedia-driver { +} { + Get summary for an object + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + @param object_id + +} { + + ns_log Notice "DIRK $query the query" + # TODO implement intermedia::summary + return [string range $text 0 2000] +} + +ad_proc -public -callback search::driver_info -impl intermedia-driver { +} { + Info for the service contract implementation + for intermedia + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + +} { + return [list package_key intermedia-driver version 1 automatic_and_queries_p 1 stopwords_p 1] +} + +namespace eval intermedia:: {} +namespace eval intermedia::install:: {} + +ad_proc -public intermedia::install::package_install { +} { + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + Install APM callback, sets up service contract + implementations + +} { + intermedia::install::register_fts_impl +} + +ad_proc -private intermedia::install::register_fts_impl { +} { + + Register FtsEngineDriver service contract implementation + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + @return + + @error +} { + + set spec { + name "intermedia-driver" + aliases { + search intermedia::search + index intermedia::index + unindex intermedia::unindex + update_index intermedia::update_index + summary intermedia::summary + info intermedia::driver_info + } + contract_name "FtsEngineDriver" + owner "search" + } + + acs_sc::impl::new_from_spec -spec $spec + +} + +ad_proc -public intermedia::search { + query + offset + limit + user_id + df + dt +} { + Search full text index + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + @param query + @param offset + @param limit + @param user_id + @param df + @param dt +} { + set results_ids [db_list search "select o.object_id from site_wide_index swi, acs_objects o where swi.object_id= o.object_id and contains (swi.indexed_content,:query)> 0 and and rownum > $offset and rownum <= $offset + $limit"] + # TODO implement stopwords reporting for user query + set count [db_string count "select count(swi.object_id) from site_wide_index swi, acs_objects o where o.object_id=swi.object_id and contains (swi.indexed_content,:query)> 0"] + set stop_words "" + ns_log notice " +----------------------------------------------------------------------------- +DAVEB intermedia::search +query = '{$query}' +return = '[list ids $results_ids stopwords $stop_words count $count]' +----------------------------------------------------------------------------- +" + return [list ids $results_ids stopwords $stop_words count $count] +} + +ad_proc -public -callback search::summary -impl intermedia-driver { +} { + Get summary for an object + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + + @param object_id + +} { + # TODO implement intermedia::summary + return [string range $text 0 100] +} + +ad_proc -public -callback search::driver_info -impl intermedia-driver { +} { + Info for the service contract implementation + for intermedia + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-05-29 + +} { + return [list package_key intermedia-driver version 1 automatic_and_queries_p 1 stopwords_p 1] +} \ No newline at end of file