Index: openacs-4/packages/acs-bootstrap-installer/bootstrap.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-bootstrap-installer/bootstrap.tcl,v diff -u -N -r1.29 -r1.30 --- openacs-4/packages/acs-bootstrap-installer/bootstrap.tcl 10 Jan 2007 21:22:02 -0000 1.29 +++ openacs-4/packages/acs-bootstrap-installer/bootstrap.tcl 25 Nov 2008 17:08:50 -0000 1.30 @@ -149,6 +149,12 @@ apm_bootstrap_load_libraries -init xotcl-core } + # Build the list of subsite packages + apm_build_subsite_packages_list + + # Build the nsv dependency and descendent structures + apm_build_package_relationships + # Load libraries, queries etc. for remaining packages apm_load_packages Index: openacs-4/packages/acs-kernel/acs-kernel.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/acs-kernel.info,v diff -u -N -r1.99 -r1.100 --- openacs-4/packages/acs-kernel/acs-kernel.info 23 Sep 2008 19:13:58 -0000 1.99 +++ openacs-4/packages/acs-kernel/acs-kernel.info 25 Nov 2008 17:08:49 -0000 1.100 @@ -7,15 +7,15 @@ t t - + OpenACS Core Team Routines and data models providing the foundation for OpenACS-based Web services. 2008-05-31 OpenACS The OpenACS kernel contains the core datamodel create and drop scripts for such things as objects, groups, partiies and the supporting PL/SQL and PL/pgSQL procedures. 3 - + Index: openacs-4/packages/acs-kernel/sql/oracle/acs-metadata-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/oracle/acs-metadata-create.sql,v diff -u -N -r1.10 -r1.11 --- openacs-4/packages/acs-kernel/sql/oracle/acs-metadata-create.sql 30 Aug 2006 17:25:08 -0000 1.10 +++ openacs-4/packages/acs-kernel/sql/oracle/acs-metadata-create.sql 25 Nov 2008 17:08:49 -0000 1.11 @@ -260,6 +260,11 @@ values ('email', null); + insert into acs_datatypes + (datatype, max_n_values) + values + ('file', 1); + commit; end; / Index: openacs-4/packages/acs-kernel/sql/oracle/apm-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/oracle/apm-create.sql,v diff -u -N -r1.41 -r1.42 --- openacs-4/packages/acs-kernel/sql/oracle/apm-create.sql 8 May 2008 02:25:04 -0000 1.41 +++ openacs-4/packages/acs-kernel/sql/oracle/apm-create.sql 25 Nov 2008 17:08:49 -0000 1.42 @@ -37,7 +37,13 @@ check (initial_install_p in ('t', 'f')), singleton_p char(1) default 'f' not null constraint apm_packages_site_avail_p_ck - check (singleton_p in ('t', 'f')) + check (singleton_p in ('t', 'f')), + implements_subsite_p char(1) default 'f' not null + constraint apm_packages_impl_subsite_p_ck + check (singleton_p in ('t', 'f')), + inherit_templates_p char(1) default 't' not null + constraint apm_packages_inherit_t_p_ck + check (inherit_templates_p in ('t', 'f')) ); comment on table apm_package_types is ' @@ -77,6 +83,18 @@ in other words whether or not this package is part of the OpenACS core. '; +comment on column apm_package_types.implements_subsite_p is ' + If true, this package implements subsite semantics, typically by extending the + acs-subsite package. Used by the admin "mount subsite" UI, the request processor (for + setting ad_conn''s subsite_* attributes), etc. +'; + +comment on column apm_package_types.inherit_templates_p is ' + If true, inherit templates from packages this package extends. If false, only + templates in this package''s www subdirectory tree will be mapped to URLs by the + request processor. +'; + begin -- Create a new object type for packages. acs_object_type.create_type ( @@ -505,8 +523,10 @@ create or replace view apm_package_version_info as select v.package_key, t.package_uri, t.pretty_name, t.singleton_p, t.initial_install_p, v.version_id, v.version_name, + t.inherit_templates_p, t.implements_subsite_p, v.version_uri, v.summary, v.description_format, v.description, v.release_date, - v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, v.imported_p, v.data_model_loaded_p, + v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, + v.imported_p, v.data_model_loaded_p, v.activation_date, v.deactivation_date, nvl(v.content_length,0) as tarball_length, distribution_uri, distribution_date @@ -743,7 +763,8 @@ constraint apm_package_deps_version_id_nn not null, dependency_type varchar2(20) constraint apm_package_deps_type_nn not null - constraint apm_package_deps_type_ck check(dependency_type in ('provides','requires')), + constraint apm_package_deps_type_ck + check(dependency_type in ('extends', 'provides','requires')), service_uri varchar2(1500) constraint apm_package_deps_uri_nn not null, service_version varchar2(100) @@ -828,6 +849,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -848,6 +873,10 @@ default null, singleton_p in apm_package_types.singleton_p%TYPE default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -873,6 +902,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -895,6 +928,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1169,6 +1206,8 @@ package_type in apm_package_types.package_type%TYPE, initial_install_p in apm_package_types.initial_install_p%TYPE, singleton_p in apm_package_types.singleton_p%TYPE, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE default null ); @@ -1187,6 +1226,10 @@ default null, singleton_p in apm_package_types.singleton_p%TYPE default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1285,6 +1328,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1300,6 +1347,8 @@ package_type => register_package.package_type, initial_install_p => register_package.initial_install_p, singleton_p => register_package.singleton_p, + implements_subsite_p => register_package.implements_subsite_p, + inherit_templates_p => register_package.inherit_templates_p, spec_file_path => register_package.spec_file_path, spec_file_mtime => spec_file_mtime ); @@ -1319,6 +1368,10 @@ default null, singleton_p in apm_package_types.singleton_p%TYPE default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1335,6 +1388,8 @@ package_type => update_package.package_type, initial_install_p => update_package.initial_install_p, singleton_p => update_package.singleton_p, + implements_subsite_p => update_package.implements_subsite_p, + inherit_templates_p => update_package.inherit_templates_p, spec_file_path => update_package.spec_file_path, spec_file_mtime => update_package.spec_file_mtime ); @@ -1374,6 +1429,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1389,6 +1448,8 @@ package_type => 'apm_application', initial_install_p => register_application.initial_install_p, singleton_p => register_application.singleton_p, + implements_subsite_p => register_application.implements_subsite_p, + inherit_templates_p => register_application.inherit_templates_p, spec_file_path => register_application.spec_file_path, spec_file_mtime => register_application.spec_file_mtime ); @@ -1415,6 +1476,10 @@ default 'f', singleton_p in apm_package_types.singleton_p%TYPE default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -1430,6 +1495,8 @@ package_type => 'apm_service', initial_install_p => register_service.initial_install_p, singleton_p => register_service.singleton_p, + implements_subsite_p => register_service.implements_subsite_p, + inherit_templates_p => register_service.inherit_templates_p, spec_file_path => register_service.spec_file_path, spec_file_mtime => register_service.spec_file_mtime ); @@ -2358,18 +2425,22 @@ package_type in apm_package_types.package_type%TYPE, initial_install_p in apm_package_types.initial_install_p%TYPE, singleton_p in apm_package_types.singleton_p%TYPE, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE default null ) is begin insert into apm_package_types (package_key, pretty_name, pretty_plural, package_uri, package_type, - spec_file_path, spec_file_mtime, initial_install_p, singleton_p) + spec_file_path, spec_file_mtime, initial_install_p, singleton_p, + implements_subsite_p, inherit_templates_p) values (create_type.package_key, create_type.pretty_name, create_type.pretty_plural, create_type.package_uri, create_type.package_type, create_type.spec_file_path, - create_type.spec_file_mtime, create_type.initial_install_p, create_type.singleton_p); + create_type.spec_file_mtime, create_type.initial_install_p, create_type.singleton_p, + create_type.implements_subsite_p, create_type.inherit_templates_p); end create_type; function update_type( @@ -2386,6 +2457,10 @@ default null, singleton_p in apm_package_types.singleton_p%TYPE default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, spec_file_path in apm_package_types.spec_file_path%TYPE default null, spec_file_mtime in apm_package_types.spec_file_mtime%TYPE @@ -2401,7 +2476,9 @@ spec_file_path = nvl(update_type.spec_file_path, spec_file_path), spec_file_mtime = nvl(update_type.spec_file_mtime, spec_file_mtime), initial_install_p = nvl(update_type.initial_install_p, initial_install_p), - singleton_p = nvl(update_type.singleton_p, singleton_p) + singleton_p = nvl(update_type.singleton_p, singleton_p), + implements_subsite_p = nvl(update_type.implements_subsite_p, implements_subsite_p), + inherits_subsite_p = nvl(update_type.implements_subsite_p, implements_subsite_p) where package_key = update_type.package_key; return update_type.package_key; end update_type; Index: openacs-4/packages/acs-kernel/sql/oracle/upgrade/upgrade-5.5.0d3-5.5.0d4.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/oracle/upgrade/upgrade-5.5.0d3-5.5.0d4.sql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-kernel/sql/oracle/upgrade/upgrade-5.5.0d3-5.5.0d4.sql 25 Nov 2008 17:08:49 -0000 1.1 @@ -0,0 +1,1393 @@ +alter table apm_package_dependencies drop constraint apm_package_deps_type_ck; +alter table apm_package_dependencies add + constraint apm_package_deps_type_ck + check (dependency_type in ('provides', 'requires', 'extends')); + +create or replace package apm_package_version +as + function new ( + version_id in apm_package_versions.version_id%TYPE + default null, + package_key in apm_package_versions.package_key%TYPE, + version_name in apm_package_versions.version_name%TYPE + default null, + version_uri in apm_package_versions.version_uri%TYPE, + summary in apm_package_versions.summary%TYPE, + description_format in apm_package_versions.description_format%TYPE, + description in apm_package_versions.description%TYPE, + release_date in apm_package_versions.release_date%TYPE, + vendor in apm_package_versions.vendor%TYPE, + vendor_uri in apm_package_versions.vendor_uri%TYPE, + auto_mount in apm_package_versions.auto_mount%TYPE, + installed_p in apm_package_versions.installed_p%TYPE + default 'f', + data_model_loaded_p in apm_package_versions.data_model_loaded_p%TYPE + default 'f' + ) return apm_package_versions.version_id%TYPE; + + procedure del ( + version_id in apm_packages.package_id%TYPE + ); + + procedure enable ( + version_id in apm_package_versions.version_id%TYPE + ); + + procedure disable ( + version_id in apm_package_versions.version_id%TYPE + ); + + function edit ( + new_version_id in apm_package_versions.version_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + version_name in apm_package_versions.version_name%TYPE + default null, + version_uri in apm_package_versions.version_uri%TYPE, + summary in apm_package_versions.summary%TYPE, + description_format in apm_package_versions.description_format%TYPE, + description in apm_package_versions.description%TYPE, + release_date in apm_package_versions.release_date%TYPE, + vendor in apm_package_versions.vendor%TYPE, + vendor_uri in apm_package_versions.vendor_uri%TYPE, + auto_mount in apm_package_versions.auto_mount%TYPE, + installed_p in apm_package_versions.installed_p%TYPE + default 'f', + data_model_loaded_p in apm_package_versions.data_model_loaded_p%TYPE + default 'f' + ) return apm_package_versions.version_id%TYPE; + + -- Add an interface provided by this version. + function add_interface( + interface_id in apm_package_dependencies.dependency_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + interface_uri in apm_package_dependencies.service_uri%TYPE, + interface_version in apm_package_dependencies.service_version%TYPE + ) return apm_package_dependencies.dependency_id%TYPE; + + procedure remove_interface( + interface_id in apm_package_dependencies.dependency_id%TYPE + ); + + procedure remove_interface( + interface_uri in apm_package_dependencies.service_uri%TYPE, + interface_version in apm_package_dependencies.service_version%TYPE, + version_id in apm_package_versions.version_id%TYPE + ); + + -- Add a requirement for this version. A requirement is some interface that this + -- version depends on. + function add_dependency( + dependency_type in apm_package_dependenceis.dependency_type%TYPE, + dependency_id in apm_package_dependencies.dependency_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + dependency_uri in apm_package_dependencies.service_uri%TYPE, + dependency_version in apm_package_dependencies.service_version%TYPE + ) return apm_package_dependencies.dependency_id%TYPE; + + procedure remove_dependency( + dependency_id in apm_package_dependencies.dependency_id%TYPE + ); + + procedure remove_dependency( + dependency_uri in apm_package_dependencies.service_uri%TYPE, + dependency_version in apm_package_dependencies.service_version%TYPE, + version_id in apm_package_versions.version_id%TYPE + ); + + -- Given a version_name (e.g. 3.2a), return + -- something that can be lexicographically sorted. + function sortable_version_name ( + version_name in apm_package_versions.version_name%TYPE + ) return varchar2; + + -- Given two version names, return 1 if one > two, -1 if two > one, 0 otherwise. + -- Deprecate? + function version_name_greater( + version_name_one in apm_package_versions.version_name%TYPE, + version_name_two in apm_package_versions.version_name%TYPE + ) return integer; + + function upgrade_p( + path in varchar2, + initial_version_name in apm_package_versions.version_name%TYPE, + final_version_name in apm_package_versions.version_name%TYPE + ) return integer; + + procedure upgrade( + version_id in apm_package_versions.version_id%TYPE + ); + +end apm_package_version; +/ +show errors + +create or replace package body apm_package_version +as + function new ( + version_id in apm_package_versions.version_id%TYPE + default null, + package_key in apm_package_versions.package_key%TYPE, + version_name in apm_package_versions.version_name%TYPE + default null, + version_uri in apm_package_versions.version_uri%TYPE, + summary in apm_package_versions.summary%TYPE, + description_format in apm_package_versions.description_format%TYPE, + description in apm_package_versions.description%TYPE, + release_date in apm_package_versions.release_date%TYPE, + vendor in apm_package_versions.vendor%TYPE, + vendor_uri in apm_package_versions.vendor_uri%TYPE, + auto_mount in apm_package_versions.auto_mount%TYPE, + installed_p in apm_package_versions.installed_p%TYPE + default 'f', + data_model_loaded_p in apm_package_versions.data_model_loaded_p%TYPE + default 'f' + ) return apm_package_versions.version_id%TYPE + is + v_version_id apm_package_versions.version_id%TYPE; + begin + if version_id is null then + select acs_object_id_seq.nextval + into v_version_id + from dual; + else + v_version_id := version_id; + end if; + v_version_id := acs_object.new( + object_id => v_version_id, + object_type => 'apm_package_version', + title => package_key || ', Version ' || version_name + ); + insert into apm_package_versions + (version_id, package_key, version_name, version_uri, summary, description_format, description, + release_date, vendor, vendor_uri, auto_mount, installed_p, data_model_loaded_p) + values + (v_version_id, package_key, version_name, version_uri, + summary, description_format, description, + release_date, vendor, vendor_uri, auto_mount, + installed_p, data_model_loaded_p); + return v_version_id; + end new; + + procedure del ( + version_id in apm_packages.package_id%TYPE + ) + is + begin + delete from apm_package_owners + where version_id = apm_package_version.del.version_id; + + delete from apm_package_dependencies + where version_id = apm_package_version.del.version_id; + + delete from apm_package_versions + where version_id = apm_package_version.del.version_id; + + acs_object.del(apm_package_version.del.version_id); + + end del; + + procedure enable ( + version_id in apm_package_versions.version_id%TYPE + ) + is + begin + update apm_package_versions set enabled_p = 't' + where version_id = enable.version_id; + end enable; + + procedure disable ( + version_id in apm_package_versions.version_id%TYPE + ) + is + begin + update apm_package_versions + set enabled_p = 'f' + where version_id = disable.version_id; + end disable; + + function copy( + version_id in apm_package_versions.version_id%TYPE, + new_version_id in apm_package_versions.version_id%TYPE default null, + new_version_name in apm_package_versions.version_name%TYPE, + new_version_uri in apm_package_versions.version_uri%TYPE + ) return apm_package_versions.version_id%TYPE + is + v_version_id integer; + begin + v_version_id := acs_object.new( + object_id => new_version_id, + object_type => 'apm_package_version' + ); + + insert into apm_package_versions(version_id, package_key, version_name, + version_uri, summary, description_format, description, + release_date, vendor, vendor_uri, auto_mount) + select v_version_id, package_key, copy.new_version_name, + copy.new_version_uri, summary, description_format, description, + release_date, vendor, vendor_uri, auto_mount + from apm_package_versions + where version_id = copy.version_id; + + update acs_objects + set title = (select v.package_key || ', Version ' || v.version_name + from apm_package_versions v + where v.version_id = copy.version_id) + where object_id = copy.version_id; + + insert into apm_package_dependencies(dependency_id, version_id, dependency_type, service_uri, service_version) + select acs_object_id_seq.nextval, v_version_id, dependency_type, service_uri, service_version + from apm_package_dependencies + where version_id = copy.version_id; + + insert into apm_package_callbacks (version_id, type, proc) + select v_version_id, type, proc + from apm_package_callbacks + where version_id = copy.version_id; + + insert into apm_package_owners(version_id, owner_uri, owner_name, sort_key) + select v_version_id, owner_uri, owner_name, sort_key + from apm_package_owners + where version_id = copy.version_id; + + return v_version_id; + end copy; + + function edit ( + new_version_id in apm_package_versions.version_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + version_name in apm_package_versions.version_name%TYPE + default null, + version_uri in apm_package_versions.version_uri%TYPE, + summary in apm_package_versions.summary%TYPE, + description_format in apm_package_versions.description_format%TYPE, + description in apm_package_versions.description%TYPE, + release_date in apm_package_versions.release_date%TYPE, + vendor in apm_package_versions.vendor%TYPE, + vendor_uri in apm_package_versions.vendor_uri%TYPE, + auto_mount in apm_package_versions.auto_mount%TYPE, + installed_p in apm_package_versions.installed_p%TYPE + default 'f', + data_model_loaded_p in apm_package_versions.data_model_loaded_p%TYPE + default 'f' + ) return apm_package_versions.version_id%TYPE + is + v_version_id apm_package_versions.version_id%TYPE; + version_unchanged_p integer; + begin + -- Determine if version has changed. + select decode(count(*),0,0,1) into version_unchanged_p + from apm_package_versions + where version_id = edit.version_id + and version_name = edit.version_name; + if version_unchanged_p <> 1 then + v_version_id := copy( + version_id => edit.version_id, + new_version_id => edit.new_version_id, + new_version_name => edit.version_name, + new_version_uri => edit.version_uri + ); + else + v_version_id := edit.version_id; + end if; + + update apm_package_versions + set version_uri = edit.version_uri, + summary = edit.summary, + description_format = edit.description_format, + description = edit.description, + release_date = trunc(sysdate), + vendor = edit.vendor, + vendor_uri = edit.vendor_uri, + auto_mount = edit.auto_mount, + installed_p = edit.installed_p, + data_model_loaded_p = edit.data_model_loaded_p + where version_id = v_version_id; + return v_version_id; + end edit; + +-- Add an interface provided by this version. + function add_interface( + interface_id in apm_package_dependencies.dependency_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + interface_uri in apm_package_dependencies.service_uri%TYPE, + interface_version in apm_package_dependencies.service_version%TYPE + ) return apm_package_dependencies.dependency_id%TYPE + is + v_dep_id apm_package_dependencies.dependency_id%TYPE; + begin + if add_interface.interface_id is null then + select acs_object_id_seq.nextval into v_dep_id from dual; + else + v_dep_id := add_interface.interface_id; + end if; + + insert into apm_package_dependencies + (dependency_id, version_id, dependency_type, service_uri, service_version) + values + (v_dep_id, add_interface.version_id, 'provides', add_interface.interface_uri, + add_interface.interface_version); + return v_dep_id; + end add_interface; + + procedure remove_interface( + interface_id in apm_package_dependencies.dependency_id%TYPE + ) + is + begin + delete from apm_package_dependencies + where dependency_id = remove_interface.interface_id; + end remove_interface; + + procedure remove_interface( + interface_uri in apm_package_dependencies.service_uri%TYPE, + interface_version in apm_package_dependencies.service_version%TYPE, + version_id in apm_package_versions.version_id%TYPE + ) + is + v_dep_id apm_package_dependencies.dependency_id%TYPE; + begin + select dependency_id into v_dep_id from apm_package_dependencies + where service_uri = remove_interface.interface_uri + and interface_version = remove_interface.interface_version; + remove_interface(v_dep_id); + end remove_interface; + + -- Add a requirement for this version. A requirement is some interface that this + -- version depends on. + function add_dependency( + dependency_type in apm_package_dependenceis.dependency_type%TYPE, + dependency_id in apm_package_dependencies.dependency_id%TYPE + default null, + version_id in apm_package_versions.version_id%TYPE, + dependency_uri in apm_package_dependencies.service_uri%TYPE, + dependency_version in apm_package_dependencies.service_version%TYPE + ) return apm_package_dependencies.dependency_id%TYPE + is + v_dep_id apm_package_dependencies.dependency_id%TYPE; + begin + if add_dependency.dependency_id is null then + select acs_object_id_seq.nextval into v_dep_id from dual; + else + v_dep_id := add_dependency.dependency_id; + end if; + + insert into apm_package_dependencies + (dependency_id, version_id, dependency_type, service_uri, service_version) + values + (v_dep_id, add_dependency.version_id, add_dependency.dependency_type, + add_dependency.dependency_uri, add_dependency.dependency_version); + return v_dep_id; + end add_dependency; + + procedure remove_dependency( + dependency_id in apm_package_dependencies.dependency_id%TYPE + ) + is + begin + delete from apm_package_dependencies + where dependency_id = remove_dependency.dependency_id; + end remove_dependency; + + + procedure remove_dependency( + dependency_uri in apm_package_dependencies.service_uri%TYPE, + dependency_version in apm_package_dependencies.service_version%TYPE, + version_id in apm_package_versions.version_id%TYPE + ) + is + v_dep_id apm_package_dependencies.dependency_id%TYPE; + begin + select dependency_id into v_dep_id from apm_package_dependencies + where service_uri = remove_dependency.dependency_uri + and service_version = remove_dependency.dependency_version; + remove_dependency(v_dep_id); + end remove_dependency; + + function sortable_version_name ( + version_name in apm_package_versions.version_name%TYPE + ) return varchar2 + is + a_fields integer; + a_start integer; + a_end integer; + a_order varchar2(1000); + a_char char(1); + a_seen_letter char(1) := 'f'; + begin + a_fields := 0; + a_start := 1; + loop + a_end := a_start; + + -- keep incrementing a_end until we run into a non-number + while substr(version_name, a_end, 1) >= '0' and substr(version_name, a_end, 1) <= '9' loop + a_end := a_end + 1; + end loop; + if a_end = a_start then + return -1; + -- raise_application_error(-20000, 'Expected number at position ' || a_start); + end if; + if a_end - a_start > 4 then + return -1; + -- raise_application_error(-20000, 'Numbers within versions can only be up to 4 digits long'); + end if; + + -- zero-pad and append the number + a_order := a_order || substr('0000', 1, 4 - (a_end - a_start)) || + substr(version_name, a_start, a_end - a_start) || '.'; + a_fields := a_fields + 1; + if a_end > length(version_name) then + -- end of string - we're outta here + if a_seen_letter = 'f' then + -- append the "final" suffix if there haven't been any letters + -- so far (i.e., not development/alpha/beta) + a_order := a_order || lpad(' ',(7 - a_fields)*5,'0000.') || ' 3F.'; + end if; + return a_order; + end if; + + -- what's the next character? if a period, just skip it + a_char := substr(version_name, a_end, 1); + if a_char = '.' then + null; + else + -- if the next character was a letter, append the appropriate characters + if a_char = 'd' then + a_order := a_order || lpad(' ',(7 - a_fields)*5,'0000.') || ' 0D.'; + elsif a_char = 'a' then + a_order := a_order || lpad(' ',(7 - a_fields)*5,'0000.') || ' 1A.'; + elsif a_char = 'b' then + a_order := a_order || lpad(' ',(7 - a_fields)*5,'0000.') || ' 2B.'; + end if; + + -- can't have something like 3.3a1b2 - just one letter allowed! + if a_seen_letter = 't' then + return -1; + -- raise_application_error(-20000, 'Not allowed to have two letters in version name ''' + -- || version_name || ''''); + end if; + a_seen_letter := 't'; + + -- end of string - we're done! + if a_end = length(version_name) then + return a_order; + end if; + end if; + a_start := a_end + 1; + end loop; + end sortable_version_name; + + function version_name_greater( + version_name_one in apm_package_versions.version_name%TYPE, + version_name_two in apm_package_versions.version_name%TYPE + ) return integer is + a_order_a varchar2(1000); + a_order_b varchar2(1000); + begin + a_order_a := sortable_version_name(version_name_one); + a_order_b := sortable_version_name(version_name_two); + if a_order_a < a_order_b then + return -1; + elsif a_order_a > a_order_b then + return 1; + end if; + return 0; + end version_name_greater; + + function upgrade_p( + path in varchar2, + initial_version_name in apm_package_versions.version_name%TYPE, + final_version_name in apm_package_versions.version_name%TYPE + ) return integer + is + v_pos1 integer; + v_pos2 integer; + v_path varchar2(1500); + v_version_from apm_package_versions.version_name%TYPE; + v_version_to apm_package_versions.version_name%TYPE; + begin + + -- Set v_path to the tail of the path (the file name). + v_path := substr(upgrade_p.path, instr(upgrade_p.path, '/', -1) + 1); + + -- Remove the extension, if it's .sql. + v_pos1 := instr(v_path, '.', -1); + if v_pos1 > 0 and substr(v_path, v_pos1) = '.sql' then + v_path := substr(v_path, 1, v_pos1 - 1); + end if; + + -- Figure out the from/to version numbers for the individual file. + v_pos1 := instr(v_path, '-', -1, 2); + v_pos2 := instr(v_path, '-', -1); + if v_pos1 = 0 or v_pos2 = 0 then + -- There aren't two hyphens in the file name. Bail. + return 0; + end if; + + v_version_from := substr(v_path, v_pos1 + 1, v_pos2 - v_pos1 - 1); + v_version_to := substr(v_path, v_pos2 + 1); + + if version_name_greater(upgrade_p.initial_version_name, v_version_from) <= 0 and + version_name_greater(upgrade_p.final_version_name, v_version_to) >= 0 then + return 1; + end if; + + return 0; + exception when others then + -- Invalid version number. + return 0; + end upgrade_p; + + procedure upgrade( + version_id in apm_package_versions.version_id%TYPE + ) + is + begin + update apm_package_versions + set enabled_p = 'f', + installed_p = 'f' + where package_key = (select package_key from apm_package_versions + where version_id = upgrade.version_id); + update apm_package_versions + set enabled_p = 't', + installed_p = 't' + where version_id = upgrade.version_id; + + end upgrade; + +end apm_package_version; +/ +show errors + +alter table apm_package_types + add implements_subsite_p char(1) default 'f'; + +begin + update apm_package_types + set implements_subsite_p = 't' + where package_key = 'acs-subsite'; not null; +end; +/ +show errors; + +alter table apm_package_types add + constraint apm_packages_impl_subsite_p_ck + check (singleton_p in ('t', 'f')); + +alter table apm_package_types + add inherit_template_p char(1) default 't'; + +alter table apm_package_types add + constraint apm_packages_inherit_t_p_ck + check (inherit_templates_p in ('t', 'f')); + +create or replace view apm_package_version_info as + select v.package_key, t.package_uri, t.pretty_name, t.singleton_p, t.initial_install_p, + v.version_id, v.version_name, + t.inherit_templates_p, t.implements_subsite_p, + v.version_uri, v.summary, v.description_format, v.description, v.release_date, + v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, + v.imported_p, v.data_model_loaded_p, + v.activation_date, v.deactivation_date, + nvl(v.content_length,0) as tarball_length, + distribution_uri, distribution_date + from apm_package_types t, apm_package_versions v + where v.package_key = t.package_key; + +-- A useful view for simply determining which packages are eanbled. +create or replace view apm_enabled_package_versions as + select * from apm_package_version_info + where enabled_p = 't'; + +create or replace package apm +as + procedure register_package ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + package_type in apm_package_types.package_type%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ); + + function update_package ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE + default null, + pretty_plural in apm_package_types.pretty_plural%TYPE + default null, + package_uri in apm_package_types.package_uri%TYPE + default null, + package_type in apm_package_types.package_type%TYPE + default null, + initial_install_p in apm_package_types.initial_install_p%TYPE + default null, + singleton_p in apm_package_types.singleton_p%TYPE + default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) return apm_package_types.package_type%TYPE; + + procedure unregister_package ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 't' + ); + + function register_p ( + package_key in apm_package_types.package_key%TYPE + ) return integer; + + -- Informs the APM that this application is available for use. + procedure register_application ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ); + + -- Remove the application from the system. + procedure unregister_application ( + package_key in apm_package_types.package_key%TYPE, + -- Delete all objects associated with this application. + cascade_p in char default 'f' + ); + + procedure register_service ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ); + + -- Remove the service from the system. + procedure unregister_service ( + package_key in apm_package_types.package_key%TYPE, + -- Delete all objects associated with this service. + cascade_p in char default 'f' + ); + + -- Indicate to APM that a parameter is available to the system. + function register_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE + default null, + package_key in apm_parameters.package_key%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE, + description in apm_parameters.description%TYPE + default null, + datatype in apm_parameters.datatype%TYPE + default 'string', + default_value in apm_parameters.default_value%TYPE + default null, + section_name in apm_parameters.section_name%TYPE + default null, + min_n_values in apm_parameters.min_n_values%TYPE + default 1, + max_n_values in apm_parameters.max_n_values%TYPE + default 1 + ) return apm_parameters.parameter_id%TYPE; + + function update_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + default null, + description in apm_parameters.description%TYPE + default null, + datatype in apm_parameters.datatype%TYPE + default 'string', + default_value in apm_parameters.default_value%TYPE + default null, + section_name in apm_parameters.section_name%TYPE + default null, + min_n_values in apm_parameters.min_n_values%TYPE + default 1, + max_n_values in apm_parameters.max_n_values%TYPE + default 1 + ) return apm_parameters.parameter_name%TYPE; + + function parameter_p( + package_key in apm_package_types.package_key%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + ) return integer; + + -- Remove any uses of this parameter. + procedure unregister_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE + default null + ); + + -- Return the value of this parameter for a specific package and parameter. + function get_value ( + parameter_id in apm_parameter_values.parameter_id%TYPE, + package_id in apm_packages.package_id%TYPE + ) return apm_parameter_values.attr_value%TYPE; + + function get_value ( + package_id in apm_packages.package_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + ) return apm_parameter_values.attr_value%TYPE; + + -- Sets a value for a parameter for a package instance. + procedure set_value ( + parameter_id in apm_parameter_values.parameter_id%TYPE, + package_id in apm_packages.package_id%TYPE, + attr_value in apm_parameter_values.attr_value%TYPE + ); + + procedure set_value ( + package_id in apm_packages.package_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE, + attr_value in apm_parameter_values.attr_value%TYPE + ); + + +end apm; +/ +show errors + +create or replace package apm_package_type +as + procedure create_type( + package_key in apm_package_types.package_key%TYPE, + pretty_name in acs_object_types.pretty_name%TYPE, + pretty_plural in acs_object_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + package_type in apm_package_types.package_type%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE, + singleton_p in apm_package_types.singleton_p%TYPE, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE, + spec_file_path in apm_package_types.spec_file_path%TYPE default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE default null + ); + + function update_type ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in acs_object_types.pretty_name%TYPE + default null, + pretty_plural in acs_object_types.pretty_plural%TYPE + default null, + package_uri in apm_package_types.package_uri%TYPE + default null, + package_type in apm_package_types.package_type%TYPE + default null, + initial_install_p in apm_package_types.initial_install_p%TYPE + default null, + singleton_p in apm_package_types.singleton_p%TYPE + default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) return apm_package_types.package_type%TYPE; + + procedure drop_type ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 'f' + ); + + function num_parameters ( + package_key in apm_package_types.package_key%TYPE + ) return integer; + +end apm_package_type; +/ +show errors + +create or replace package body apm +as + procedure register_package ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + package_type in apm_package_types.package_type%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) + is + begin + apm_package_type.create_type( + package_key => register_package.package_key, + pretty_name => register_package.pretty_name, + pretty_plural => register_package.pretty_plural, + package_uri => register_package.package_uri, + package_type => register_package.package_type, + initial_install_p => register_package.initial_install_p, + singleton_p => register_package.singleton_p, + implements_subsite_p => register_package.implements_subsite_p, + inherit_templates_p => register_package.inherit_templates_p, + spec_file_path => register_package.spec_file_path, + spec_file_mtime => spec_file_mtime + ); + end register_package; + + function update_package ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE + default null, + pretty_plural in apm_package_types.pretty_plural%TYPE + default null, + package_uri in apm_package_types.package_uri%TYPE + default null, + package_type in apm_package_types.package_type%TYPE + default null, + initial_install_p in apm_package_types.initial_install_p%TYPE + default null, + singleton_p in apm_package_types.singleton_p%TYPE + default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) return apm_package_types.package_type%TYPE + is + begin + + return apm_package_type.update_type( + package_key => update_package.package_key, + pretty_name => update_package.pretty_name, + pretty_plural => update_package.pretty_plural, + package_uri => update_package.package_uri, + package_type => update_package.package_type, + initial_install_p => update_package.initial_install_p, + singleton_p => update_package.singleton_p, + implements_subsite_p => update_package.implements_subsite_p, + inherit_templates_p => update_package.inherit_templates_p, + spec_file_path => update_package.spec_file_path, + spec_file_mtime => update_package.spec_file_mtime + ); + + end update_package; + + + procedure unregister_package ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 't' + ) + is + begin + apm_package_type.drop_type( + package_key => unregister_package.package_key, + cascade_p => unregister_package.cascade_p + ); + end unregister_package; + + function register_p ( + package_key in apm_package_types.package_key%TYPE + ) return integer + is + v_register_p integer; + begin + select decode(count(*),0,0,1) into v_register_p from apm_package_types + where package_key = register_p.package_key; + return v_register_p; + end register_p; + + procedure register_application ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) + is + begin + apm.register_package( + package_key => register_application.package_key, + pretty_name => register_application.pretty_name, + pretty_plural => register_application.pretty_plural, + package_uri => register_application.package_uri, + package_type => 'apm_application', + initial_install_p => register_application.initial_install_p, + singleton_p => register_application.singleton_p, + implements_subsite_p => register_application.implements_subsite_p, + inherit_templates_p => register_application.inherit_templates_p, + spec_file_path => register_application.spec_file_path, + spec_file_mtime => register_application.spec_file_mtime + ); + end register_application; + + procedure unregister_application ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 'f' + ) + is + begin + apm.unregister_package ( + package_key => unregister_application.package_key, + cascade_p => unregister_application.cascade_p + ); + end unregister_application; + + procedure register_service ( + package_key in apm_package_types.package_key%TYPE, + pretty_name in apm_package_types.pretty_name%TYPE, + pretty_plural in apm_package_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE + default 'f', + singleton_p in apm_package_types.singleton_p%TYPE + default 'f', + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default 'f', + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default 't', + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) + is + begin + apm.register_package( + package_key => register_service.package_key, + pretty_name => register_service.pretty_name, + pretty_plural => register_service.pretty_plural, + package_uri => register_service.package_uri, + package_type => 'apm_service', + initial_install_p => register_service.initial_install_p, + singleton_p => register_service.singleton_p, + implements_subsite_p => register_service.implements_subsite_p, + inherit_templates_p => register_service.inherit_templates_p, + spec_file_path => register_service.spec_file_path, + spec_file_mtime => register_service.spec_file_mtime + ); + end register_service; + + procedure unregister_service ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 'f' + ) + is + begin + apm.unregister_package ( + package_key => unregister_service.package_key, + cascade_p => unregister_service.cascade_p + ); + end unregister_service; + + -- Indicate to APM that a parameter is available to the system. + function register_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE + default null, + package_key in apm_parameters.package_key%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE, + description in apm_parameters.description%TYPE + default null, + datatype in apm_parameters.datatype%TYPE + default 'string', + default_value in apm_parameters.default_value%TYPE + default null, + section_name in apm_parameters.section_name%TYPE + default null, + min_n_values in apm_parameters.min_n_values%TYPE + default 1, + max_n_values in apm_parameters.max_n_values%TYPE + default 1 + ) return apm_parameters.parameter_id%TYPE + is + v_parameter_id apm_parameters.parameter_id%TYPE; + v_value_id apm_parameter_values.value_id%TYPE; + begin + -- Create the new parameter. + v_parameter_id := acs_object.new( + object_id => parameter_id, + object_type => 'apm_parameter', + title => register_parameter.package_key || ': Parameter ' || register_parameter.parameter_name + ); + + insert into apm_parameters + (parameter_id, parameter_name, description, package_key, datatype, + default_value, section_name, min_n_values, max_n_values) + values + (v_parameter_id, register_parameter.parameter_name, register_parameter.description, + register_parameter.package_key, register_parameter.datatype, + register_parameter.default_value, register_parameter.section_name, + register_parameter.min_n_values, register_parameter.max_n_values); + -- Propagate parameter to new instances. + for pkg in (select package_id from apm_packages where package_key = register_parameter.package_key) + loop + v_value_id := apm_parameter_value.new( + package_id => pkg.package_id, + parameter_id => v_parameter_id, + attr_value => register_parameter.default_value + ); + end loop; + return v_parameter_id; + end register_parameter; + + function update_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + default null, + description in apm_parameters.description%TYPE + default null, + datatype in apm_parameters.datatype%TYPE + default 'string', + default_value in apm_parameters.default_value%TYPE + default null, + section_name in apm_parameters.section_name%TYPE + default null, + min_n_values in apm_parameters.min_n_values%TYPE + default 1, + max_n_values in apm_parameters.max_n_values%TYPE + default 1 + ) return apm_parameters.parameter_name%TYPE + is + begin + update apm_parameters + set parameter_name = nvl(update_parameter.parameter_name, parameter_name), + default_value = nvl(update_parameter.default_value, default_value), + datatype = nvl(update_parameter.datatype, datatype), + description = nvl(update_parameter.description, description), + section_name = nvl(update_parameter.section_name, section_name), + min_n_values = nvl(update_parameter.min_n_values, min_n_values), + max_n_values = nvl(update_parameter.max_n_values, max_n_values) + where parameter_id = update_parameter.parameter_id; + + update acs_objects + set title = (select package_key || ': Parameter ' || parameter_name + from apm_parameters + where parameter_id = update_parameter.parameter_id) + where object_id = update_parameter.parameter_id; + + return parameter_id; + end; + + function parameter_p( + package_key in apm_package_types.package_key%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + ) return integer + is + v_parameter_p integer; + begin + select decode(count(*),0,0,1) into v_parameter_p + from apm_parameters + where package_key = parameter_p.package_key + and parameter_name = parameter_p.parameter_name; + return v_parameter_p; + end parameter_p; + + procedure unregister_parameter ( + parameter_id in apm_parameters.parameter_id%TYPE + default null + ) + is + begin + delete from apm_parameter_values + where parameter_id = unregister_parameter.parameter_id; + delete from apm_parameters + where parameter_id = unregister_parameter.parameter_id; + acs_object.del(parameter_id); + end unregister_parameter; + + function id_for_name ( + parameter_name in apm_parameters.parameter_name%TYPE, + package_key in apm_parameters.package_key%TYPE + ) return apm_parameters.parameter_id%TYPE + is + a_parameter_id apm_parameters.parameter_id%TYPE; + begin + select parameter_id into a_parameter_id + from apm_parameters p + where p.parameter_name = id_for_name.parameter_name and + p.package_key = id_for_name.package_key; + return a_parameter_id; + end id_for_name; + + function get_value ( + parameter_id in apm_parameter_values.parameter_id%TYPE, + package_id in apm_packages.package_id%TYPE + ) return apm_parameter_values.attr_value%TYPE + is + value apm_parameter_values.attr_value%TYPE; + begin + select attr_value into value from apm_parameter_values v + where v.package_id = get_value.package_id + and parameter_id = get_value.parameter_id; + return value; + end get_value; + + function get_value ( + package_id in apm_packages.package_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE + ) return apm_parameter_values.attr_value%TYPE + is + v_parameter_id apm_parameter_values.parameter_id%TYPE; + begin + select parameter_id into v_parameter_id + from apm_parameters + where parameter_name = get_value.parameter_name + and package_key = (select package_key from apm_packages + where package_id = get_value.package_id); + return apm.get_value( + parameter_id => v_parameter_id, + package_id => get_value.package_id + ); + end get_value; + + + -- Sets a value for a parameter for a package instance. + procedure set_value ( + parameter_id in apm_parameter_values.parameter_id%TYPE, + package_id in apm_packages.package_id%TYPE, + attr_value in apm_parameter_values.attr_value%TYPE + ) + is + v_value_id apm_parameter_values.value_id%TYPE; + begin + -- Determine if the value exists + select value_id into v_value_id from apm_parameter_values + where parameter_id = set_value.parameter_id + and package_id = set_value.package_id; + update apm_parameter_values set attr_value = set_value.attr_value + where parameter_id = set_value.parameter_id + and package_id = set_value.package_id; + exception + when NO_DATA_FOUND + then + v_value_id := apm_parameter_value.new( + package_id => set_value.package_id, + parameter_id => set_value.parameter_id, + attr_value => set_value.attr_value + ); + end set_value; + + procedure set_value ( + package_id in apm_packages.package_id%TYPE, + parameter_name in apm_parameters.parameter_name%TYPE, + attr_value in apm_parameter_values.attr_value%TYPE + ) + is + v_parameter_id apm_parameter_values.parameter_id%TYPE; + begin + select parameter_id into v_parameter_id + from apm_parameters + where parameter_name = set_value.parameter_name + and package_key = (select package_key from apm_packages + where package_id = set_value.package_id); + apm.set_value( + parameter_id => v_parameter_id, + package_id => set_value.package_id, + attr_value => set_value.attr_value + ); + exception + when NO_DATA_FOUND + then + RAISE_APPLICATION_ERROR(-20000, 'The parameter named ' || set_value.parameter_name || ' that you attempted to set does not exist AND/OR the specified package ' || set_value.package_id || ' does not exist in the system.'); + end set_value; +end apm; +/ +show errors + +create or replace package body apm_package_type +as + procedure create_type( + package_key in apm_package_types.package_key%TYPE, + pretty_name in acs_object_types.pretty_name%TYPE, + pretty_plural in acs_object_types.pretty_plural%TYPE, + package_uri in apm_package_types.package_uri%TYPE, + package_type in apm_package_types.package_type%TYPE, + initial_install_p in apm_package_types.initial_install_p%TYPE, + singleton_p in apm_package_types.singleton_p%TYPE, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE, + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE, + spec_file_path in apm_package_types.spec_file_path%TYPE default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE default null + ) + is + begin + insert into apm_package_types + (package_key, pretty_name, pretty_plural, package_uri, package_type, + spec_file_path, spec_file_mtime, initial_install_p, singleton_p, + implements_subsite_p, inherit_templates_p) + values + (create_type.package_key, create_type.pretty_name, create_type.pretty_plural, + create_type.package_uri, create_type.package_type, create_type.spec_file_path, + create_type.spec_file_mtime, create_type.initial_install_p, create_type.singleton_p, + create_type.implements_subsite_p, create_type.inherit_templates_p); + end create_type; + + function update_type( + package_key in apm_package_types.package_key%TYPE, + pretty_name in acs_object_types.pretty_name%TYPE + default null, + pretty_plural in acs_object_types.pretty_plural%TYPE + default null, + package_uri in apm_package_types.package_uri%TYPE + default null, + package_type in apm_package_types.package_type%TYPE + default null, + initial_install_p in apm_package_types.initial_install_p%TYPE + default null, + singleton_p in apm_package_types.singleton_p%TYPE + default null, + implements_subsite_p in apm_package_types.implements_subsite_p%TYPE + default null + inherit_templates_p in apm_package_types.inherit_templates_p%TYPE + default null, + spec_file_path in apm_package_types.spec_file_path%TYPE + default null, + spec_file_mtime in apm_package_types.spec_file_mtime%TYPE + default null + ) return apm_package_types.package_type%TYPE + is + begin + UPDATE apm_package_types SET + pretty_name = nvl(update_type.pretty_name, pretty_name), + pretty_plural = nvl(update_type.pretty_plural, pretty_plural), + package_uri = nvl(update_type.package_uri, package_uri), + package_type = nvl(update_type.package_type, package_type), + spec_file_path = nvl(update_type.spec_file_path, spec_file_path), + spec_file_mtime = nvl(update_type.spec_file_mtime, spec_file_mtime), + initial_install_p = nvl(update_type.initial_install_p, initial_install_p), + singleton_p = nvl(update_type.singleton_p, singleton_p), + implements_subsite_p = nvl(update_type.implements_subsite_p, implements_subsite_p), + inherits_subsite_p = nvl(update_type.implements_subsite_p, implements_subsite_p) + where package_key = update_type.package_key; + return update_type.package_key; + end update_type; + + procedure drop_type ( + package_key in apm_package_types.package_key%TYPE, + cascade_p in char default 'f' + ) + is + cursor all_package_ids is + select package_id + from apm_packages + where package_key = drop_type.package_key; + + cursor all_parameters is + select parameter_id from apm_parameters + where package_key = drop_type.package_key; + + cursor all_versions is + select version_id from apm_package_versions + where package_key = drop_type.package_key; + begin + if cascade_p = 't' then + for cur_val in all_package_ids + loop + apm_package.del( + package_id => cur_val.package_id + ); + end loop; + -- Unregister all parameters. + for cur_val in all_parameters + loop + apm.unregister_parameter(parameter_id => cur_val.parameter_id); + end loop; + + -- Unregister all versions + for cur_val in all_versions + loop + apm_package_version.del(version_id => cur_val.version_id); + end loop; + end if; + delete from apm_package_types + where package_key = drop_type.package_key; + end drop_type; + + function num_parameters ( + package_key in apm_package_types.package_key%TYPE + ) return integer + is + v_count integer; + begin + select count(*) into v_count + from apm_parameters + where package_key = num_parameters.package_key; + return v_count; + end num_parameters; + +end apm_package_type; + + +/ +show errors + +begin + insert into acs_datatypes + (datatype, max_n_values) + values + ('file', 1); +end; +/ +show errors + Index: openacs-4/packages/acs-kernel/sql/postgresql/acs-metadata-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/postgresql/acs-metadata-create.sql,v diff -u -N -r1.27 -r1.28 --- openacs-4/packages/acs-kernel/sql/postgresql/acs-metadata-create.sql 17 Sep 2007 09:43:56 -0000 1.27 +++ openacs-4/packages/acs-kernel/sql/postgresql/acs-metadata-create.sql 25 Nov 2008 17:08:49 -0000 1.28 @@ -345,6 +345,10 @@ values (''email'', null); + insert into acs_datatypes + (datatype, max_n_values) + values + (''file'', 1); return 0; end;' language 'plpgsql'; Index: openacs-4/packages/acs-kernel/sql/postgresql/apm-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/postgresql/apm-create.sql,v diff -u -N -r1.67 -r1.68 --- openacs-4/packages/acs-kernel/sql/postgresql/apm-create.sql 25 Sep 2007 15:22:35 -0000 1.67 +++ openacs-4/packages/acs-kernel/sql/postgresql/apm-create.sql 25 Nov 2008 17:08:49 -0000 1.68 @@ -32,8 +32,18 @@ check (package_type in ('apm_application', 'apm_service')), spec_file_path varchar(1500), spec_file_mtime integer, - initial_install_p boolean default 'f' not null, - singleton_p boolean default 'f' not null + initial_install_p boolean default 'f' + constraint apm_packages_in_inst_nn + not null, + singleton_p boolean default 'f' + constraint apm_packages_singleton_nn + not null, + implements_subsite_p boolean default 'f' + constraint apm_packages_impl_subs_p_nn + not null, + inherit_templates_p boolean default 't' + constraint inherit_templates_p_nn + not null ); comment on table apm_package_types is ' @@ -73,7 +83,18 @@ restricted to the acs-admin/ subsite. '; +comment on column apm_package_types.implements_subsite_p is ' + If true, this package implements subsite semantics, typically by extending the + acs-subsite package. Used by the admin "mount subsite" UI, the request processor (for + setting ad_conn''s subsite_* attributes), etc. +'; +comment on column apm_package_types.inherit_templates_p is ' + If true, inherit templates from packages this package extends. If false, only + templates in this package''s www subdirectory tree will be mapped to URLs by the + request processor. +'; + create or replace function inline_0 () returns integer as ' begin @@ -641,9 +662,11 @@ -- DCW - 2001-05-04, converted tarball storage to use content repository. create view apm_package_version_info as select v.package_key, t.package_uri, t.pretty_name, t.singleton_p, t.initial_install_p, + t.inherit_templates_p, t.implements_subsite_p, v.version_id, v.version_name, v.version_uri, v.summary, v.description_format, v.description, v.release_date, - v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, v.imported_p, v.data_model_loaded_p, + v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, + v.imported_p, v.data_model_loaded_p, v.activation_date, v.deactivation_date, coalesce(v.content_length,0) as tarball_length, distribution_uri, distribution_date @@ -972,7 +995,8 @@ constraint apm_package_deps_version_id_nn not null, dependency_type varchar(20) constraint apm_package_deps_type_nn not null - constraint apm_package_deps_type_ck check(dependency_type in ('provides','requires')), + constraint apm_package_deps_type_ck + check(dependency_type in ('extends', 'provides','requires')), service_uri varchar(1500) constraint apm_package_deps_uri_nn not null, service_version varchar(100) @@ -1069,7 +1093,7 @@ drop function inline_7 (); -create or replace function apm__register_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm__register_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns integer as ' declare package_key alias for $1; @@ -1079,8 +1103,10 @@ package_type alias for $5; initial_install_p alias for $6; -- default ''f'' singleton_p alias for $7; -- default ''f'' - spec_file_path alias for $8; -- default null - spec_file_mtime alias for $9; -- default null + implements_subsite_p alias for $8; -- default ''f'' + inherit_templates_p alias for $9; -- default ''f'' + spec_file_path alias for $10; -- default null + spec_file_mtime alias for $11; -- default null begin PERFORM apm_package_type__create_type( package_key, @@ -1090,16 +1116,17 @@ package_type, initial_install_p, singleton_p, + implements_subsite_p, + inherit_templates_p, spec_file_path, spec_file_mtime ); return 0; end;' language 'plpgsql'; - -- function update_package -create or replace function apm__update_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm__update_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns varchar as ' declare package_key alias for $1; @@ -1109,8 +1136,10 @@ package_type alias for $5; -- default null initial_install_p alias for $6; -- default null singleton_p alias for $7; -- default null - spec_file_path alias for $8; -- default null - spec_file_mtime alias for $9; -- default null + implements_subsite_p alias for $8; -- default ''f'' + inherit_templates_p alias for $9; -- default ''f'' + spec_file_path alias for $10; -- default null + spec_file_mtime alias for $11; -- default null begin return apm_package_type__update_type( @@ -1121,13 +1150,13 @@ package_type, initial_install_p, singleton_p, + implements_subsite_p, + inherit_templates_p, spec_file_path, spec_file_mtime ); - end;' language 'plpgsql'; - -- procedure unregister_package create or replace function apm__unregister_package (varchar,boolean) returns integer as ' @@ -1168,7 +1197,7 @@ -- procedure register_application -create or replace function apm__register_application (varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm__register_application (varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns integer as ' declare package_key alias for $1; @@ -1177,8 +1206,10 @@ package_uri alias for $4; initial_install_p alias for $5; -- default ''f'' singleton_p alias for $6; -- default ''f'' - spec_file_path alias for $7; -- default null - spec_file_mtime alias for $8; -- default null + implements_subsite_p alias for $7; -- default ''f'' + inherit_templates_p alias for $8; -- default ''f'' + spec_file_path alias for $9; -- default null + spec_file_mtime alias for $10; -- default null begin PERFORM apm__register_package( package_key, @@ -1188,6 +1219,8 @@ ''apm_application'', initial_install_p, singleton_p, + implements_subsite_p, + inherit_templates_p, spec_file_path, spec_file_mtime ); @@ -1220,7 +1253,7 @@ -- procedure register_service -create or replace function apm__register_service (varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm__register_service (varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns integer as ' declare package_key alias for $1; @@ -1229,8 +1262,10 @@ package_uri alias for $4; initial_install_p alias for $5; -- default ''f'' singleton_p alias for $6; -- default ''f'' - spec_file_path alias for $7; -- default null - spec_file_mtime alias for $8; -- default null + implements_subsite_p alias for $7; -- default ''f'' + inherit_templates_p alias for $8; -- default ''f'' + spec_file_path alias for $9; -- default null + spec_file_mtime alias for $10; -- default null begin PERFORM apm__register_package( package_key, @@ -1240,6 +1275,8 @@ ''apm_service'', initial_install_p, singleton_p, + implements_subsite_p, + inherit_templates_p, spec_file_path, spec_file_mtime ); @@ -1520,6 +1557,35 @@ -- create or replace package body apm_package -- procedure initialize_parameters + +create or replace function apm_package__is_child(varchar, varchar) returns boolean as ' +declare + parent_package_key alias for $1; + child_package_key alias for $2; + dependency record; +begin + + if parent_package_key = child_package_key then + return ''t''; + end if; + + for dependency in + select apd.service_uri + from apm_package_versions apv, apm_package_dependencies apd + where apd.version_id = apv.version_id + and apv.enabled_p + and apd.dependency_type = ''extends'' + and apv.package_key = child_package_key + loop + if dependency.service_uri = parent_package_key or + apm_package__is_child(parent_package_key, dependency.service_uri) then + return ''t''; + end if; + end loop; + + return ''f''; +end;' language 'plpgsql'; + create or replace function apm_package__initialize_parameters (integer,varchar) returns integer as ' declare @@ -2027,13 +2093,14 @@ -- function add_dependency -create or replace function apm_package_version__add_dependency (integer,integer,varchar,varchar) +create or replace function apm_package_version__add_dependency (varchar,integer,integer,varchar,varchar) returns integer as ' declare - add_dependency__dependency_id alias for $1; -- default null - add_dependency__version_id alias for $2; - add_dependency__dependency_uri alias for $3; - add_dependency__dependency_version alias for $4; + add_dependency__dependency_type alias for $1; + add_dependency__dependency_id alias for $2; -- default null + add_dependency__version_id alias for $3; + add_dependency__dependency_uri alias for $4; + add_dependency__dependency_version alias for $5; v_dep_id apm_package_dependencies.dependency_id%TYPE; begin if add_dependency__dependency_id is null then @@ -2045,8 +2112,8 @@ insert into apm_package_dependencies (dependency_id, version_id, dependency_type, service_uri, service_version) values - (v_dep_id, add_dependency__version_id, ''requires'', add_dependency__dependency_uri, - add_dependency__dependency_version); + (v_dep_id, add_dependency__version_id, add_dependency__dependency_type, + add_dependency__dependency_uri, add_dependency__dependency_version); return v_dep_id; @@ -2252,7 +2319,7 @@ -- create or replace package body apm_package_type -- procedure create_type -create or replace function apm_package_type__create_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm_package_type__create_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns integer as ' declare create_type__package_key alias for $1; @@ -2262,23 +2329,27 @@ create_type__package_type alias for $5; create_type__initial_install_p alias for $6; create_type__singleton_p alias for $7; - create_type__spec_file_path alias for $8; -- default null - create_type__spec_file_mtime alias for $9; -- default null + create_type__implements_subsite_p alias for $8; + create_type__inherit_templates_p alias for $9; + create_type__spec_file_path alias for $10; -- default null + create_type__spec_file_mtime alias for $11; -- default null begin insert into apm_package_types (package_key, pretty_name, pretty_plural, package_uri, package_type, - spec_file_path, spec_file_mtime, initial_install_p, singleton_p) + spec_file_path, spec_file_mtime, initial_install_p, singleton_p, + implements_subsite_p, inherit_templates_p) values (create_type__package_key, create_type__pretty_name, create_type__pretty_plural, create_type__package_uri, create_type__package_type, create_type__spec_file_path, - create_type__spec_file_mtime, create_type__initial_install_p, create_type__singleton_p); + create_type__spec_file_mtime, create_type__initial_install_p, create_type__singleton_p, + create_type__implements_subsite_p, create_type__inherit_templates_p); return 0; end;' language 'plpgsql'; -- function update_type -create or replace function apm_package_type__update_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,varchar,integer) +create or replace function apm_package_type__update_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) returns varchar as ' declare update_type__package_key alias for $1; @@ -2288,8 +2359,10 @@ update_type__package_type alias for $5; -- default null update_type__initial_install_p alias for $6; -- default null update_type__singleton_p alias for $7; -- default null - update_type__spec_file_path alias for $8; -- default null - update_type__spec_file_mtime alias for $9; -- default null + update_type__implements_subsite_p alias for $8; -- default null + update_type__inherit_templates_p alias for $9; -- default null + update_type__spec_file_path alias for $10; -- default null + update_type__spec_file_mtime alias for $11; -- default null begin UPDATE apm_package_types SET pretty_name = coalesce(update_type__pretty_name, pretty_name), @@ -2299,7 +2372,9 @@ spec_file_path = coalesce(update_type__spec_file_path, spec_file_path), spec_file_mtime = coalesce(update_type__spec_file_mtime, spec_file_mtime), singleton_p = coalesce(update_type__singleton_p, singleton_p), - initial_install_p = coalesce(update_type__initial_install_p, initial_install_p) + initial_install_p = coalesce(update_type__initial_install_p, initial_install_p), + implements_subsite_p = coalesce(update_type__implements_subsite_p, implements_subsite_p), + inherit_templates_p = coalesce(update_type__inherit_templates_p, inherit_templates_p) where package_key = update_type__package_key; return update_type__package_key; Index: openacs-4/packages/acs-kernel/sql/postgresql/upgrade/upgrade-5.5.0d3-5.5.0d4.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/sql/postgresql/upgrade/upgrade-5.5.0d3-5.5.0d4.sql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-kernel/sql/postgresql/upgrade/upgrade-5.5.0d3-5.5.0d4.sql 25 Nov 2008 17:08:49 -0000 1.1 @@ -0,0 +1,282 @@ + insert into acs_datatypes + (datatype, max_n_values) + values + ('file', 1); + +alter table apm_package_dependencies drop constraint apm_package_deps_type_ck; +alter table apm_package_dependencies add + constraint apm_package_deps_type_ck + check (dependency_type in ('provides', 'requires', 'extends')); + +-- function add_dependency +create or replace function apm_package_version__add_dependency (varchar,integer,integer,varchar,varchar) +returns integer as ' +declare + add_dependency__dependency_type alias for $1; + add_dependency__dependency_id alias for $2; -- default null + add_dependency__version_id alias for $3; + add_dependency__dependency_uri alias for $4; + add_dependency__dependency_version alias for $5; + v_dep_id apm_package_dependencies.dependency_id%TYPE; +begin + if add_dependency__dependency_id is null then + select nextval(''t_acs_object_id_seq'') into v_dep_id from dual; + else + v_dep_id := add_dependency__dependency_id; + end if; + + insert into apm_package_dependencies + (dependency_id, version_id, dependency_type, service_uri, service_version) + values + (v_dep_id, add_dependency__version_id, add_dependency__dependency_type, + add_dependency__dependency_uri, add_dependency__dependency_version); + + return v_dep_id; + +end;' language 'plpgsql'; + +alter table apm_package_types add implements_subsite_p boolean default 'f'; +update apm_package_types set implements_subsite_p = 't' where package_key = 'acs-subsite'; + +alter table apm_package_types add inherit_templates_p boolean default 't'; + +drop view apm_enabled_package_versions; +drop view apm_package_version_info; + +create or replace view apm_package_version_info as + select v.package_key, t.package_uri, t.pretty_name, t.singleton_p, t.initial_install_p, + t.inherit_templates_p, t.implements_subsite_p, + v.version_id, v.version_name, + v.version_uri, v.summary, v.description_format, v.description, v.release_date, + v.vendor, v.vendor_uri, v.auto_mount, v.enabled_p, v.installed_p, v.tagged_p, + v.imported_p, v.data_model_loaded_p, + v.activation_date, v.deactivation_date, + coalesce(v.content_length,0) as tarball_length, + distribution_uri, distribution_date + from apm_package_types t, apm_package_versions v + where v.package_key = t.package_key; + +-- A useful view for simply determining which packages are eanbled. +create view apm_enabled_package_versions as + select * from apm_package_version_info + where enabled_p = 't'; + +create or replace function apm__register_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns integer as ' +declare + package_key alias for $1; + pretty_name alias for $2; + pretty_plural alias for $3; + package_uri alias for $4; + package_type alias for $5; + initial_install_p alias for $6; -- default ''f'' + singleton_p alias for $7; -- default ''f'' + implements_subsite_p alias for $8; -- default ''f'' + inherit_templates_p alias for $9; -- default ''f'' + spec_file_path alias for $10; -- default null + spec_file_mtime alias for $11; -- default null +begin + PERFORM apm_package_type__create_type( + package_key, + pretty_name, + pretty_plural, + package_uri, + package_type, + initial_install_p, + singleton_p, + implements_subsite_p, + inherit_templates_p, + spec_file_path, + spec_file_mtime + ); + + return 0; +end;' language 'plpgsql'; + + +-- function update_package +create or replace function apm__update_package (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns varchar as ' +declare + package_key alias for $1; + pretty_name alias for $2; -- default null + pretty_plural alias for $3; -- default null + package_uri alias for $4; -- default null + package_type alias for $5; -- default null + initial_install_p alias for $6; -- default null + singleton_p alias for $7; -- default null + implements_subsite_p alias for $8; -- default ''f'' + inherit_templates_p alias for $9; -- default ''f'' + spec_file_path alias for $10; -- default null + spec_file_mtime alias for $11; -- default null +begin + + return apm_package_type__update_type( + package_key, + pretty_name, + pretty_plural, + package_uri, + package_type, + initial_install_p, + singleton_p, + implements_subsite_p, + inherit_templates_p, + spec_file_path, + spec_file_mtime + ); + +end;' language 'plpgsql'; + +create or replace function apm_package_type__create_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns integer as ' +declare + create_type__package_key alias for $1; + create_type__pretty_name alias for $2; + create_type__pretty_plural alias for $3; + create_type__package_uri alias for $4; + create_type__package_type alias for $5; + create_type__initial_install_p alias for $6; + create_type__singleton_p alias for $7; + create_type__implements_subsite_p alias for $8; + create_type__inherit_templates_p alias for $9; + create_type__spec_file_path alias for $10; -- default null + create_type__spec_file_mtime alias for $11; -- default null +begin + insert into apm_package_types + (package_key, pretty_name, pretty_plural, package_uri, package_type, + spec_file_path, spec_file_mtime, initial_install_p, singleton_p, + implements_subsite_p, inherit_templates_p) + values + (create_type__package_key, create_type__pretty_name, create_type__pretty_plural, + create_type__package_uri, create_type__package_type, create_type__spec_file_path, + create_type__spec_file_mtime, create_type__initial_install_p, create_type__singleton_p, + create_type__implements_subsite_p, create_type__inherit_templates_p); + + return 0; +end;' language 'plpgsql'; + + +-- function update_type +create or replace function apm_package_type__update_type (varchar,varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns varchar as ' +declare + update_type__package_key alias for $1; + update_type__pretty_name alias for $2; -- default null + update_type__pretty_plural alias for $3; -- default null + update_type__package_uri alias for $4; -- default null + update_type__package_type alias for $5; -- default null + update_type__initial_install_p alias for $6; -- default null + update_type__singleton_p alias for $7; -- default null + update_type__implements_subsite_p alias for $8; + update_type__inherit_templates_p alias for $9; + update_type__spec_file_path alias for $10; -- default null + update_type__spec_file_mtime alias for $11; -- default null +begin + UPDATE apm_package_types SET + pretty_name = coalesce(update_type__pretty_name, pretty_name), + pretty_plural = coalesce(update_type__pretty_plural, pretty_plural), + package_uri = coalesce(update_type__package_uri, package_uri), + package_type = coalesce(update_type__package_type, package_type), + spec_file_path = coalesce(update_type__spec_file_path, spec_file_path), + spec_file_mtime = coalesce(update_type__spec_file_mtime, spec_file_mtime), + singleton_p = coalesce(update_type__singleton_p, singleton_p), + initial_install_p = coalesce(update_type__initial_install_p, initial_install_p), + implements_subsite_p = coalesce(update_type__implements_subsite_p, implements_subsite_p), + inherit_templates_p = coalesce(update_type__inherit_templates_p, inherit_templates_p) + where package_key = update_type__package_key; + + return update_type__package_key; + +end;' language 'plpgsql'; + +-- procedure register_application +create or replace function apm__register_application (varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns integer as ' +declare + package_key alias for $1; + pretty_name alias for $2; + pretty_plural alias for $3; + package_uri alias for $4; + initial_install_p alias for $5; -- default ''f'' + singleton_p alias for $6; -- default ''f'' + implements_subsite_p alias for $7; -- default ''f'' + inherit_templates_p alias for $8; -- default ''f'' + spec_file_path alias for $9; -- default null + spec_file_mtime alias for $10; -- default null +begin + PERFORM apm__register_package( + package_key, + pretty_name, + pretty_plural, + package_uri, + ''apm_application'', + initial_install_p, + singleton_p, + implements_subsite_p, + inherit_templates_p, + spec_file_path, + spec_file_mtime + ); + + return 0; +end;' language 'plpgsql'; + +-- procedure register_service +create or replace function apm__register_service (varchar,varchar,varchar,varchar,boolean,boolean,boolean,boolean,varchar,integer) +returns integer as ' +declare + package_key alias for $1; + pretty_name alias for $2; + pretty_plural alias for $3; + package_uri alias for $4; + initial_install_p alias for $5; -- default ''f'' + singleton_p alias for $6; -- default ''f'' + implements_subsite_p alias for $7; -- default ''f'' + inherit_templates_p alias for $8; -- default ''f'' + spec_file_path alias for $9; -- default null + spec_file_mtime alias for $10; -- default null +begin + PERFORM apm__register_package( + package_key, + pretty_name, + pretty_plural, + package_uri, + ''apm_service'', + initial_install_p, + singleton_p, + implements_subsite_p, + inherit_templates_p, + spec_file_path, + spec_file_mtime + ); + + return 0; +end;' language 'plpgsql'; + +create or replace function apm_package__is_child(varchar, varchar) returns boolean as ' +declare + parent_package_key alias for $1; + child_package_key alias for $2; + dependency record; +begin + + if parent_package_key = child_package_key then + return ''t''; + end if; + + for dependency in + select apd.service_uri + from apm_package_versions apv, apm_package_dependencies apd + where apd.version_id = apv.version_id + and apv.enabled_p + and apd.dependency_type = ''extends'' + and apv.package_key = child_package_key + loop + if dependency.service_uri = parent_package_key or + apm_package__is_child(parent_package_key, dependency.service_uri) then + return ''t''; + end if; + end loop; + + return ''f''; +end;' language 'plpgsql'; Index: openacs-4/packages/acs-subsite/acs-subsite.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/acs-subsite.info,v diff -u -N -r1.99 -r1.100 --- openacs-4/packages/acs-subsite/acs-subsite.info 23 Sep 2008 19:13:59 -0000 1.99 +++ openacs-4/packages/acs-subsite/acs-subsite.info 25 Nov 2008 17:08:50 -0000 1.100 @@ -6,8 +6,9 @@ Subsite Services t f + t - + OpenACS Subsite 2008-05-31 @@ -16,7 +17,7 @@ GPL 3 - + Index: openacs-4/packages/acs-subsite/tcl/subsite-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/tcl/subsite-procs-oracle.xql,v diff -u -N -r1.7 -r1.8 --- openacs-4/packages/acs-subsite/tcl/subsite-procs-oracle.xql 7 Mar 2005 21:02:16 -0000 1.7 +++ openacs-4/packages/acs-subsite/tcl/subsite-procs-oracle.xql 25 Nov 2008 17:08:50 -0000 1.8 @@ -66,7 +66,7 @@ from apm_package_types where not (apm_package.singleton_p(package_key) = 1 and apm_package.num_instances(package_key) >= 1) - and package_key != 'acs-subsite' + and implements_subsite_p = 'f' order by upper(pretty_name) @@ -84,5 +84,20 @@ and rownum < 2 + + + + select apm_parameter_value.new( + package_id => :subsite_id, + parameter_id => ap.parameter_id, + value => ap.default_value) + from apm_parameters ap + where ap.package_key = :new_package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.package_key = :old_package_key + and ap2.parameter_name = ap.parameter_name) + + Index: openacs-4/packages/acs-subsite/tcl/subsite-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/tcl/subsite-procs-postgresql.xql,v diff -u -N -r1.9 -r1.10 --- openacs-4/packages/acs-subsite/tcl/subsite-procs-postgresql.xql 7 Mar 2005 21:02:16 -0000 1.9 +++ openacs-4/packages/acs-subsite/tcl/subsite-procs-postgresql.xql 25 Nov 2008 17:08:50 -0000 1.10 @@ -68,7 +68,7 @@ from apm_package_types where not (apm_package__singleton_p(package_key) = 1 and apm_package__num_instances(package_key) >= 1) - and package_key != 'acs-subsite' + and not implements_subsite_p order by upper(pretty_name) @@ -87,5 +87,17 @@ limit 1 - + + + + select apm_parameter_value__new(null, :subsite_id, ap.parameter_id, ap.default_value) + from apm_parameters ap + where ap.package_key = :new_package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.package_key = :old_package_key + and ap2.parameter_name = ap.parameter_name) + + + Index: openacs-4/packages/acs-subsite/tcl/subsite-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/tcl/subsite-procs.tcl,v diff -u -N -r1.41 -r1.42 --- openacs-4/packages/acs-subsite/tcl/subsite-procs.tcl 8 May 2008 01:35:58 -0000 1.41 +++ openacs-4/packages/acs-subsite/tcl/subsite-procs.tcl 25 Nov 2008 17:08:50 -0000 1.42 @@ -281,23 +281,14 @@ ad_proc -public subsite::package_keys { - {-no_cache:boolean} } { - Get the list of packages which can be subsites. + Get the list of packages which can be subsites. This is built during the + bootstrap process. If you install a new subsite-implementing package and don't + accept the installers invitation to reboot openacs, tough luck. - We return acs-subsite, and catch the query since when upgrading an existing - site we still need to know acs-subsite is a subsite. - @return the packages keys of all installed packages acting as subsites. } { - if {$no_cache_p} { - #if {[catch {set keys [db_list get_keys {}]} errMsg] || $keys eq ""} { - return {acs-subsite} - # } - return $keys - } else { - return [util_memoize "subsite::package_keys -no_cache"] - } + return [nsv_get apm_subsite_packages_list package_keys] } ad_proc -public subsite::get { @@ -849,6 +840,7 @@ ad_proc -public subsite::get_application_options {} { Gets options list for applications to install } { + set subsite_package_keys [join '[subsite::package_keys]' ","] return [db_list_of_lists package_types {}] } @@ -1070,3 +1062,76 @@ return [util_memoize [list subsite::util::packages_no_mem -node_id $subsite_node_id] 1200] } +ad_proc -public subsite::util::get_package_options { +} { + Get a list of pretty name, package key pairs for all packages which identify + themselves as implementing subsite semantics. + + @return a list of pretty name, package key pairs suitable for use in a template + select widget. +} { + return [db_list_of_lists get {}] +} + +ad_proc -public subsite::util::get_package_descendent_options { + package_key +} { + Get a list of pretty name, package key pairs for all subsite packages which are descendents + of the given package key. + + @param package_key The parent package's key. + @return a list of pretty name, package key pairs suitable for use in a template + select widget. +} { + set in_clause '[join [apm_package_descendents $package_key] ',']' + return [db_list_of_lists get {}] +} + +ad_proc -public subsite::util::convert_type { + -subsite_id + -old_package_key + -new_package_key:required +} { + Convert a subsite to a new type, doing the proper instantiate and mount callbacks and + parameter creation. + + @param subsite_id The package id of the subsite to convert (default current subsite) + @param old_package_key The package key we're converting from (default current package key) + @param new_package_key The new subsite type we're converting to (required) + +} { + if { ![info exists subsite_id] } { + set subsite_id [ad_conn subsite_id] + } + + if { ![info exists old_package_key] } { + set old_package_key [ad_conn package_key] + } + + set node_id [site_node::get_node_id_from_object_id -object_id $subsite_id] + + db_dml update_package_key {} + site_node::update_cache -node_id $node_id + + db_foreach get_params {} { + db_1row get_new_parameter_id {} + db_dml update_param {} + } + db_list copy_new_params {} + apm_parameter_sync $new_package_key $subsite_id + + foreach inherited_package_key [apm_package_inherit_order $new_package_key] { + if { [lsearch -exact [apm_package_inherit_order $old_package_key] $inherited_package_key] + == -1 } { + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type after-instantiate \ + -arg_list [list package_id $subsite_id] + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type after-mount \ + -arg_list [list node_id $node_id package_id $subsite_id] + } + } + +} Index: openacs-4/packages/acs-subsite/tcl/subsite-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/tcl/Attic/subsite-procs.xql,v diff -u -N -r1.9 -r1.10 --- openacs-4/packages/acs-subsite/tcl/subsite-procs.xql 8 May 2008 01:35:58 -0000 1.9 +++ openacs-4/packages/acs-subsite/tcl/subsite-procs.xql 25 Nov 2008 17:08:50 -0000 1.10 @@ -48,7 +48,6 @@ - @@ -115,4 +114,57 @@ + + + select pretty_name, package_key + from apm_package_types + where implements_subsite_p = 't' + order by pretty_name + + + + + + select pretty_name, package_key + from apm_package_types + where implements_subsite_p = 't' + and package_key in ($in_clause) + order by pretty_name + + + + + + update apm_packages + set package_key = :new_package_key + where package_id = :subsite_id + + + + + + select parameter_name, parameter_id + from apm_parameters + where package_key = :old_package_key + + + + + + select parameter_id as new_parameter_id + from apm_parameters + where package_key = :new_package_key + and parameter_name = :parameter_name + + + + + + update apm_parameter_values + set parameter_id = :new_parameter_id + where parameter_id = :parameter_id + and package_id = :subsite_id + + + Index: openacs-4/packages/acs-subsite/www/admin/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/www/admin/index.adp,v diff -u -N -r1.25 -r1.26 --- openacs-4/packages/acs-subsite/www/admin/index.adp 11 May 2008 23:08:13 -0000 1.25 +++ openacs-4/packages/acs-subsite/www/admin/index.adp 25 Nov 2008 17:08:50 -0000 1.26 @@ -9,6 +9,9 @@
  • Members
  • Parameters
  • Create new subsite + +
  • Convert to descendent subsite type +

    Advanced Features

    Index: openacs-4/packages/acs-subsite/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/www/admin/index.tcl,v diff -u -N -r1.16 -r1.17 --- openacs-4/packages/acs-subsite/www/admin/index.tcl 11 May 2008 00:08:56 -0000 1.16 +++ openacs-4/packages/acs-subsite/www/admin/index.tcl 25 Nov 2008 17:08:50 -0000 1.17 @@ -24,11 +24,4 @@ set acs_admin_name $acs_admin_node(instance_name) set sw_admin_p [permission::permission_p -party_id [ad_conn user_id] -object_id $acs_admin_node(object_id) -privilege admin] - - - - - - - - +set convert_subsite_p [expr { [llength [subsite::util::get_package_descendent_options [ad_conn package_key]]] > 0 }] Index: openacs-4/packages/acs-subsite/www/admin/subsite-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/www/admin/subsite-add.tcl,v diff -u -N -r1.11 -r1.12 --- openacs-4/packages/acs-subsite/www/admin/subsite-add.tcl 8 May 2008 01:35:58 -0000 1.11 +++ openacs-4/packages/acs-subsite/www/admin/subsite-add.tcl 25 Nov 2008 17:08:50 -0000 1.12 @@ -14,9 +14,28 @@ set context [list $page_title] - ad_form -name subsite -cancel_url . -form { - {node_id:key} + {node_id:key}} + +set subsite_package_options [subsite::util::get_package_options] + +if { [llength $subsite_package_options] == 1 } { + ad_form -extend -name subsite -form { + {package_key:text(hidden) + {value "[lindex [lindex $subsite_package_options 0] 1]"} + } + } +} else { + ad_form -extend -name subsite -form { + {package_key:text(select) + {label "Subsite Package"} + {help_text "Choose the subsite package you'd like to mount"} + {options $subsite_package_options} + } + } +} + +ad_form -extend -name subsite -form { {instance_name:text {label $subsite_pretty_name} {help_text "The name of the new subsite you're setting up."} @@ -58,7 +77,7 @@ -parent_node_id [ad_conn node_id] \ -node_name $folder \ -package_name $instance_name \ - -package_key acs-subsite] + -package_key $package_key] # Set template subsite::set_theme -subsite_id $new_package_id -theme $theme Index: openacs-4/packages/acs-subsite/www/shared/parameters-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/www/shared/Attic/parameters-oracle.xql,v diff -u -N -r1.3 -r1.4 --- openacs-4/packages/acs-subsite/www/shared/parameters-oracle.xql 25 Sep 2007 15:22:38 -0000 1.3 +++ openacs-4/packages/acs-subsite/www/shared/parameters-oracle.xql 25 Nov 2008 17:08:50 -0000 1.4 @@ -17,7 +17,7 @@ from apm_parameter_values v where v.package_id = :package_id ) v - where p.package_key = (select package_key from apm_packages where package_id = :package_id) + where p.package_key = :package_key and p.parameter_id = v.parameter_id $section_where_clause order by section_name, parameter_name @@ -35,7 +35,7 @@ from apm_parameter_values v where v.package_id = :package_id ) v - where p.package_key = (select package_key from apm_packages where package_id = :package_id) + where p.package_key = :package_key and p.parameter_id = v.parameter_id $section_where_clause Index: openacs-4/packages/acs-subsite/www/shared/parameters-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/www/shared/Attic/parameters-postgresql.xql,v diff -u -N -r1.3 -r1.4 --- openacs-4/packages/acs-subsite/www/shared/parameters-postgresql.xql 25 Sep 2007 15:22:38 -0000 1.3 +++ openacs-4/packages/acs-subsite/www/shared/parameters-postgresql.xql 25 Nov 2008 17:08:50 -0000 1.4 @@ -17,7 +17,7 @@ from apm_parameter_values v where v.package_id = :package_id ) v on p.parameter_id = v.parameter_id - where p.package_key = (select package_key from apm_packages where package_id = :package_id) + where p.package_key = :package_key $section_where_clause order by section_name, parameter_name @@ -35,7 +35,7 @@ from apm_parameter_values v where v.package_id = :package_id ) v on p.parameter_id = v.parameter_id - where p.package_key = (select package_key from apm_packages where package_id = :package_id) + where p.package_key = :package_key $section_where_clause Index: openacs-4/packages/acs-tcl/tcl/apm-install-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-install-procs-oracle.xql,v diff -u -N -r1.10 -r1.11 --- openacs-4/packages/acs-tcl/tcl/apm-install-procs-oracle.xql 12 Jul 2004 11:12:38 -0000 1.10 +++ openacs-4/packages/acs-tcl/tcl/apm-install-procs-oracle.xql 25 Nov 2008 17:08:49 -0000 1.11 @@ -124,6 +124,8 @@ pretty_plural => :pretty_plural, initial_install_p => :initial_install_p, singleton_p => :singleton_p, + implements_subsite_p => :implements_subsite_p, + inherit_templates_p => :inherit_templates_p, spec_file_path => :spec_file_path, spec_file_mtime => :spec_file_mtime ); @@ -144,6 +146,8 @@ pretty_plural => :pretty_plural, initial_install_p => :initial_install_p, singleton_p => :singleton_p, + implements_subsite_p => :implements_subsite_p, + inherit_templates_p => :inherit_templates_p, spec_file_path => :spec_file_path, spec_file_mtime => :spec_file_mtime ); @@ -244,6 +248,51 @@ + + + select apm.register_parameter( + parameter_name => ap.parameter_name, + package_key => :descendent_package_key, + description => ap.description, + datatype => ap.datatype, + default_value => ap.default_value, + section_name => qp.section_name, + min_n_values => ap.min_n_values, + max_n_values => ap.max_n_values) + from apm_parameters ap + where package_key = :package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.parameter_name = ap.parameter_name + and ap2.package_key = :descendent_package_key) + + + + + + + select apm.register_parameter( + parameter_name => ap.parameter_name, + package_key => :package_key, + description => ap.description, + datatype => ap.datatype, + default_value => ap.default_value, + section_name => qp.section_name, + min_n_values => ap.min_n_values, + max_n_values => ap.max_n_values) + from apm_parameters ap + where package_key = :inherited_package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.parameter_name = ap.parameter_name + and ap2.package_key = :package_key) + + + + + + + Index: openacs-4/packages/acs-tcl/tcl/apm-install-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-install-procs-postgresql.xql,v diff -u -N -r1.14 -r1.15 --- openacs-4/packages/acs-tcl/tcl/apm-install-procs-postgresql.xql 12 Jul 2004 11:12:38 -0000 1.14 +++ openacs-4/packages/acs-tcl/tcl/apm-install-procs-postgresql.xql 25 Nov 2008 17:08:49 -0000 1.15 @@ -77,6 +77,8 @@ :package_uri, :initial_install_p, :singleton_p, + :implements_subsite_p, + :inherit_templates_p, :spec_file_path, :spec_file_mtime ); @@ -95,6 +97,8 @@ :package_uri, :initial_install_p, :singleton_p, + :implements_subsite_p, + :inherit_templates_p, :spec_file_path, :spec_file_mtime ); @@ -185,6 +189,34 @@ + + + select apm__register_parameter(null, :descendent_package_key, ap.parameter_name, + ap.description, ap.datatype, ap.default_value, + ap.section_name, ap.min_n_values, ap.max_n_values) + from apm_parameters ap + where package_key = :package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.parameter_name = ap.parameter_name + and ap2.package_key = :descendent_package_key) + + + + + + select apm__register_parameter(null, :package_key, ap.parameter_name, ap.description, + ap.datatype, ap.default_value, ap.section_name, + ap.min_n_values, ap.max_n_values) + from apm_parameters ap + where package_key = :inherited_package_key + and not exists (select 1 + from apm_parameters ap2 + where ap2.parameter_name = ap.parameter_name + and ap2.package_key = :package_key) + + + Index: openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl,v diff -u -N -r1.91 -r1.92 --- openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl 29 Jul 2008 19:22:23 -0000 1.91 +++ openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl 25 Nov 2008 17:08:49 -0000 1.92 @@ -124,19 +124,20 @@ } } -ad_proc -private pkg_info_new { package_key spec_file_path provides requires {dependency_p ""} {comment ""}} { +ad_proc -private pkg_info_new { package_key spec_file_path extends provides requires {dependency_p ""} {comment ""}} { Returns a datastructure that maintains information about a package. @param package_key The key of the package. @param spec_file_path The path to the package specification file + @param extends A list of packages extended by the package.. @param provides A list of dependencies provided by the package. @param requires A list of requirements provided by the package.. @param dependency_p Can the package be installed without violating dependency checking. @param comment Some text about the package. Useful to explain why it fails dependency check. @return a list whose first element is a package key and whose second element is a path to the associated .info file. } { - return [list $package_key $spec_file_path $provides $requires $dependency_p $comment] + return [list $package_key $spec_file_path $extends $provides $requires $dependency_p $comment] } ad_proc -private pkg_info_key {pkg_info} { @@ -166,36 +167,44 @@ return [file dirname [pkg_info_spec $pkg_info]] } -ad_proc -private pkg_info_provides {pkg_info} { +ad_proc -private pkg_info_extends {pkg_info} { @return The dependencies provided by the package. } { return [lindex $pkg_info 2] } +ad_proc -private pkg_info_provides {pkg_info} { + + @return The dependencies provided by the package. + +} { + return [lindex $pkg_info 3] +} + ad_proc -private pkg_info_requires {pkg_info} { @return The dependencies required by the package info map. } { - return [lindex $pkg_info 3] + return [lindex $pkg_info 4] } ad_proc -private pkg_info_dependency_p {pkg_info} { @return Does it pass the dependency checker? "" Means it has not been run yet. } { - return [lindex $pkg_info 4] + return [lindex $pkg_info 5] } ad_proc -private pkg_info_comment {pkg_info} { @return Any comment specified about this package. } { - return [lindex $pkg_info 5] + return [lindex $pkg_info 6] } # DRB: This routine does more than check dependencies, it also parses spec files, @@ -245,7 +254,7 @@ array set package [apm_read_package_info_file $spec_file] if { ([string equal $package(initial-install-p) "t"] || !$initial_install_p) && \ [apm_package_supports_rdbms_p -package_key $package(package.key)] } { - lappend install_pend [pkg_info_new $package(package.key) $spec_file $package(provides) $package(requires) ""] + lappend install_pend [pkg_info_new $package(package.key) $spec_file $package(extends) $package(provides) $package(requires) ""] } # Remove this package from the pkg_info_all list ... @@ -284,7 +293,7 @@ # Now determine if we can add another package to the install set. foreach pkg_info $install_pend { set satisfied_p 1 - foreach req [pkg_info_requires $pkg_info] { + foreach req [concat [pkg_info_extends $pkg_info] [pkg_info_requires $pkg_info]] { if {[apm_dependency_provided_p -dependency_list $install_in_provides \ [lindex $req 0] [lindex $req 1]] != 1} { # Unsatisfied dependency. @@ -302,7 +311,7 @@ if { $satisfied_p } { # At least one more package was added to the list that can be installed, so repeat. lappend install_in [pkg_info_new [pkg_info_key $pkg_info] [pkg_info_spec $pkg_info] \ - [pkg_info_provides $pkg_info] [pkg_info_requires $pkg_info] \ + [pkg_info_extends $pkg_info] [pkg_info_provides $pkg_info] [pkg_info_requires $pkg_info] \ "t" "Package satisfies dependencies."] set updated_p 1 } @@ -362,7 +371,8 @@ if { [exists_and_not_null install_pend] } { foreach pkg_info $install_pend { lappend install_in [pkg_info_new [pkg_info_key $pkg_info] [pkg_info_spec $pkg_info] \ - [pkg_info_provides $pkg_info] [pkg_info_requires $pkg_info] \ + [pkg_info_extends $pkg_info] [pkg_info_provides $pkg_info] \ + [pkg_info_requires $pkg_info] \ "f" $install_error([pkg_info_key $pkg_info])] } return [list 0 $install_in] @@ -460,14 +470,14 @@ array set version $repository($package_key) set satisfied_p 1 - foreach req $version(requires) { + foreach req [concat $version(extends) $version(requires)] { set req_uri [lindex $req 0] set req_version [lindex $req 1] if { ![info exists provided($req_uri)] || \ [apm_version_names_compare $provided($req_uri) $req_version]== -1 } { - ns_log Debug "apm_dependency_check_new: $package_key requires $req_uri $req_version => failed" + ns_log Debug "apm_dependency_check_new: $package_key extends or requires $req_uri $req_version => failed" set satisfied_p 0 @@ -477,7 +487,7 @@ set required($req_uri) $req_version } } else { - ns_log Debug "apm_dependency_check_new: $package_key requires $req_uri $req_version => OK" + ns_log Debug "apm_dependency_check_new: $package_key extends or requires $req_uri $req_version => OK" } } @@ -589,16 +599,16 @@ lappend result(packages) $package_key # Find unsatisfied requirements - foreach req $version(requires) { + foreach req [concat $version(extends) $version(requires)] { set req_uri [lindex $req 0] set req_version [lindex $req 1] if { ![info exists provided($req_uri)] || \ [apm_version_names_compare $provided($req_uri) $req_version] == -1 } { lappend failed($package_key) [list $req_uri $req_version] if { [info exists provided($req_uri)] } { - ns_log Debug "apm_dependency_check_new: Failed dependency: $package_key requires $req_uri $req_version, but we only provide $provided($req_uri)" + ns_log Debug "apm_dependency_check_new: Failed dependency: $package_key extends/requires $req_uri $req_version, but we only provide $provided($req_uri)" } else { - ns_log Debug "apm_dependency_check_new: Failed dependency: $package_key requires $req_uri $req_version, but we don't have it" + ns_log Debug "apm_dependency_check_new: Failed dependency: $package_key extends/requires $req_uri $req_version, but we don't have it" } } } @@ -684,6 +694,8 @@ set pretty_plural $version(pretty-plural) set initial_install_p $version(initial-install-p) set singleton_p $version(singleton-p) + set implements_subsite_p $version(implements-subsite-p) + set inherit_templates_p $version(inherit-templates-p) set auto_mount $version(auto-mount) set version_name $version(name) set version_uri $version(url) @@ -706,7 +718,9 @@ $package_uri \ $package_type \ $initial_install_p \ - $singleton_p + $singleton_p \ + $implements_subsite_p \ + $inherit_templates_p } # Source Tcl procs and queries to be able @@ -786,10 +800,22 @@ } # Update all other package information. - apm_package_install_dependencies -callback $callback $version(provides) $version(requires) $version_id + apm_package_install_dependencies -callback $callback \ + $version(extends) $version(provides) $version(requires) $version_id apm_package_install_owners -callback $callback $version(owners) $version_id apm_package_install_callbacks -callback $callback $version(callbacks) $version_id + apm_build_one_package_relationships $package_key + if { $upgrade_p } { + foreach descendent_package_key [nsv_get apm_package_descendents $package_key] { + db_list copy_descendent_params {} + } + } else { + foreach inherited_package_key [nsv_get apm_package_inherit_order $package_key] { + db_list copy_inherited_params {} + } + } + apm_callback_and_log $callback "

    Installed $version(package-name), version $version(name).

    " } { global errorInfo @@ -1199,7 +1225,7 @@ } } -ad_proc -private apm_package_install_dependencies { {-callback apm_dummy_callback} provides requires version_id} { +ad_proc -private apm_package_install_dependencies { {-callback apm_dummy_callback} extends provides requires version_id} { Install all package dependencies. @@ -1222,11 +1248,18 @@ apm_interface_add $version_id $interface_uri $interface_version } + foreach item $extends { + set dependency_uri [lindex $item 0] + set dependency_version [lindex $item 1] + ns_log Debug "apm_package_install_dependencies: Registering dependency $dependency_uri, $dependency_version for $version_id" + apm_dependency_add extends $version_id $dependency_uri $dependency_version + } + foreach item $requires { set dependency_uri [lindex $item 0] set dependency_version [lindex $item 1] ns_log Debug "apm_package_install_dependencies: Registering dependency $dependency_uri, $dependency_version for $version_id" - apm_dependency_add $version_id $dependency_uri $dependency_version + apm_dependency_add requires $version_id $dependency_uri $dependency_version } } @@ -1382,6 +1415,8 @@ package_type initial_install_p singleton_p + implements_subsite_p + inherit_templates_p } { Register the package in the system. } { @@ -2252,7 +2287,7 @@ if { ![regexp {^-?[0-9]+$} $maturity] } { set error_message "Maturity must be integer" } elseif { [expr {$maturity < -1 || $maturity > 3}] } { - set error_message "Matuirity must be integer between -1 and 3" + set error_message "Maturity must be integer between -1 and 3" } } Index: openacs-4/packages/acs-tcl/tcl/apm-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-procs-oracle.xql,v diff -u -N -r1.13 -r1.14 --- openacs-4/packages/acs-tcl/tcl/apm-procs-oracle.xql 16 Jun 2004 01:34:24 -0000 1.13 +++ openacs-4/packages/acs-tcl/tcl/apm-procs-oracle.xql 25 Nov 2008 17:08:49 -0000 1.14 @@ -80,6 +80,7 @@ begin :1 := apm_package_version.add_dependency( + dependency_type => :dependency_type, dependency_id => :dependency_id, version_id => :version_id, dependency_uri => :dependency_uri, Index: openacs-4/packages/acs-tcl/tcl/apm-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-procs-postgresql.xql,v diff -u -N -r1.14 -r1.15 --- openacs-4/packages/acs-tcl/tcl/apm-procs-postgresql.xql 1 Apr 2004 20:56:29 -0000 1.14 +++ openacs-4/packages/acs-tcl/tcl/apm-procs-postgresql.xql 25 Nov 2008 17:08:50 -0000 1.15 @@ -59,6 +59,7 @@ select apm_package_version__add_dependency( + :dependency_type, :dependency_id, :version_id, :dependency_uri, Index: openacs-4/packages/acs-tcl/tcl/apm-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-procs.tcl,v diff -u -N -r1.79 -r1.80 --- openacs-4/packages/acs-tcl/tcl/apm-procs.tcl 27 Jun 2007 23:35:35 -0000 1.79 +++ openacs-4/packages/acs-tcl/tcl/apm-procs.tcl 25 Nov 2008 17:08:50 -0000 1.80 @@ -138,7 +138,166 @@ ns_log $severity $message } +ad_proc apm_one_package_descendents { + package_key +} { + global apm_visited_package_keys + global apm_package_descendents + foreach descendent [db_list get_descendents {}] { + if { [info exists apm_visited_package_keys($descendent)] } { + continue + } + set apm_visited_package_keys($descendent) 1 + lappend apm_package_descendents $descendent + apm_one_package_descendents $descendent + } + +} + +ad_proc apm_build_subsite_packages_list {} { + + nsv_set apm_subsite_packages_list package_keys {} + + # Make sure old versions work ... + catch { nsv_set apm_subsite_packages_list package_keys [db_list get_subsites {}] } + if { [lsearch -exact [nsv_get apm_subsite_packages_list package_keys] acs-subsite] == -1 } { + nsv_lappend apm_subsite_packages_list package_keys acs-subsite + } + +} + +ad_proc apm_package_list_search_order { + package_list +} { + Left-right, breadth-first traverse of the inheritance DAG. +} { + global apm_visited_package_keys + global apm_package_search_order + + foreach package_key $package_list { + if { [info exists apm_visited_package_keys($package_key)] } { + continue + } + lappend apm_package_search_order $package_key + set apm_visited_package_keys($package_key) 1 + } + + # Make sure old versions work ... + foreach package_key $package_list { + set inherit_templates_p 1 + catch { db_1row get_inherit_templates_p {} } + if { [string is true $inherit_templates_p] } { + apm_package_list_search_order [db_list get_dependencies {}] + } + } +} + +ad_proc apm_one_package_inherit_order { + package_key +} { + global apm_visited_package_keys + global apm_package_inherit_order + + if { [info exists apm_visited_package_keys($package_key)] } { + return + } + set apm_visited_package_keys($package_key) 1 + + foreach dependency [db_list get_dependencies {}] { + apm_one_package_inherit_order $dependency + } + + lappend apm_package_inherit_order $package_key +} + +ad_proc apm_one_package_load_libraries_dependencies { + package_key +} { + global apm_visited_package_keys + global apm_package_load_libraries_order + + if { [info exists apm_visited_package_keys($package_key)] } { + return + } + set apm_visited_package_keys($package_key) 1 + set package_key_list "" + + foreach dependency [db_list get_dependencies {}] { + apm_one_package_load_libraries_dependencies $dependency + } + lappend apm_package_load_libraries_order $package_key +} + +ad_proc apm_build_one_package_relationships { + package_key +} { + + Builds the nsv dependency structures for a single package. + +} { + global apm_visited_package_keys + global apm_package_search_order + global apm_package_inherit_order + global apm_package_load_libraries_order + global apm_package_descendents + + array unset apm_visited_package_keys + set apm_package_search_order [list] + apm_package_list_search_order $package_key + nsv_set apm_package_search_order $package_key $apm_package_search_order + + array unset apm_visited_package_keys + set apm_package_inherit_order [list] + apm_one_package_inherit_order $package_key + nsv_set apm_package_inherit_order $package_key $apm_package_inherit_order + + array unset apm_visited_package_keys + set apm_package_load_libraries_order [list] + apm_one_package_load_libraries_dependencies $package_key + nsv_set apm_package_load_libraries_order $package_key $apm_package_load_libraries_order + + array unset apm_visited_package_keys + set apm_package_descendents [list] + apm_one_package_descendents $package_key + nsv_set apm_package_descendents $package_key $apm_package_descendents + +} + +ad_proc apm_build_package_relationships {} { + + Builds the nsv dependency and ancestor structures. + +} { + foreach package_key [apm_enabled_packages] { + apm_build_one_package_relationships $package_key + } +} + +ad_proc apm_package_descendents { + package_key +} { + return [nsv_get apm_package_descendents $package_key] +} + +ad_proc apm_package_inherit_order { + package_key +} { + return [nsv_get apm_package_inherit_order $package_key] +} + +ad_proc apm_package_search_order { + package_key +} { + return [nsv_get apm_package_search_order $package_key] +} + +ad_proc apm_package_load_libraries_order { + package_key +} { + return [nsv_get apm_package_load_libraries_order $package_key] +} + ad_proc -public apm_version_loaded_p { version_id } { Returns 1 if a version of a package has been loaded and initialized, or 0 otherwise. @@ -852,7 +1011,7 @@ { -callback apm_dummy_callback -dependency_id "" - } version_id dependency_uri dependency_version + } dependency_type version_id dependency_uri dependency_version } { Add a dependency to a version. @@ -863,17 +1022,7 @@ set dependency_id [db_null] } - return [db_exec_plsql dependency_add { - begin - :1 := apm_package_version.add_dependency( - dependency_id => :dependency_id, - version_id => :version_id, - dependency_uri => :dependency_uri, - dependency_version => :dependency_version - ); - end; - }] -} + return [db_exec_plsql dependency_add {}] } ad_proc -public apm_dependency_remove {dependency_id} { @@ -1536,7 +1685,12 @@ apm_parameter_sync $package_key $package_id - apm_invoke_callback_proc -package_key $package_key -type "after-instantiate" -arg_list [list package_id $package_id] + foreach inherited_package_key [nsv_get apm_package_inherit_order $package_key] { + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type after-instantiate \ + -arg_list [list package_id $package_id] + } return $package_id } @@ -1568,10 +1722,15 @@ } { Deletes an instance of a package } { - apm_invoke_callback_proc -package_key [apm_package_key_from_id $package_id] \ - -type before-uninstantiate \ - -arg_list [list package_id $package_id] + set package_key [apm_package_key_from_id $package_id] + foreach inherited_package_key [nsv_get apm_package_inherit_order $package_key] { + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type before-uninstantiate \ + -arg_list [list package_id $package_id] + } + db_exec_plsql apm_package_instance_delete {} } Index: openacs-4/packages/acs-tcl/tcl/apm-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-procs.xql,v diff -u -N -r1.23 -r1.24 --- openacs-4/packages/acs-tcl/tcl/apm-procs.xql 29 Aug 2007 13:53:40 -0000 1.23 +++ openacs-4/packages/acs-tcl/tcl/apm-procs.xql 25 Nov 2008 17:08:50 -0000 1.24 @@ -1,6 +1,69 @@ + + + select apv.package_key + from apm_package_versions apv, apm_package_dependencies apd + where apd.version_id = apv.version_id + and apv.enabled_p = 't' + and apd.dependency_type = 'extends' + and apd.service_uri = :package_key + + + + + + select package_key + from apm_package_types + where implements_subsite_p = 't' + + + + + + select inherit_templates_p + from apm_package_types + where package_key = :package_key + + + + + + select apd.service_uri + from apm_package_versions apv, apm_package_dependencies apd + where apv.package_key = :package_key + and apv.installed_p = 't' + and apd.version_id = apv.version_id + and apd.dependency_type = 'extends' + order by apd.dependency_id + + + + + + select apd.service_uri + from apm_package_versions apv, apm_package_dependencies apd + where apv.package_key = :package_key + and apv.installed_p = 't' + and apd.version_id = apv.version_id + and apd.dependency_type = 'extends' + order by apd.dependency_id desc + + + + + + select apd.service_uri + from apm_package_versions apv, apm_package_dependencies apd + where apv.package_key = :package_key + and apv.installed_p = 't' + and apd.version_id = apv.version_id + and apd.dependency_type in ('requires', 'extends') + order by apd.dependency_id desc + + + select case when count(*) = 0 then 0 else 1 end from apm_package_versions Index: openacs-4/packages/acs-tcl/tcl/apm-xml-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-xml-procs.tcl,v diff -u -N -r1.26 -r1.27 --- openacs-4/packages/acs-tcl/tcl/apm-xml-procs.tcl 10 Jan 2007 21:22:12 -0000 1.26 +++ openacs-4/packages/acs-tcl/tcl/apm-xml-procs.tcl 25 Nov 2008 17:08:50 -0000 1.27 @@ -72,6 +72,8 @@ [ad_quotehtml $pretty_plural] $initial_install_p $singleton_p + $implements_subsite_p + $inherit_templates_p ${auto_mount_tag} \n" @@ -167,8 +169,9 @@
    • path: a path to the file read
    • mtime: the mtime of the file read -
    • provides and requires: lists of dependency - information, containing elements of the form [list $url $version] +
    • provides, extends, and requires: + lists of dependency information, containing elements of the form + [list $url $version]
    • owners: a list of owners containing elements of the form [list $url $name]
    • files: a list of files in the package, @@ -255,8 +258,10 @@ set properties(package.type) [apm_attribute_value -default "apm_application" $package type] set properties(package-name) [apm_tag_value $package package-name] set properties(initial-install-p) [apm_tag_value -default "f" $package initial-install-p] - set properties(singleton-p) [apm_tag_value -default "f" $package singleton-p] set properties(auto-mount) [apm_tag_value -default "" $package auto-mount] + set properties(singleton-p) [apm_tag_value -default "f" $package singleton-p] + set properties(implements-subsite-p) [apm_tag_value -default "f" $package implements-subsite-p] + set properties(inherit-templates-p) [apm_tag_value -default "t" $package inherit-templates-p] set properties(pretty-plural) [apm_tag_value -default "$properties(package-name)s" $package pretty-plural] @@ -306,8 +311,9 @@ set properties(provides) [list] set properties(requires) [list] + set properties(extends) [list] - foreach dependency_type { provides requires } { + foreach dependency_type { provides requires extends } { set dependency_types [xml_node_get_children_by_name $version $dependency_type] foreach node $dependency_types { Index: openacs-4/packages/acs-tcl/tcl/apm-xml-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-xml-procs.xql,v diff -u -N -r1.7 -r1.8 --- openacs-4/packages/acs-tcl/tcl/apm-xml-procs.xql 24 Sep 2003 17:51:24 -0000 1.7 +++ openacs-4/packages/acs-tcl/tcl/apm-xml-procs.xql 25 Nov 2008 17:08:50 -0000 1.8 @@ -11,6 +11,8 @@ t.package_type, t.initial_install_p, t.singleton_p, + t.implements_subsite_p, + t.inherit_templates_p, v.* from apm_package_versions v, apm_package_types t Index: openacs-4/packages/acs-tcl/tcl/install-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/install-procs.tcl,v diff -u -N -r1.24 -r1.25 --- openacs-4/packages/acs-tcl/tcl/install-procs.tcl 15 Nov 2008 17:13:03 -0000 1.24 +++ openacs-4/packages/acs-tcl/tcl/install-procs.tcl 25 Nov 2008 17:08:50 -0000 1.25 @@ -118,6 +118,7 @@ } lappend pkg_info_list [pkg_info_new $package(package.key) \ $spec_file \ + $package(extends) \ $package(provides) \ $package(requires)] } Index: openacs-4/packages/acs-tcl/tcl/request-processor-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/request-processor-procs.tcl,v diff -u -N -r1.95 -r1.96 --- openacs-4/packages/acs-tcl/tcl/request-processor-procs.tcl 5 Nov 2008 09:50:21 -0000 1.95 +++ openacs-4/packages/acs-tcl/tcl/request-processor-procs.tcl 25 Nov 2008 17:08:50 -0000 1.96 @@ -851,7 +851,9 @@ set roots [ns_info pageroot][string trimright [ad_conn package_url] /] if { [ad_conn package_key] ne "" } { - lappend roots [acs_root_dir]/packages/[ad_conn package_key]/www + foreach package_key [apm_package_search_order [ad_conn package_key]] { + lappend roots [acs_root_dir]/packages/$package_key/www + } } foreach root $roots { Index: openacs-4/packages/acs-tcl/tcl/site-nodes-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/site-nodes-procs.tcl,v diff -u -N -r1.83 -r1.84 --- openacs-4/packages/acs-tcl/tcl/site-nodes-procs.tcl 11 Apr 2008 22:37:12 -0000 1.83 +++ openacs-4/packages/acs-tcl/tcl/site-nodes-procs.tcl 25 Nov 2008 17:08:50 -0000 1.84 @@ -142,7 +142,13 @@ db_dml update_package_context_id "" } - apm_invoke_callback_proc -package_key [apm_package_key_from_id $object_id] -type "after-mount" -arg_list [list node_id $node_id package_id $object_id] + set package_key [apm_package_key_from_id $object_id] + foreach inherited_package_key [nsv_get apm_package_inherit_order $package_key] { + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type after-mount \ + -arg_list [list package_id $package_id node_id $node_id] + } } @@ -242,8 +248,15 @@ unmount an object from the site node } { set package_id [get_object_id -node_id $node_id] - apm_invoke_callback_proc -package_key [apm_package_key_from_id $package_id] -type before-unmount -arg_list [list package_id $package_id node_id $node_id] + set package_key [apm_package_key_from_id $package_id] + foreach inherited_package_key [nsv_get apm_package_inherit_order $package_key] { + apm_invoke_callback_proc \ + -package_key $inherited_package_key \ + -type before-unmount \ + -arg_list [list package_id $package_id node_id $node_id] + } + db_dml unmount_object {} db_dml update_object_package_id {} update_cache -node_id $node_id