- Publicity: Public Only All
relation-procs.tcl
Helpers for dealing with relations
- Location:
- packages/acs-subsite/tcl/relation-procs.tcl
- Created:
- Sun Dec 10 16:46:11 2000
- Author:
- mbryzek@arsdigita.com
- CVS Identification:
$Id: relation-procs.tcl,v 1.20.2.2 2019/05/16 09:27:52 gustafn Exp $
Procedures in this file
- relation::get_id (public)
- relation::get_object_one (public)
- relation::get_object_two (public)
- relation::get_objects (public)
- relation_add (public)
- relation_permission_p (public, deprecated)
- relation_remove (public)
- relation_required_segments_multirow (public)
- relation_segment_has_dependent (public)
- relation_type_is_valid_to_group_p (public)
- relation_types_valid_to_group_multirow (public)
Detailed information
relation::get_id (public)
relation::get_id -object_id_one object_id_one \ -object_id_two object_id_two [ -rel_type rel_type ]
Find the rel_id of the relation matching the given object_id_one, object_id_two, and rel_type.
- Switches:
- -object_id_one (required)
- -object_id_two (required)
- -rel_type (optional, defaults to
"membership_rel"
)- Returns:
- rel_id of the found acs_rel, or the empty string if none existed.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_relation_procs
relation::get_object_one (public)
relation::get_object_one -object_id_two object_id_two \ [ -rel_type rel_type ] [ -multiple ]
Return the object_id of object one if a relation of rel_type exists between the supplied object_id_two and it.
- Switches:
- -object_id_two (required)
- -rel_type (optional, defaults to
"membership_rel"
)- -multiple (optional, boolean)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_relation_procs, category_tree_procs
relation::get_object_two (public)
relation::get_object_two -object_id_one object_id_one \ [ -rel_type rel_type ] [ -multiple ]
Return the object_id of object two if a relation of rel_type exists between the supplied object_id_one and it.
- Switches:
- -object_id_one (required)
- -rel_type (optional, defaults to
"membership_rel"
)- -multiple (optional, boolean)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_relation_procs
relation::get_objects (public)
relation::get_objects [ -object_id_one object_id_one ] \ [ -object_id_two object_id_two ] [ -rel_type rel_type ]
Return the list of object_ids if a relation of rel_type exists between the supplied object_id and it.
- Switches:
- -object_id_one (optional)
- -object_id_two (optional)
- -rel_type (optional, defaults to
"membership_rel"
)- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_relation_procs
relation_add (public)
relation_add [ -form_id form_id ] [ -extra_vars extra_vars ] \ [ -variable_prefix variable_prefix ] \ [ -creation_user creation_user ] [ -creation_ip creation_ip ] \ [ -member_state 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.
- Switches:
- -form_id (optional)
- The form id from templating form system
- -extra_vars (optional)
- An ns_set of extra variables
- -variable_prefix (optional)
- Only form elements that begin with the specified prefix will be processed.
- -creation_user (optional)
- The user who is creating the relation
- -creation_ip (optional)
- -member_state (optional)
- Only used for membership_relations. See column membership_rels.member_state for more info.
- Parameters:
- rel_type (required)
- object_id_one (required)
- object_id_two (required)
- Returns:
- The
rel_id
of the new relation- Authors:
- Michael Bryzek <mbryzek@arsdigita.com>
- Ben Adida <ben@openforce.net>
- Created:
- 1/5/2001
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_expose_bug_775, acs_subsite_check_composite_group, acs_subsite_relation_procs, acs_subsite_rel_segment_new
relation_permission_p (public, deprecated)
relation_permission_p [ -user_id user_id ] [ -privilege privilege ] \ rel_id
Deprecated. Invoking this procedure generates a warning.
Wrapper for ad_permission_p that lets us default to read permission Deprecated: just another wrapper for permission::permission_p
- Switches:
- -user_id (optional)
- -privilege (optional, defaults to
"read"
)- Parameters:
- rel_id (required)
- Author:
- Michael Bryzek <mbryzek@arsdigita.com>
- Created:
- 12/2000
- See Also:
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
relation_remove (public)
relation_remove [ rel_id ]
Removes the specified relation. Throws an error if we violate a relational constraint by removing this relation.
- Parameters:
- rel_id (optional)
- Returns:
- 1 if we delete anything. 0 otherwise (e.g. when the relation was already deleted)
- Author:
- Michael Bryzek <mbryzek@arsdigita.com>
- Created:
- 1/5/2001
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- acs_subsite_relation_procs
relation_required_segments_multirow (public)
relation_required_segments_multirow \ [ -datasource_name datasource_name ] [ -group_id group_id ] \ [ -rel_type rel_type ] [ -rel_side rel_side ]
Sets up a multirow datasource. Also returns a list containing the most essential information.
- Switches:
- -datasource_name (optional)
- -group_id (optional)
- -rel_type (optional, defaults to
"membership_rel"
)- -rel_side (optional, defaults to
"two"
)- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
relation_segment_has_dependent (public)
relation_segment_has_dependent [ -rel_id rel_id ] \ [ -segment_id segment_id ] [ -party_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
rel_id
orsegment_id
andparty_id
must be specified.rel_id
takes precedence.
- Switches:
- -rel_id (optional)
- -segment_id (optional)
- -party_id (optional)
- Author:
- Michael Bryzek <mbryzek@arsdigita.com>
- Created:
- 12/2000
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- demote_promote_a_user
relation_type_is_valid_to_group_p (public)
relation_type_is_valid_to_group_p [ -group_id 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.
- Switches:
- -group_id (optional)
- - if unspecified, then we use [application_group::group_id_from_package_id]
- Parameters:
- rel_type (required)
- Author:
- Oumi Mehrotra <oumi@arsdigita.com>
- Created:
- 2000-02-07
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
relation_types_valid_to_group_multirow (public)
relation_types_valid_to_group_multirow \ [ -datasource_name datasource_name ] [ -start_with start_with ] \ [ -group_id 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:
- object_type
- object_type_enc - encoded object type
- indent - an HTML indentation string
- pretty_name - pretty name of object type
- Switches:
- -datasource_name (optional, defaults to
"object_types"
)- -start_with (optional, defaults to
"acs_rel"
)- -group_id (optional)
- - if unspecified, then [application_group::group_id_from_package_id] is used.
- Author:
- Oumi Mehrotra <oumi@arsdigita.com>
- Created:
- 2000-02-07
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
Content File Source
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: