relation-procs.tcl
Does not contain a contract.
- Location:
- /packages/acs-subsite/tcl/relation-procs.tcl
Related Files
- packages/acs-subsite/tcl/relation-procs.xql
- packages/acs-subsite/tcl/relation-procs.tcl
- packages/acs-subsite/tcl/relation-procs-postgresql.xql
- packages/acs-subsite/tcl/relation-procs-oracle.xql
[ hide source ] | [ make this the default ]
File Contents
ad_library { Helpers for dealing with relations @author mbryzek@arsdigita.com @creation-date Sun Dec 10 16:46:11 2000 @cvs-id $Id: relation-procs.tcl,v 1.20.2.2 2019/05/16 09:27:52 gustafn Exp $ } namespace eval relation {} d_proc -deprecated -public relation_permission_p { { -user_id "" } { -privilege "read" } rel_id } { Wrapper for ad_permission_p that lets us default to read permission Deprecated: just another wrapper for permission::permission_p @author Michael Bryzek (mbryzek@arsdigita.com) @creation-date 12/2000 @see permission::permission_p } { return [permission::permission_p -party_id $user_id -object_id $rel_id -privilege $privilege] } d_proc -public relation_add { { -form_id "" } { -extra_vars "" } { -variable_prefix "" } { -creation_user "" } { -creation_ip "" } { -member_state "" } rel_type object_id_one object_id_two } { Creates a new relation of the specified type between the two objects. Throws an error if the new relation violates a relational constraint. @author Michael Bryzek (mbryzek@arsdigita.com) @author Ben Adida (ben@openforce.net) @creation-date 1/5/2001 @param form_id The form id from templating form system @param extra_vars An ns_set of extra variables @param variable_prefix Only form elements that begin with the specified prefix will be processed. @param creation_user The user who is creating the relation @param creation_ip @param member_state Only used for membership_relations. See column membership_rels.member_state for more info. @return The <code>rel_id</code> of the new relation } { # First check if the relation already exists, and if so, just return that set existing_rel_id [db_string rel_exists { select rel_id from acs_rels where rel_type = :rel_type and object_id_one = :object_id_one and object_id_two = :object_id_two } -default {}] if { $existing_rel_id ne "" } { return $existing_rel_id } set var_list [list \ [list object_id_one $object_id_one] \ [list object_id_two $object_id_two]] # Note that we don't explicitly check whether rel_type is a type of # membership relation before adding the member_state variable. The # package_instantiate_object proc will ignore the member_state variable # if the rel_type's plsql package doesn't support it. if {$member_state ne ""} { lappend var_list [list member_state $member_state] } # We initialize rel_id, so it's set if there's a problem set rel_id {} # We use db_transaction inside this proc to roll back the insert # in case of a violation db_transaction { set rel_id [package_instantiate_object \ -creation_user $creation_user \ -creation_ip $creation_ip \ -start_with "relationship" \ -form_id $form_id \ -extra_vars $extra_vars \ -variable_prefix $variable_prefix \ -var_list $var_list \ $rel_type] # Check to see if constraints are violated because of this new # relation # JCD: this is enforced by trigger so no longer check explicitly # see membership_rels_in_tr # # set violated_err_msg [db_string select_rel_violation {} -default ""] # # if { $violated_err_msg ne "" } { # error $violated_err_msg # } } on_error { return -code error $errmsg } return $rel_id } d_proc -public relation_remove { {rel_id ""} } { Removes the specified relation. Throws an error if we violate a relational constraint by removing this relation. @author Michael Bryzek (mbryzek@arsdigita.com) @creation-date 1/5/2001 @return 1 if we delete anything. 0 otherwise (e.g. when the relation was already deleted) } { # Pull out the segment_id and the party_id (object_id_two) from # acs_rels. Note the outer joins since the segment may not exist. if { ![db_0or1row select_rel_info_rm {}] } { # Relation doesn't exist return 0 } # Check if we would violate some constraint by removing this relation. # This query basically says: Does there exist a segment, to which # this party is an element (with any relationship type), that # depends on this party being in this segment? That's tough to # parse. Another way to say the same things is: Is there some constraint # that requires this segment? If so, is the user a member of the segment # on which that constraint is defined? If so, we cannot remove this # relation. Note that this segment is defined by joining against # acs_rels to find the group and rel_type for this relation. if { $segment_id ne "" } { if { [relation_segment_has_dependent -segment_id $segment_id -party_id $party_id] } { error "Relational constraints violated by removing this relation" } } db_exec_plsql relation_delete {} return 1 } d_proc -public relation_segment_has_dependent { { -rel_id "" } { -segment_id "" } { -party_id "" } } { Returns 1 if the specified segment/party combination has a dependent (meaning a constraint would be violated if we removed this relation). 0 otherwise. Either <code>rel_id</code> or <code>segment_id</code> and <code>party_id</code> must be specified. <code>rel_id</code> takes precedence. @author Michael Bryzek (mbryzek@arsdigita.com) @creation-date 12/2000 } { if { $rel_id ne "" } { if { ![db_0or1row select_rel_info {}] } { # There is either no relation or no segment... thus no dependents return 0 } } if { $segment_id eq "" || $party_id eq "" } { error "Both of segment_id and party_id must be specified in call to relation_segment_has_dependent" } return [db_string others_depend_p {}] } d_proc -public relation_type_is_valid_to_group_p { { -group_id "" } rel_type } { Returns 1 if group $group_id allows elements through a relation of type $rel_type, or 0 otherwise. If there are no relational constraints that prevent $group_id from being on side one of a relation of type $rel_type, then 1 is returned. @author Oumi Mehrotra (oumi@arsdigita.com) @creation-date 2000-02-07 @param group_id - if unspecified, then we use [application_group::group_id_from_package_id] @param rel_type } { if {$group_id eq ""} { set group_id [application_group::group_id_from_package_id] } return [db_string rel_type_valid_p {}] } d_proc relation_types_valid_to_group_multirow { {-datasource_name object_types} {-start_with acs_rel} {-group_id ""} } { creates multirow datasource containing relationship types starting with the $start_with relationship type. The datasource has columns that are identical to the party::types_allowed_in_group_multirow, which is why the columns are broadly named "object_*" instead of "rel_*". A common template can be used for generating select widgets etc. for both this datasource and the party::types_allowed_in_groups_multirow datasource. All subtypes of $start_with are returned, but the "valid_p" column in the datasource indicates whether the type is a valid one for $group_id. If -group_id is not specified or is specified null, then the current application_group will be used (determined from [application_group::group_id_from_package_id]). Includes fields that are useful for presentation in a hierarchical select widget: <ul> <li> object_type <li> object_type_enc - encoded object type <li> indent - an HTML indentation string <li> pretty_name - pretty name of object type </ul> @author Oumi Mehrotra (oumi@arsdigita.com) @creation-date 2000-02-07 @param datasource_name @param start_with @param group_id - if unspecified, then [application_group::group_id_from_package_id] is used. } { if {$group_id eq ""} { set group_id [application_group::group_id_from_package_id] } template::multirow create $datasource_name \ object_type object_type_enc indent pretty_name valid_p db_foreach select_sub_rel_types {} { template::multirow append $datasource_name $object_type [ad_urlencode $object_type] $indent $pretty_name $valid_p } } d_proc -public relation_required_segments_multirow { { -datasource_name "" } { -group_id "" } { -rel_type "membership_rel" } { -rel_side "two" } } { Sets up a multirow datasource. Also returns a list containing the most essential information. } { if {$group_id eq ""} { set group_id [application_group::group_id_from_package_id] } template::multirow create $datasource_name \ segment_id group_id rel_type rel_type_enc \ rel_type_pretty_name group_name join_policy set group_rel_type_list [list] db_foreach select_required_rel_segments {} { template::multirow append $datasource_name $segment_id $group_id $rel_type [ad_urlencode $rel_type] $rel_type_pretty_name $group_name $join_policy lappend group_rel_type_list [list $group_id $rel_type] } return $group_rel_type_list } d_proc -public relation::get_id { {-object_id_one:required} {-object_id_two:required} {-rel_type "membership_rel"} } { Find the rel_id of the relation matching the given object_id_one, object_id_two, and rel_type. @return rel_id of the found acs_rel, or the empty string if none existed. } { return [db_string select_rel_id {} -default {}] } d_proc -public relation::get_object_one { {-object_id_two:required} {-rel_type "membership_rel"} {-multiple:boolean} } { Return the object_id of object one if a relation of rel_type exists between the supplied object_id_two and it. @param multiple_p If set to "t" return a list instead of only one object_id } { if {$multiple_p} { return [db_list select_object_one {}] } else { return [db_string select_object_one {} -default {}] } } d_proc -public relation::get_object_two { {-object_id_one:required} {-rel_type "membership_rel"} {-multiple:boolean} } { Return the object_id of object two if a relation of rel_type exists between the supplied object_id_one and it. @param multiple_p If set to "t" return a list instead of only one object_id } { if {$multiple_p} { return [db_list select_object_two {}] } else { return [db_string select_object_two {} -default {}] } } d_proc -public relation::get_objects { {-object_id_one ""} {-object_id_two ""} {-rel_type "membership_rel"} } { Return the list of object_ids if a relation of rel_type exists between the supplied object_id and it. } { if {$object_id_one eq ""} { if {$object_id_two eq ""} { ad_return_error \ [_ acs-subsite.Missing_argument] \ [_ acs-subsite.lt_You_have_to_provide_a] ad_script_abort } else { return [relation::get_object_one -object_id_two $object_id_two -rel_type $rel_type -multiple] } } else { return [relation::get_object_two -object_id_one $object_id_one -rel_type $rel_type -multiple] } } # Local variables: # mode: tcl # tcl-indent-level: 4 # indent-tabs-mode: nil # End: