Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#12048] Add dangling course delete script #13090

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package teammates.client.scripts.sql;

import java.io.IOException;

import java.util.Optional;

import teammates.client.connector.DatastoreClient;
import teammates.client.util.ClientProperties;
import teammates.common.util.HibernateUtil;
import teammates.storage.entity.Course;
import teammates.test.FileHelper;


import com.google.cloud.datastore.Cursor;
import com.google.cloud.datastore.QueryResults;
import com.googlecode.objectify.cmd.Query;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;


public class DeleteDanglingCourseScript extends DatastoreClient {
private static final String BASE_LOG_URI = "src/client/java/teammates/client/scripts/log/";
private static final String COURSE_MIGRATION_SCRIPT_NAME = "DataMigrationForCourseEntitySql";
public static void main(String[] args) {
String connectionUrl = ClientProperties.SCRIPT_API_URL;
String username = ClientProperties.SCRIPT_API_NAME;
String password = ClientProperties.SCRIPT_API_PASSWORD;

HibernateUtil.buildSessionFactory(connectionUrl, username, password);

DeleteDanglingCourseScript script = new DeleteDanglingCourseScript();
script.doOperationRemotely();
}

protected void doOperation() {
deleteDanglingCourse();
}


private void deleteDanglingCourse() {
Cursor cursor = readPositionOfCursorFromFile().orElse(null);
if (cursor == null) {
throw new Error("No cursor found!");
}

Course danglingCourse = getDanglingCourse(cursor);
log("Deleting partially migrated course: " + danglingCourse.getUniqueId());
deleteCourseCascade(danglingCourse);
}

private Course getDanglingCourse(Cursor cursor) {
Query<Course> filterQueryKeys = getFilterQuery().limit(1);
filterQueryKeys = filterQueryKeys.startAt(cursor);
QueryResults<?> iterator = filterQueryKeys.iterator();

Course course = null;
// Cascade delete the course if it is not fully migrated.
if (iterator.hasNext()) {
course = (Course) iterator.next();
if (course.isMigrated()) {
throw new Error("Course does not have any dangling entities");
}
Course danglingCourse = course;
return danglingCourse;
} else {
throw new Error("No course remaining");
}
}

protected Objectify ofy() {
return ObjectifyService.ofy();
}

protected Query<Course> getFilterQuery() {
return ofy().load().type(Course.class);
}

/**
* Deletes the course and its related entities from sql database.
*/
private void deleteCourseCascade(Course oldCourse) {
String courseId = oldCourse.getUniqueId();

HibernateUtil.beginTransaction();
teammates.storage.sqlentity.Course newCourse = HibernateUtil.get(teammates.storage.sqlentity.Course.class, courseId);
if (newCourse == null) {
HibernateUtil.commitTransaction();
throw new Error("Course does not have any dangling entities");
}

log("delete dangling course with id: " + courseId);
HibernateUtil.remove(newCourse);
HibernateUtil.flushSession();
HibernateUtil.clearSession();
HibernateUtil.commitTransaction();
}

/**
* Reads the cursor position from the saved file.
*
* @return cursor if the file can be properly decoded.
*/
private Optional<Cursor> readPositionOfCursorFromFile() {
try {
String cursorPosition =
FileHelper.readFile(BASE_LOG_URI + COURSE_MIGRATION_SCRIPT_NAME + ".cursor");
return Optional.of(Cursor.fromUrlSafe(cursorPosition));
} catch (IOException | IllegalArgumentException e) {
return Optional.empty();
}
}

protected void log(String logLine) {
System.out.println(String.format("%s %s", getLogPrefix(), logLine));
}

protected String getLogPrefix() {
return String.format("Cleaning up dangling course: ");
}
}
4 changes: 1 addition & 3 deletions src/client/java/teammates/client/scripts/sql/SeedDb.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,7 @@ private void seedAccountRequests() {
AccountRequest accountRequest = AccountRequestAttributes
.builder(accountRequestEmail, accountRequestInstitute, accountRequestName)
.withRegisteredAt(Instant.now()).build().toEntity();

ofy().save().entities(accountRequest).now();
saveEntityDeferred(buffer, accountRequest);
} catch (Exception e) {
log("Account and account request" + e.toString());
}
Expand Down Expand Up @@ -496,7 +495,6 @@ public static void main(String[] args) throws Exception {
@Override
protected void doOperation() {
try {
// clearDataStore();
// LogicStarter.initializeDependencies();
this.persistData();
} catch (Exception e) {
Expand Down