Exemple #1
0
def _alter_column_type_if_needed(
    table: Type[Model],
    field_instance: Field,
    new_type: Field,
) -> bool:
    field_type_name = new_type.__class__.__name__
    current_type = field_instance.__class__.__name__
    column_name = field_instance.name.lower()
    table_name = table.__name__.lower()

    if field_type_name.lower() == current_type.lower():
        log.info(f'Column {column_name} is already {field_type_name}')
        return False

    log.info(
        f'Changing {column_name} from {current_type} '
        f'to {field_type_name} in {table}',
    )
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        migrate(
            migrator.alter_column_type(table_name, column_name, new_type),
        )
        db_config.database.commit()
    return True
Exemple #2
0
def _execute_sql_if_possible(sql: str) -> bool:
    with db_config.database.transaction():
        log.info(f'Running {sql}')
        try:
            db_config.database.execute_sql(sql)
            db_config.database.commit()
        except (OperationalError, ProgrammingError) as e:
            log.info(f"Can't run SQL '{sql}' because: {e}")
    return True
Exemple #3
0
 def _get_or_create_user_in_model(user: UserToCreate) -> None:
     log.info('Create user with email: %s', user.email)
     models.User.get_or_create(**{
         models.User.mail_address.name: user.email,
         models.User.username.name: user.email,
     }, defaults={
         models.User.fullname.name: f'{user.name}',
         models.User.role.name: models.Role.get_student_role(),
         models.User.password.name: user.password,
     })
Exemple #4
0
def _add_course_and_numbers_to_exercises_table(
    table: Model,
    course: models.Course,
) -> None:
    log.info(
        'Adding Course, Numbers for exercises, might take some extra time...',
    )
    with db_config.database.transaction():
        for exercise in table:
            exercise.number = exercise.id
            exercise.course = course
            exercise.save()
Exemple #5
0
def _add_user_course_constaint() -> bool:
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        try:
            migrate(
                migrator.add_index(
                    'usercourse',
                    ('user_id', 'course_id'),
                    True,
                ), )
        except (OperationalError, ProgrammingError) as e:
            log.info(f'Index usercourse user and course already exists: {e}')
        db_config.database.commit()
Exemple #6
0
def _add_exercise_course_id_and_number_columns_constraint() -> bool:
    Exercise = models.Exercise
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        _add_not_null_column(Exercise, Exercise.course)
        _add_not_null_column(Exercise, Exercise.number)
        try:
            migrate(
                migrator.add_index('exercise', ('course_id', 'number'),
                                   True), )
        except (OperationalError, ProgrammingError) as e:
            log.info(f'Index exercise course and number already exists: {e}')
        db_config.database.commit()
Exemple #7
0
def _drop_constraint_if_needed(table: Type[Model], column_name: str) -> bool:
    table_name = table.__name__.lower()
    cols = {col.name for col in db_config.database.get_columns(table_name)}

    if column_name not in cols:
        log.info(f'Column {column_name} not exists in {table}')
        return False

    log.info(f'Drop foreign key on {table}.{column_name}')
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        migrate(migrator.drop_constraint(table_name, column_name))
        db_config.database.commit()
    return True
Exemple #8
0
def _add_not_null_column(
    table: Model, column: Field,
    run_before_adding_not_null: Callable[[Model, Field], None] = None,
) -> bool:
    already_exists, table_name, column_name = get_details(table, column)
    log.info(f'Adding {table_name}.{column_name}, if needed.')
    if already_exists:
        log.info(f'Column {column_name} already exists in {table_name}.')
        return False

    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        column.null = True
        migrate(migrator.add_column(table_name, column_name, field=column))
        if callable(run_before_adding_not_null):
            run_before_adding_not_null(table, column)
        migrate(migrator.drop_not_null(table_name, column_name))
        db_config.database.commit()
    return True
Exemple #9
0
 def __enter__(self):
     args = (
         'docker',
         'run',
         '-d',
         '--memory',
         self.memory_limit,
         '--cpus',
         self.cpu_limit,
         '--network',
         'none',
         '--rm',
         '--name',
         self._container_name,
         self.base_image,
         'sleep',
         str(self.timeout_seconds),
     )
     log.info('Start executing safe container context with %s', args)
     subprocess.check_call(args)  # NOQA: S603
     return self
Exemple #10
0
def _migrate_column_in_table_if_needed(
    table: Type[Model],
    field_instance: Field,
    *,
    field_name: Optional[str] = None,
    **kwargs: Any,
) -> bool:
    column_name = field_name or field_instance.name
    table_name = table.__name__.lower()
    cols = {col.name for col in db_config.database.get_columns(table_name)}

    if column_name in cols:
        log.info(f'Column {column_name} already exists in {table}')
        return False

    log.info(f'Create {column_name} field in {table}')
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        try:
            migrate(
                migrator.add_column(
                    table=table_name,
                    column_name=column_name,
                    field=field_instance,
                    **kwargs,
                ))
        except (OperationalError, ProgrammingError) as e:
            if 'does not exist' in str(e):
                log.info(f'Column {field_name} already exists: {e}')
            else:
                raise
        db_config.database.commit()
    return True
Exemple #11
0
def _rename_column_in_table_if_needed(
    table: Type[Model],
    old_column_name: str,
    new_column_name: str,
) -> bool:
    column_name = old_column_name.lower()
    table_name = table.__name__.lower()
    cols = {col.name for col in db_config.database.get_columns(table_name)}

    if new_column_name in cols:
        log.info(f'Column {new_column_name} already exists in {table}')
        return False
    if old_column_name not in cols:
        log.info(f'Column {old_column_name} not exists in {table}')
        return False

    log.info(f'Changing {column_name} -> {new_column_name} in {table}')
    migrator = db_config.get_migrator_instance()
    with db_config.database.transaction():
        migrate(
            migrator.rename_column(
                table_name,
                old_column_name,
                new_column_name,
            ), )
        db_config.database.commit()
    return True
Exemple #12
0
def register_test_class(file_path: str, test_class: typing.ClassVar):
    subject = test_class.__doc__
    exercise = models.Exercise.get_or_none(models.Exercise.subject == subject)
    if not exercise:
        log.info(f'Failed to find exercise subject {subject}')
        raise SystemError

    with open(file_path, 'r') as file_reader:
        code = file_reader.read()

    exercise_test = models.ExerciseTest.get_or_create_exercise_test(
        exercise=exercise,
        code=code,
    )

    for test_func_name in inspect.getmembers(test_class):
        test_func_name = test_func_name[0]
        if test_func_name.startswith('test_'):
            test_func = getattr(test_class, test_func_name)
            models.ExerciseTestName.create_exercise_test_name(
                exercise_test=exercise_test,
                test_name=test_func_name,
                pretty_test_name=test_func.__doc__,
            )
Exemple #13
0
def ratelimit_handler(e):
    log.info(f'IP Address: {get_remote_address()}: {e}')
    return make_response(
        jsonify(error='ratelimit exceeded %s' % e.description), 429,
    )
Exemple #14
0
def _add_uuid_to_users_table(table: Model, _column: Field) -> None:
    log.info('Adding UUIDs for all users, might take some extra time...')
    with db_config.database.transaction():
        for user in table:
            user.uuid = uuid4()
            user.save()
Exemple #15
0
def _create_usercourses_objects(table: Model, course: models.Course) -> None:
    log.info('Adding UserCourse for all users, might take some extra time...')
    UserCourse = models.UserCourse
    with db_config.database.transaction():
        for user in table:
            UserCourse.create(user=user, course=course)
Exemple #16
0
def _add_api_keys_to_users_table(table: Model, _column: Field) -> None:
    log.info('Adding API Keys for all users, might take some extra time...')
    with db_config.database.transaction():
        for user in table:
            user.api_key = table.random_password(stronger=True)
            user.save()