-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathSetProblem.pm
More file actions
139 lines (95 loc) · 3.01 KB
/
SetProblem.pm
File metadata and controls
139 lines (95 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package DB::Schema::Result::SetProblem;
use DBIx::Class::Core;
use strict;
use warnings;
use feature 'signatures';
no warnings qw/experimental::signatures/;
use base qw/DBIx::Class::Core DB::Validation/;
=head1 DESCRIPTION
This is the database schema for a SetProblem. Note: this table has two purposes 1) a relationship table linking
the course and user tables (many-to-many) and 2) storing information about the user in the given course.
=head2 fields
=over
=item *
C<set_problem_id>: database id (primary key, autoincrement integer)
=item *
C<set_id>: the database id of the set the problem is in (foreign key)
=item *
C<problem_number>: the number of the problem (integer, non-negative?)
=item *
C<problem_params>: a JSON object storing parameters. These are:
=over
=item *
C<weight>: the weight of a problem (nonnegative integer)
=item *
C<library_id>: a database id of the problem (foreign key)
=item *
C<problem_path>: alternatively, the path of the problem
=item *
C<problem_pool_id>: if part of a problem pool, the database id of it (foreign key)
=back
=back
=head4
Note: a problem should have only one of a library_id, problem_path or problem_pool_id
=cut
# This is the table that stores problems for a given Problem Set.
__PACKAGE__->table('set_problem');
__PACKAGE__->load_components(qw/InflateColumn::Serializer Core/);
__PACKAGE__->add_columns(
set_problem_id => {
data_type => 'integer',
size => 16,
is_auto_increment => 1,
},
set_id => {
data_type => 'integer',
size => 16,
},
problem_number => {
data_type => 'integer',
size => 16,
is_nullable => 1,
},
# Store params as a JSON object.
problem_params => {
data_type => 'text',
size => 256,
default_value => '{}',
retrieve_on_insert => 1,
serializer_class => 'JSON',
serializer_options => { utf8 => 1 }
}
);
__PACKAGE__->set_primary_key('set_problem_id');
# Maybe we don't need this.
__PACKAGE__->add_unique_constraint([qw/set_problem_id set_id problem_number/]);
__PACKAGE__->belongs_to(problem_set => 'DB::Schema::Result::ProblemSet', 'set_id');
__PACKAGE__->has_many(user_problems => 'DB::Schema::Result::UserProblem', 'set_problem_id');
=head2 C<valid_fields>
subroutine that returns a hash of the valid fields for json columns
=cut
sub valid_fields ($, $column_name) {
if ($column_name eq 'problem_params') {
return {
weight => q{^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$}, # positive integers or decimals
library_id => q{\d+},
file_path => q{.*},
problem_pool_id => q{\d+},
max_attempts => q{-?\d+}
};
} else {
return {};
}
}
=head2 C<required>
subroutine that returns a hashref describing the required fields in JSON columns
=cut
sub required ($, $column_name) {
if ($column_name eq 'problem_params') {
# TODO: ultimately we only want '_ONE_OF_' the problem_sources
return { '_ALL_' => [ 'weight', { '_AT_LEAST_ONE_OF_' => [ 'library_id', 'file_path', 'problem_pool_id' ] } ] };
} else {
return {};
}
}
1;