WeBWorK::DB - interface with the WeBWorK databases.
my $db = WeBWorK::DB->new($dbLayout);
my @userIDs = $db->listUsers();
my $Sam = $db->{user}->{record}->new();
$Sam->user_id("sammy");
$Sam->first_name("Sam");
$Sam->last_name("Hathaway");
# etc.
$db->addUser($User);
my $Dennis = $db->getUser("dennis");
$Dennis->status("C");
$db->putUser->($Dennis);
$db->deleteUser("sammy");
WeBWorK::DB provides a consistent interface to a number of database backends.
Access and modification functions are provided for each logical table used by
the webwork system. The particular backend (``schema'' and ``driver''), record
class, data source, and additional parameters are specified by the hash
referenced by $dbLayout, usually taken from the course environment.
The new database system uses a three-tier architecture to insulate each layer from the adjacent layers.
The top layer of the architecture is the DB module. It provides the methods listed below, and uses schema modules (via tables) to implement those methods.
/ new* list* exists* add* get* get*s put* delete* \ <- api
+------------------------------------------------------------------+
| DB |
+------------------------------------------------------------------+
\ password permission key user set set_user problem problem_user / <- tables
The middle layer of the architecture is provided by one or more schema modules. They are called ``schema'' modules because they control the structure of the data for a table. This includes odd things like the way multiple tables are encoded in a single hash in the WW1Hash schema, and the encoding scheme used.
The schema modules provide an API that matches the requirements of the DB layer, on a per-table basis. Each schema module has a style that determines which drivers it can interface with. For example, WW1Hash is a ``hash'' style schema. SQL is a ``dbi'' style schema.
Both WeBWorK 1.x and 2.x courses use:
/ password permission key \ / user \ <- tables provided
+-----------------------------+ +----------------+
| Auth1Hash | | Classlist1Hash |
+-----------------------------+ +----------------+
\ hash / \ hash / <- driver style required
WeBWorK 1.x courses also use:
/ set_user problem_user \ / set problem \
+-------------------------+ +---------------------+
| WW1Hash | | GlobalTableEmulator |
+-------------------------+ +---------------------+
\ hash / \ null /
The GlobalTableEmulator schema emulates the global set and problem tables using data from the set_user and problem_user tables.
WeBWorK 2.x courses also use:
/ set set_user problem problem_user \
+-------------------------------------+
| WW2Hash |
+-------------------------------------+
\ hash /
Driver modules implement a style for a schema. They provide physical access to
a data source containing the data for a table. The style of a driver determines
what methods it provides. All drivers provide connect(MODE) and
disconnect() methods. A hash style driver provides a hash() method which
returns the tied hash. A dbi style driver provides a handle() method which
returns the DBI handle.
/ hash \ / hash \ / hash \ <- style +--------+ +--------+ +--------+ | DB | | GDBM | | DB3 | +--------+ +--------+ +--------+
/ dbi \ / ldap \ +-------+ +--------+ | SQL | | LDAP | +-------+ +--------+
In %dblayout, each table is assigned a record class, used for passing
complete records to and from the database. The default record classes are
subclasses of the WeBWorK::DB::Record class, and are named as follows: User,
Password, PermissionLevel, Key, Set, UserSet, Problem, UserProblem. In the
following documentation, a reference the the record class for a table means the
record class currently defined for that table in %dbLayout.
new($dbLayout)
The new method creates a DB object and brings up the underlying schema/driver
structure according to the hash referenced by $dbLayout.
$dbLayout Format$dbLayout is a hash reference consisting of items keyed by table names. The
value of each item is a reference to a hash containing the following items:
The name of a perl module to use for representing the data in a record.
The name of a perl module to use for access to the table.
The name of a perl module to use for access to the data source.
The location of the data source that should be used by the driver module. Depending on the driver, this may be a path, a url, or a DBI spec.
A reference to a hash containing extra information needed by the schema. Some schemas require parameters, some do not. Consult the documentation for the schema in question.
For each table defined in $dbLayout, new loads the record, schema, and
driver modules. It the schema module's tables method lists the current table
(or contains the string ``*'') and the output of the schema and driver modules'
style methods match, the table is installed. Otherwise, an exception is
thrown.
hashDatabaseOK($fix)
If the schema module in use for the set and problem tables is
WeBWorK::DB::Schema::GlobalTableEmulator, the database is checked to make sure
that the ``global user'' exists and all sets and problems are assigned to it. If
$fix is true, problems found will be fixed: A global user will be created and
all sets/problems assigned to it.
A list of values is returned. The first value is a boolean value indicating
whether problems remain in the database after hashDatabaseOK() is called. The
remaining values are a list of strings indicating the particular ways in which
the database is (or was) broken.
newPassword()
Returns a new, empty password object.
listPasswords()
Returns a list of user IDs representing the records in the password table.
addPassword($Password)
$Password is a record object. The password will be added to the password table if a password with the same user ID does not already exist. If one does exist, an exception is thrown. To add a password, a user with a matching user ID must exist in the user table.
getPassword($userID)
If a record with a matching user ID exists, a record object containting that record's data will be returned. If no such record exists, one will be created.
getPasswords(@uesrIDs)
Return a list of password records associated with the user IDs given. If there is no record associated with a given user ID, one will be created.
putPassword($Password)
$Password is a record object. If a password record with the same user ID exists in the password table, the data in the record is replaced with the data in $Password. If a matching password record does not exist, one will be created. (This is different from most other ``put'' methods.)
deletePassword($userID)
If a password record with a user ID matching $userID exists in the password table, it is removed and the method returns a true value. If one does exist, a false value is returned.
newPermissionLevel()
Returns a new, empty permission level object.
listPermissionLevels()
Returns a list of user IDs representing the records in the permission table.
addPermissionLevel($PermissionLevel)
$PermissionLevel is a record object. The permission level will be added to the permission table if a permission level with the same user ID does not already exist. If one does exist, an exception is thrown. To add a permission level, a user with a matching user ID must exist in the user table.
getPermissionLevel($userID)
If a record with a matching user ID exists, a record object containting that record's data will be returned. If no such record exists, one will be created.
getPermissionLevels(@uesrIDs)
Return a list of permission level records associated with the user IDs given. If there is no record associated with a given user ID, one will be created.
putPermissionLevel($PermissionLevel)
$PermissionLevel is a record object. If a permission level record with the same user ID exists in the permission table, the data in the record is replaced with the data in $PermissionLevel. If a matching permission level record does not exist, one will be created. (This is different from most other ``put'' methods.)
deletePermissionLevel($userID)
If a permission level record with a user ID matching $userID exists in the permission table, it is removed and the method returns a true value. If one does exist, a false value is returned.
newKey()
Returns a new, empty key object.
listKeys()
Returns a list of user IDs representing the records in the key table.
addKey($Key)
$Key is a record object. The key will be added to the key table if a key with the same user ID does not already exist. If one does exist, an exception is thrown. To add a key, a user with a matching user ID must exist in the user table.
getKey($userID)
If a record with a matching user ID exists, a record object containting that record's data will be returned. If no such record exists, an undefined value will be returned.
getKeys(@uesrIDs)
Return a list of key records associated with the user IDs given. If there is no record associated with a given user ID, that element of the list will be undefined.
putKey($Key)
$Key is a record object. If a key record with the same user ID exists in the key table, the data in the record is replaced with the data in $Key. If a matching key record does not exist, an exception is thrown.
deleteKey($userID)
If a key record with a user ID matching $userID exists in the key table, it is removed and the method returns a true value. If one does exist, a false value is returned.
newUser()
Returns a new, empty user object.
listUsers()
Returns a list of user IDs representing the records in the user table.
addUser($User)
$User is a record object. The user will be added to the user table if a user with the same user ID does not already exist. If one does exist, an exception is thrown.
getUser($userID)
If a record with a matching user ID exists, a record object containting that record's data will be returned. If no such record exists, an undefined value will be returned.
getUsers(@uesrIDs)
Return a list of user records associated with the user IDs given. If there is no record associated with a given user ID, that element of the list will be undefined.
putUser($User)
$User is a record object. If a user record with the same user ID exists in the user table, the data in the record is replaced with the data in $User. If a matching user record does not exist, an exception is thrown.
deleteUser($userID)
If a user record with a user ID matching $userID exists in the user table, it is removed and the method returns a true value. If one does exist, a false value is returned. When a user record is deleted, all records associated with that user are also deleted. This includes the password, permission, and key records, and all user set records for that user.
FIXME: write this
newGlobalSet()
listGlobalSets()
addGlobalSet($GlobalSet)
addGlobalSet($setID)
getGlobalSets(@setIDs)
Return a list of global set records associated with the record IDs given. If there is no record associated with a given record ID, that element of the list will be undefined.
addGlobalSet($GlobalSet)
addGlobalSet($setID)
FIXME: write this
getUserSets(@userSetIDs)
Return a list of user set records associated with the record IDs given. If there is no record associated with a given record ID, that element of the list will be undefined. @userProblemIDs consists of references to arrays in which the first element is the user_id and the second element is the set_id.
FIXME: write this
getGlobalProblems(@problemIDs)
Return a list of global set records associated with the record IDs given. If there is no record associated with a given record ID, that element of the list will be undefined. @problemIDs consists of references to arrays in which the first element is the set_id, and the second element is the problem_id.
getAllGlobalProblems($setID)
Returns a list of Problem objects representing all the problems in the given global set. When using the WW1Hash/GlobalTableEmulator schemas, this is far more efficient than using listGlobalProblems and getGlobalProblems.
FIXME: write this
getUserProblems(@userProblemIDs)
Return a list of user set records associated with the user IDs given. If there is no record associated with a given user ID, that element of the list will be undefined. @userProblemIDs consists of references to arrays in which the first element is the user_id, the second element is the set_id, and the third element is the problem_id.
Returns a list of UserProblem objects representing all the problems in the given set. When using the WW1Hash/GlobalTableEmulator schemas, this is far more efficient than using listUserProblems and getUserProblems.
These functions combine a global set and a user set to create a merged set, which is returned. Any field that is not defined in the user set is taken from the global set. Merged sets have the same type as user sets.
Returns a merged set record associated with the record IDs given. If there is no record associated with a given record ID, the undefined value is returned.
getMegedSets(@userSetIDs)
Return a list of merged set records associated with the record IDs given. If there is no record associated with a given record ID, that element of the list will be undefined. @userSetIDs consists of references to arrays in which the first element is the user_id and the second element is the set_id.
These functions combine a global problem and a user problem to create a merged problem, which is returned. Any field that is not defined in the user problem is taken from the global problem. Merged problems have the same type as user problems.
Returns a merged problem record associated with the record IDs given. If there is no record associated with a given record ID, the undefined value is returned.
getMergedProblems(@userProblemIDs)
Return a list of merged problem records associated with the record IDs given. If there is no record associated with a given record ID, that element of the list will be undefined. @userProblemIDs consists of references to arrays in which the first element is the user_id, the second element is the set_id, and the third element is the problem_id.
Written by Sam Hathaway, sh002i (at) math.rochester.edu.