protected void RequestAttemptsByTopic(LearningStoreJob job, Int32 topicId) { LearningStoreQuery query = LStore.CreateQuery(Schema.AttemptsResultsByThemeAndUser.ViewName); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.AttemptId); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.CompletionStatus); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.AttemptStatus); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.SuccessStatus); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.StartedTimestamp); query.AddColumn(Schema.AttemptsResultsByThemeAndUser.Score); query.SetParameter(Schema.AttemptsResultsByThemeAndUser.ThemeIdParam, topicId); job.PerformQuery(query); }
/////////////////////////////////////////////////////////////////////////// // Public Methods // /// <summary> /// Requests that information about the current user be retrieved from the /// LearningStore database. Adds the request to a given /// <c>LearningStoreJob</c> for later execution. /// </summary> /// /// <param name="job">A <c>LearningStoreJob</c> to add the new query to. /// </param> /// /// <remarks> /// After executing this method, and later calling <c>Job.Execute</c>, /// call <c>GetCurrentUserInfoResults</c> to convert the <c>DataTable</c> /// returned by <c>Job.Execute</c> into an <c>LStoreUserInfo</c> object. /// </remarks> /// protected void RequestCurrentUserInfo(LearningStoreJob job) { // look up the user in the UserItem table in the database using their // user key, and set <userId> to the LearningStore numeric identifier // of the user (i.e. UserItem.Id -- the "Id" column of the UserItem // table) and <userName> to their full name (e.g. "Karen Berg"); if // there's no UserItem for the user, add one and set <userId> to its // ID LearningStoreQuery query = LStore.CreateQuery( Schema.Me.ViewName); query.AddColumn(Schema.Me.UserId); query.AddColumn(Schema.Me.UserName); job.PerformQuery(query); }
/// <summary> /// Requests that the list of all attempts all users have performed on all organizaions. /// Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> protected void RequestAllAttempts(LearningStoreJob job) { LearningStoreQuery query = LStore.CreateQuery(Schema.AllAttemptsResults.ViewName); query.AddColumn(Schema.AllAttemptsResults.AttemptId); query.AddColumn(Schema.AllAttemptsResults.UserItemKey); query.AddColumn(Schema.AllAttemptsResults.ThemeId); query.AddColumn(Schema.AllAttemptsResults.CompletionStatus); query.AddColumn(Schema.AllAttemptsResults.AttemptStatus); query.AddColumn(Schema.AllAttemptsResults.SuccessStatus); query.AddColumn(Schema.AllAttemptsResults.StartedTimestamp); query.AddColumn(Schema.AllAttemptsResults.Score); job.PerformQuery(query); }
/// <summary> /// Deletes pacakge and related attempts from database. /// </summary> /// <param name="packId">Long integer value represents package identifier.</param> protected void DeletePackage(long packId) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier(packId); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttempts.ViewName); query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttempts.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddSort(Schema.MyAttempts.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); }
/// <summary> /// Requests that the list of training for the current user be retrieved from the LearningStore /// database. Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// <param name="packageId">To request information related to a single pass the /// <c>PackageItemIdentifier</c> of the package as this parameter. Otherwise, leave this /// parameter <c>null</c>.</param> protected void RequestMyTraining(LearningStoreJob job, PackageItemIdentifier packageId) { LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttempts.ViewName); query.AddColumn(Schema.MyAttempts.PackageId); query.AddColumn(Schema.MyAttempts.OrganizationId); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddColumn(Schema.MyAttempts.AttemptStatus); query.AddColumn(Schema.MyAttempts.TotalPoints); if (packageId != null) { query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); } job.PerformQuery(query); }
/// <summary> /// Requests that the list of all answers by specified attempt on organization. /// Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// <param name="attemptId"><c>AttemptItemIdentifier</c> represents id of attempt.</param> protected void RequestInteractionResultsByAttempt(LearningStoreJob job, AttemptItemIdentifier attemptId) { LearningStoreQuery query = LStore.CreateQuery(Schema.InteractionResultsByAttempt.ViewName); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityAttemptId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityPackageId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityTitle); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionId); query.AddColumn(Schema.InteractionResultsByAttempt.CompletionStatus); query.AddColumn(Schema.InteractionResultsByAttempt.SuccessStatus); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseBool); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseString); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseNumeric); query.AddColumn(Schema.InteractionResultsByAttempt.CorrectResponse); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionType); query.AddColumn(Schema.InteractionResultsByAttempt.ScaledScore); query.SetParameter(Schema.InteractionResultsByAttempt.AttemptIdParam, attemptId); job.PerformQuery(query); }
/// <summary> /// Retrieves package id by specified IUDICO course. /// </summary> /// <param name="course">Course object represents iudico course entity.</param> /// <returns>PackageItemIdentifier value representing corresponding MLC Package ID.</returns> protected PackageItemIdentifier GetPackageIdentifier(int courseId) { PackageItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.PackageIdByCourse.ViewName); query.AddColumn(Schema.PackageIdByCourse.PackageId); query.SetParameter(Schema.PackageIdByCourse.IudicoCourseRef, courseId); job.PerformQuery(query); ReadOnlyCollection <object> resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { LStoreHelper.Cast(dataTable.Rows[0][Schema.PackageIdByCourse.PackageId], out result); } return(result); }
/// <summary> /// Retrieves Organization Id by specified package oidentifier. /// </summary> /// <param name="packageId"><c>PackageItemIdentifier</c> value representing package id, organization is being searched by.</param> /// <returns><c>ActivityPackageItemIdentifier</c> value, which represents organization identifier of specified package.</returns> protected ActivityPackageItemIdentifier GetOrganizationIdentifier(PackageItemIdentifier packageId) { ActivityPackageItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.RootActivityByPackage.ViewName); query.AddColumn(Schema.RootActivityByPackage.RootActivity); query.SetParameter(Schema.RootActivityByPackage.PackageId, packageId); job.PerformQuery(query); var resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { LStoreHelper.Cast(dataTable.Rows[0][Schema.RootActivityByPackage.RootActivity], out result); } return(result); }
/// <summary> /// Retrieves attempt identifier for specified organization id and Iudico topic id. /// </summary> /// <param name="orgId"><c>ActivityPackageItemIdentifier</c> value representing Organization ID.</param> /// <param name="topicId">Integer value - IUDICO topic id.</param> /// <returns><c>AttemptItemIdentifier</c> value representing Attempt Identifier.</returns> protected AttemptItemIdentifier GetAttemptIdentifier(ActivityPackageItemIdentifier orgId, int topicId) { AttemptItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttempts.ViewName); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddCondition(Schema.MyAttempts.OrganizationId, LearningStoreConditionOperator.Equal, orgId); query.AddCondition(Schema.MyAttempts.ThemeId, LearningStoreConditionOperator.Equal, topicId); job.PerformQuery(query); ReadOnlyCollection <object> resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { // get last result LStoreHelper.Cast(dataTable.Rows[dataTable.Rows.Count - 1][Schema.MyAttempts.AttemptId], out result); } return(result); }
protected void Page_Load(object sender, EventArgs e) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId = new AttemptItemIdentifier( Convert.ToInt64(Request.QueryString["AttemptId"], CultureInfo.InvariantCulture)); // set <previousEntryId> to the ID of the sequencing log entry that we most recently // displayed; newer entries than that will be highlighted long previousEntryId; string value = Request.QueryString["PreviousEntryId"]; if (value == null) { previousEntryId = long.MaxValue; } else { previousEntryId = Convert.ToInt64(value, CultureInfo.InvariantCulture); } try { // create a job to execute two queries LearningStoreJob job = LStore.CreateJob(); // first query: get the package name and organization title of this attempt LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttemptsAndPackages.ViewName); query.AddColumn(Schema.MyAttemptsAndPackages.PackageFileName); query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationTitle); query.AddCondition(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreConditionOperator.Equal, attemptId); job.PerformQuery(query); // second query: get the contents of the sequencing log for this attempt query = LStore.CreateQuery(Schema.SequencingLog.ViewName); query.AddColumn(Schema.SequencingLog.Id); query.AddColumn(Schema.SequencingLog.Timestamp); query.AddColumn(Schema.SequencingLog.EventType); query.AddColumn(Schema.SequencingLog.NavigationCommand); query.AddColumn(Schema.SequencingLog.Message); query.SetParameter(Schema.SequencingLog.AttemptId, attemptId); query.AddSort(Schema.SequencingLog.Id, LearningStoreSortDirection.Descending); job.PerformQuery(query); // execute the job ReadOnlyCollection <object> results = job.Execute(); DataTable attemptInfoDataTable = (DataTable)results[0]; DataTable sequencingLogDataTable = (DataTable)results[1]; // extract information from the first query into local variables DataRow attemptInfo = attemptInfoDataTable.Rows[0]; string packageFileName; LStoreHelper.CastNonNull(attemptInfo[Schema.MyAttemptsAndPackages.PackageFileName], out packageFileName); string organizationTitle; LStoreHelper.CastNonNull(attemptInfo[Schema.MyAttemptsAndPackages.OrganizationTitle], out organizationTitle); // set <trainingName> to the name to use for this attempt string trainingName; if (organizationTitle.Length == 0) { trainingName = packageFileName; } else { trainingName = String.Format("{0} - {1}", packageFileName, organizationTitle); } // copy <trainingName> to the UI TrainingName.Text = Server.HtmlEncode(trainingName); // set <maxLogEntryId> to the highest-numbered log entry ID -- which is the first one, // since they're sorted by descending entry ID SequencingLogEntryItemIdentifier maxLogEntryId; if (sequencingLogDataTable.Rows.Count > 0) { DataRow dataRow = sequencingLogDataTable.Rows[0]; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Id], out maxLogEntryId); } else { maxLogEntryId = new SequencingLogEntryItemIdentifier(-1); } // loop once for each item in the sequencing log foreach (DataRow dataRow in sequencingLogDataTable.Rows) { // extract information from <dataRow> into local variables SequencingLogEntryItemIdentifier logEntryId; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Id], out logEntryId); DateTime?time; LStoreHelper.Cast(dataRow[Schema.SequencingLog.Timestamp], out time); SequencingEventType?eventType; LStoreHelper.Cast(dataRow[Schema.SequencingLog.EventType], out eventType); NavigationCommand?navigationCommand; LStoreHelper.Cast(dataRow[Schema.SequencingLog.NavigationCommand], out navigationCommand); string message; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Message], out message); // begin the HTML table row TableRow htmlRow = new TableRow(); // highlight this row if it's new since the last refresh if (logEntryId.GetKey() > previousEntryId) { htmlRow.CssClass = "Highlight"; } // add the "ID" HTML cell TableCell htmlCell = new TableCell(); htmlCell.CssClass = "Id_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(logEntryId.GetKey().ToString())); htmlRow.Cells.Add(htmlCell); // add the "Time" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Time_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(String.Format("{0:d} {0:t}", time))); htmlRow.Cells.Add(htmlCell); // add the "EventType" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "EventType_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(eventType.ToString())); htmlRow.Cells.Add(htmlCell); // add the "NavigationCommand" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "NavigationCommand_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(navigationCommand.ToString())); htmlRow.Cells.Add(htmlCell); // add the "Message" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Message_"; htmlCell.Wrap = false; htmlCell.Text = Server.HtmlEncode(message); htmlRow.Cells.Add(htmlCell); // end the table HTML row; add it to the HTML table LogGrid.Rows.Add(htmlRow); } // update <RefreshLink> RefreshLink.NavigateUrl = String.Format("?AttemptId={0}&PreviousEntryId={1}", attemptId.GetKey(), maxLogEntryId.GetKey()); } catch (Exception ex) { // an unexpected error occurred -- display a generic message that doesn't include the // exception message (since that message may include sensitive information), and write // the exception message to the event log LogTitle.Visible = false; LogContents.Visible = false; ErrorMessage.Visible = true; ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl( Server.HtmlEncode("A serious error occurred. Please contact your system administrator. More information has been written to the server event log."))); LogEvent(System.Diagnostics.EventLogEntryType.Error, "An exception occurred while accessing the sequencing log for attempt #{0}:\n\n{1}\n\n", attemptId.GetKey(), ex.ToString()); } }
protected void DeletePackagesButton_Click(object sender, EventArgs e) { // the user clicked "Upload"... // hide the confirmation panel ConfirmMessage.Visible = false; // the PackagesToDelete hidden form element contains a comma-delimited list of IDs of // packages to delete (copied from <dialogArguments> on the client) -- attempt to delete // those packages, and set <deleted> to the IDs of packages successfully deleted List <string> deleted = new List <string>(); try { // loop once for each package to delete foreach (string id in PackagesToDelete.Value.Split(',')) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier( Convert.ToInt64(id, CultureInfo.InvariantCulture)); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttemptsAndPackages.ViewName); query.AddCondition(Schema.MyAttemptsAndPackages.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttemptsAndPackages.AttemptId); query.AddSort(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); // add the package ID to the list of deleted packages deleted.Add(id); } // the operation was successful, and there are no messages to // display to the user, so close the dialog CloseDialogScript.Visible = true; } catch (Exception ex) { // an unexpected error occurred -- display a generic message that // doesn't include the exception message (since that message may // include sensitive information), and write the exception message // to the event log ErrorIntro.Visible = true; ErrorMessage.Visible = true; ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl( Server.HtmlEncode("A serious error occurred. Please contact your system administrator. More information has been written to the server event log."))); LogEvent(System.Diagnostics.EventLogEntryType.Error, "An exception occurred while deleting a package:\n\n{0}\n\n", ex.ToString()); } // update the buttons DeletePackagesButton.Visible = false; CloseButton.Text = "OK"; // set the hidden form element PackagesSuccessfullyDeleted to a // comma-separated list of IDs of packages that were successfully // deleted, and enable the client-side script that communicates this // information to the parent page PackagesSuccessfullyDeleted.Value = String.Join(",", deleted.ToArray()); UpdateParentPageScript.Visible = true; }