All client programs will interact with the groups database using the following API.
This specification consists of five parts:
The Groups database deals in three major items: entities, groups, and individuals. An entity is either a group or an individual. Groups contain entities. An individual represents a person.
A unique integer representing either a group or an individual in the database.
This may also be written as "groupID" or "indivID" which simply indicates an entityID that refers to a group or individual respectively.
A hash containing all information about an entity. These are often the return value of functions, either alone or in a larger hash, keyed on entityIDs.
entityHash contents:
| Key | Value | Example |
|---|---|---|
| entityid | Unique ID number | 2342 |
| uwnetid | UW Net ID | jdean |
| name | Real Name | Jimmy Dean |
| Email Address | jdean@cac.washington.edu | |
| is_group | Whether entity is a group | false |
| is_internal | Whether entity is internal to C&C | true |
For data modification functions, this is returned. HEED IT! It will help you debug, and no data will be modified in the presence of an error.
error greater than zero indicates an error. Useful information will be in the description even if no error occurs. (ie, error = 0)
| Key | Value | Example |
|---|---|---|
| error | Error Number | 2 |
| description | Description of the error | Group 2345 is not empty. Can't delete |
Connects to the group database and creates a new groups object.
The clientTag should be a string descriptor of your client. This will be used for registering entity uses and debugging. Please use the same client tag for all connections made by a particular client.
For example:
$grp = new Group("Schedule Manager");
The object $grp should now be used for all group
queries.
Disconnects from the group database
Begins an exclusive set of transactions which can be either
commited or rollbacked.
Recall that no other client can use the groups database during your transaction so please be polite and make sure you use this efficiently. During an exclusive transaction, if your client goes for 5 seconds without making a request your connection will be dropped, and no changes made.
Also, be aware that NO DATA WILL BE
MODIFIED unless you issues a commit.
Returns an error hash.
Commits all changes made to the Groups database during a transaction
started by beginWork.
Returns an error hash
Undoes all changes made to the Groups database during a transaction begun
by beginWork.
returns an error hash
Returns an entity hash containing all info on the entity. Takes an entity hash containing one or more identifying values.
This function is useful for obtaining the entity id necessary for many of these functions.
If no entity can be found based on the provided information this returns an empty entityHash with an negative entityID. Check for this.
Searches through Names, UW Net IDs, and Email addresses for matches. Returns all hits in an array of entityHashes, keyed on entityid.
Returns true if entity belongs to group
Returns the groups to which the entity belongs in a hash of group hashes, keyed on entityid. The optional height argument controls how far up the membership tree will be analyzed.
A height of 1 will return all groups to which the entity directly belongs to, 2 will return all groups to which the entity belongs with one level of inheritance, and so forth. The default (no height provided) will recurse completely and return all groups to which the individual belongs. This is usually what the clients will want.
If no groups are found this function returns an empty hash, which can be considered equivalent to false in Perl.
Returns the members of group in a hash of entity hashes, keyed on entityid. The optional depth argument controls how far down the membership tree will be analyzed.
A depth of 1 will return all entities directly belonging to the passed group, 2 will return all individuals directly below the passed group, and all entities contained within any groups directly below the passed group. The default (no depth provided) will recurse completely, returning all individuals and groups contained. This is usually what clients will want.
If no members are found this function returns an empty hash, which can be considered equivalent to false in Perl.
Returns all groups registered to the provided clienttag.
Returns all groups which do not belong to other groups - the top level of the membership tree. Hash of entityHashes keyed on entityid.
Returns all individuals which do not belong to groups - the orphans of the membership tree. Hash of entityHashes keyed on entityid.
Returns all individuals.
Returns all groups.
Adds a new entity from the filled out entityHash and adds that entity to all the specified groups (array reference of groupIDs) if provided. Returns an returnHash.
It is necessary to provide values for the following keys in the entity hash: uwnetid, name, email, and is_group. You may optionally specify is_internal. The default is to set is_internal = true.
If there is no error, the 'description' key of the returnHash will contain the new entity's 'entityid'.
Modifies an entity. The passed hash MUST contain a valid entityid; this is the entity to be updated. Any other filled in fields will overwrite the current values.
When provided with an array reference containing groupsIDs, ALL current
group memberships will be REPLACED with the new groupIDs. Please use
leaveGroup and joinGroup for most operations, as
they are safer - this function can overwrite the grouping information used by
other clients.
Returns an errorhash.
Adds the specified entity to the specified list of groups. Returns a returnHash.
Removes the specified entity from the list of groups. Returns a returnHash.
Removes all entites from the specified group. Please be careful with this,
as many applications may use the same group. When possible, try to use
leaveGroup to affect only those groups you need to.
Removes the specified entity from the database. Groups will not be deleted unless they are already empty. Returns a returnHash.
Registers the use of this entity under your clientTag.
Attempts to delete this entity will result in an error for all clients.
Please not that this is not a 100% guarantee (more like 99%), as an administrative tool will be allowed to override this; code your error-checking accordingly.
Returns an errorHash.
Releases the use of this entity by your clientTag, allowing deletion by your and other clients.
Returns an errorHash.
An example of some query functions:
use Group;
# create a new groups object
$grp = new Group("schedule manager");
# get some info about an individual
%indivInfo = $grp->getEntity('uwnetid' => 'mcrawfor');
print "Name: ". %indivInfo{'name'} . "\n";
# get a list of groups which mcrawfor belongs to
%groupList = $grp->groups($indivInfo{'entityid'});
# %groupList now contains a hash: keys are entityIDs for
# the groups, values are entityHashes for the groups, so:
foreach $item (keys %groupList){
print $groupList{$item}{'name'} . "\n";
}
# belongsTo provides boolean membership checking:
# Note that "3" is a groupID (found with groups)
if( $grp->belongsTo( $indivInfo{'entityid'}, 3){
print "True";
}else{
print "False";
}
# members gets a hash of entityHashes that belong to the
# given group. The optional second argument controls the
# depth to which the membership tree is traveled.
%members = %grp->members(3,1);
# %members now contains a hash like above, so:
foreach $item (keys %members){
print $members{$item}{'name'} . "\n";
}
#disconnect
$grp->close();
Which prints:
Name: Miles Crawford Student Staff Leads Routers FaqMan Admins True Miles Crawford Michal Guerquin
Some data modification examples:
## Create a new entityHash and add it to some groups:
%newEntity = ( 'name' => 'Mr. Tux',
'uwnetid' => 'tux',
'email' => 'tux@cac.washington.edu',
'is_group' => 0);
@initialGroups = ( 45, 12, 43 );
%errHash = $grp->addEntity(%newEntity, \@initialGroups);
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
$tuxID = $errHash{'description'};
print "Success, entity $tuxID was added.\n";
}
## Add Tux to some new groups:
@moreGroups = ( 23, 34 );
%errHash = $grp->joinGroup($tuxID, @moreGroups);
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
## Tux leaves a group or two
@oldGroups = ( 23, 12 );
%errHash = $grp->leaveGroup($tuxID, @oldGroups);
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
## Delete a group
%errHash = $grp->deleteEntity(34);
#error: Tux belongs to this group
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
Which prints:
Success, entity 94 was added. Successfully joined groups. Successfully left groups. An error occurred: Entity '34' has current members. Can't Delete.
A use registry example:
## Register our use of Tux
%errHash = $grp->registerUse($tuxID);
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
## Delete Tux
%errHash = $grp->deleteEntity($tuxID);
%#error: We've registered Tux
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
## Release our use of Tux
%errHash = $grp->releaseUse($tuxID);
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print $errHash{'description'} . "\n";
}
## Try to delete that lovable penguin again
%errHash = $grp->deleteEntity($tuxID); #should work now
if($errHash{'error'}){
print "An error occurred: " . $errHash{'description'};
}else{
print "Success, tux is gone.";
}
Which prints:
Successful register. An error occurred: Entity '94' is used by: schedule_manager. Can't delete. Successful release. Success, tux is gone.
Entity List Sorting:
Frequently the groups manager will return to you hashes full of entity hashes, and it may be useful to sort these lists by name or netid, etc. Here is an example subfunction for doing this by name:
sub sort_entity_list{
my %orig = @_;
my @ordered;
@ordered =
sort {
lc($orig{$a}{'name'}) cmp lc($orig{$b}{'name'})
} keys %orig;
return @ordered;
}
Then, you can iterate through your entities in name-order:
%big_list = $grp->allIndivs();
@order = sort_entity_list(%big_list);
foreach my $key (@order){
print $big_list{$key}{'name'} . "\n";
}
Which prints:
Aardvark Amos Andy Bob ...