143 |
"the project `#{project}' is present" |
"the project `#{project}' is present" |
144 |
end |
end |
145 |
q("INSERT INTO projects VALUES ('#{e(project)}', NOW())") |
q("INSERT INTO projects VALUES ('#{e(project)}', NOW())") |
146 |
q("CREATE TABLE #{e(bug_table(project))} ( \ |
q("CREATE TABLE `#{e(bug_table(project))}` ( \ |
147 |
bug_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, \ |
bug_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, \ |
148 |
ctime DATETIME NOT NULL, \ |
ctime DATETIME NOT NULL, \ |
149 |
mtime DATETIME NOT NULL, \ |
mtime DATETIME NOT NULL, \ |
152 |
tf_summary TINYTEXT NOT NULL, \ |
tf_summary TINYTEXT NOT NULL, \ |
153 |
tf_message MEDIUMTEXT NOT NULL \ |
tf_message MEDIUMTEXT NOT NULL \ |
154 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
155 |
q("CREATE TABLE #{e(attachment_table(project))} ( \ |
q("CREATE TABLE `#{e(attachment_table(project))}` ( \ |
156 |
bug_id INT UNSIGNED PRIMARY KEY, \ |
bug_id INT UNSIGNED PRIMARY KEY, \ |
157 |
name TINYTEXT NOT NULL, \ |
name TINYTEXT NOT NULL, \ |
158 |
content_type TINYTEXT NOT NULL, \ |
content_type TINYTEXT NOT NULL, \ |
160 |
size MEDIUMINT UNSIGNED NOT NULL, \ |
size MEDIUMINT UNSIGNED NOT NULL, \ |
161 |
contents MEDIUMBLOB NOT NULL \ |
contents MEDIUMBLOB NOT NULL \ |
162 |
) TYPE = InnoDB ") |
) TYPE = InnoDB ") |
163 |
q("CREATE TABLE #{e(followup_table(project))} ( \ |
q("CREATE TABLE `#{e(followup_table(project))}` ( \ |
164 |
f_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, \ |
f_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, \ |
165 |
bug_id INT UNSIGNED NOT NULL, \ |
bug_id INT UNSIGNED NOT NULL, \ |
166 |
message MEDIUMTEXT NOT NULL \, |
message MEDIUMTEXT NOT NULL \, |
167 |
first_text MEDIUMTEXT NOT NULL |
first_text MEDIUMTEXT NOT NULL |
168 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
169 |
q("CREATE TABLE #{e(sf_table(project))} ( \ |
q("CREATE TABLE `#{e(sf_table(project))}` ( \ |
170 |
name VARCHAR(#{MAX_FIELD_NAME}) PRIMARY KEY, \ |
name VARCHAR(#{MAX_FIELD_NAME}) PRIMARY KEY, \ |
171 |
display_name TINYBLOB NOT NULL, \ |
display_name TINYBLOB NOT NULL, \ |
172 |
note TINYBLOB NOT NULL, \ |
note TINYBLOB NOT NULL, \ |
178 |
always_set BOOL NOT NULL, \ |
always_set BOOL NOT NULL, \ |
179 |
priority TINYINT NOT NULL \ |
priority TINYINT NOT NULL \ |
180 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
181 |
q("INSERT INTO #{e(sf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(sf_table(project))}` VALUES ( \ |
182 |
'status', 'Status', '', 1, 1, 0, 1, 'open,closed,deleted', 1, -100 \ |
'status', 'Status', '', 1, 1, 0, 1, 'open,closed,deleted', 1, -100 \ |
183 |
)") |
)") |
184 |
q("CREATE TABLE #{e(tf_table(project))} ( \ |
q("CREATE TABLE `#{e(tf_table(project))}` ( \ |
185 |
name VARCHAR(#{MAX_FIELD_NAME}) PRIMARY KEY, \ |
name VARCHAR(#{MAX_FIELD_NAME}) PRIMARY KEY, \ |
186 |
display_name TINYBLOB NOT NULL, \ |
display_name TINYBLOB NOT NULL, \ |
187 |
note TINYBLOB NOT NULL, \ |
note TINYBLOB NOT NULL, \ |
195 |
searched_by_default BOOL NOT NULL, \ |
searched_by_default BOOL NOT NULL, \ |
196 |
priority TINYINT NOT NULL \ |
priority TINYINT NOT NULL \ |
197 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
198 |
q("INSERT INTO #{e(tf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(tf_table(project))}` VALUES ( \ |
199 |
'reporter', 'Reporter', 'Input your e-mail address.', \ |
'reporter', 'Reporter', 'Input your e-mail address.', \ |
200 |
0, 1, 1, 1, 0, 0, '', 0, -100 \ |
0, 1, 1, 1, 0, 0, '', 0, -100 \ |
201 |
)") |
)") |
202 |
q("INSERT INTO #{e(tf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(tf_table(project))}` VALUES ( \ |
203 |
'summary', 'Summary', 'Write a short description.', \ |
'summary', 'Summary', 'Write a short description.', \ |
204 |
0, 1, 1, 1, 0, 0, '', 1, -80 \ |
0, 1, 1, 1, 0, 0, '', 1, -80 \ |
205 |
)") |
)") |
206 |
q("INSERT INTO #{e(tf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(tf_table(project))}` VALUES ( \ |
207 |
'message', 'Message', 'Write a long description.', \ |
'message', 'Message', 'Write a long description.', \ |
208 |
0, 1, 1, 1, 0, 1, '', 1, -60 \ |
0, 1, 1, 1, 0, 1, '', 1, -60 \ |
209 |
)") |
)") |
210 |
q("CREATE TABLE #{e(admins_table(project))} ( \ |
q("CREATE TABLE `#{e(admins_table(project))}` ( \ |
211 |
address VARCHAR(255) PRIMARY KEY \ |
address VARCHAR(255) PRIMARY KEY \ |
212 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
213 |
admins.each do |a| |
admins.each do |a| |
214 |
q("INSERT INTO #{e(admins_table(project))} VALUES ('#{e(a)}')") |
q("INSERT INTO `#{e(admins_table(project))}` VALUES ('#{e(a)}')") |
215 |
end |
end |
216 |
q("CREATE TABLE #{e(lists_table(project))} ( \ |
q("CREATE TABLE `#{e(lists_table(project))}` ( \ |
217 |
address VARCHAR(255) PRIMARY KEY \ |
address VARCHAR(255) PRIMARY KEY \ |
218 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
219 |
lists.each do |l| |
lists.each do |l| |
220 |
q("INSERT INTO #{e(lists_table(project))} VALUES ('#{e(l)}')") |
q("INSERT INTO `#{e(lists_table(project))}` VALUES ('#{e(l)}')") |
221 |
end |
end |
222 |
q("CREATE TABLE #{e(config_table(project))} ( \ |
q("CREATE TABLE `#{e(config_table(project))}` ( \ |
223 |
name VARCHAR(255) PRIMARY KEY, \ |
name VARCHAR(255) PRIMARY KEY, \ |
224 |
val TINYBLOB NOT NULL \ |
val TINYBLOB NOT NULL \ |
225 |
) TYPE = InnoDB") |
) TYPE = InnoDB") |
231 |
"the project `#{project}' doesn't exist any longer" |
"the project `#{project}' doesn't exist any longer" |
232 |
end |
end |
233 |
q("DELETE FROM projects WHERE name = '#{e(project)}'") |
q("DELETE FROM projects WHERE name = '#{e(project)}'") |
234 |
q("DROP TABLE #{e(bug_table(project))}, \ |
q("DROP TABLE `#{e(bug_table(project))}`, \ |
235 |
#{e(attachment_table(project))}, \ |
`#{e(attachment_table(project))}`, \ |
236 |
#{e(followup_table(project))}, \ |
`#{e(followup_table(project))}`, \ |
237 |
#{e(sf_table(project))}, \ |
`#{e(sf_table(project))}`, \ |
238 |
#{e(tf_table(project))}, \ |
`#{e(tf_table(project))}`, \ |
239 |
#{e(admins_table(project))}, \ |
`#{e(admins_table(project))}`, \ |
240 |
#{e(lists_table(project))}") |
`#{e(lists_table(project))}`") |
241 |
end |
end |
242 |
|
|
243 |
def config_project(project, actions) |
def config_project(project, actions) |
256 |
removed = action.old_admins - action.new_admins |
removed = action.old_admins - action.new_admins |
257 |
added = action.new_admins - action.old_admins |
added = action.new_admins - action.old_admins |
258 |
unless removed.empty? |
unless removed.empty? |
259 |
q("DELETE FROM #{e(admins_table(project))} WHERE address IN (" + |
q("DELETE FROM `#{e(admins_table(project))}` WHERE address IN (" + |
260 |
removed.collect {|a| "'#{e(a)}'"}.join(',') + |
removed.collect {|a| "'#{e(a)}'"}.join(',') + |
261 |
")") |
")") |
262 |
end |
end |
263 |
unless added.empty? |
unless added.empty? |
264 |
q("INSERT INTO #{e(admins_table(project))} VALUES (" + |
q("INSERT INTO `#{e(admins_table(project))}` VALUES (" + |
265 |
added.collect {|a| "'#{e(a)}'"}.join('),(') + |
added.collect {|a| "'#{e(a)}'"}.join('),(') + |
266 |
")") |
")") |
267 |
end |
end |
274 |
removed = action.old_lists - action.new_lists |
removed = action.old_lists - action.new_lists |
275 |
added = action.new_lists - action.old_lists |
added = action.new_lists - action.old_lists |
276 |
unless removed.empty? |
unless removed.empty? |
277 |
q("DELETE FROM #{e(lists_table(project))} WHERE address IN (" + |
q("DELETE FROM `#{e(lists_table(project))}` WHERE address IN (" + |
278 |
removed.collect {|a| "'#{e(a)}'"}.join(',') + |
removed.collect {|a| "'#{e(a)}'"}.join(',') + |
279 |
")") |
")") |
280 |
end |
end |
281 |
unless added.empty? |
unless added.empty? |
282 |
q("INSERT INTO #{e(lists_table(project))} VALUES (" + |
q("INSERT INTO `#{e(lists_table(project))}` VALUES (" + |
283 |
added.collect {|a| "'#{e(a)}'"}.join('),(') + |
added.collect {|a| "'#{e(a)}'"}.join('),(') + |
284 |
")") |
")") |
285 |
end |
end |
298 |
"the selection field `#{old_f.name}' was modified after the request" |
"the selection field `#{old_f.name}' was modified after the request" |
299 |
end |
end |
300 |
keywords = new_f.keywords.join(',') |
keywords = new_f.keywords.join(',') |
301 |
q("UPDATE #{e(sf_table(project))} SET \ |
q("UPDATE `#{e(sf_table(project))}` SET \ |
302 |
display_name='#{e(new_f.display_name)}', \ |
display_name='#{e(new_f.display_name)}', \ |
303 |
note='#{e(new_f.note)}', \ |
note='#{e(new_f.note)}', \ |
304 |
admin_only=#{if new_f.admin_only? then 1 else 0 end}, \ |
admin_only=#{if new_f.admin_only? then 1 else 0 end}, \ |
316 |
raise MalformedDataError, |
raise MalformedDataError, |
317 |
"the text field `#{old_f.name}' was modified after the request" |
"the text field `#{old_f.name}' was modified after the request" |
318 |
end |
end |
319 |
q("UPDATE #{e(tf_table(project))} SET \ |
q("UPDATE `#{e(tf_table(project))}` SET \ |
320 |
display_name='#{e(new_f.display_name)}', \ |
display_name='#{e(new_f.display_name)}', \ |
321 |
note='#{e(new_f.note)}', \ |
note='#{e(new_f.note)}', \ |
322 |
admin_only=#{if new_f.admin_only? then 1 else 0 end}, \ |
admin_only=#{if new_f.admin_only? then 1 else 0 end}, \ |
327 |
test_re='#{e(new_f.regexp)}' \ |
test_re='#{e(new_f.regexp)}' \ |
328 |
WHERE name = '#{e(new_f.name)}'") |
WHERE name = '#{e(new_f.name)}'") |
329 |
if f.multiple_lines != new_f.multiple_lines |
if f.multiple_lines != new_f.multiple_lines |
330 |
q("ALTER TABLE #{e(bug_table(project))} MODIFY \ |
q("ALTER TABLE `#{e(bug_table(project))}` MODIFY \ |
331 |
tf_#{e(new_f.name)} " + |
tf_#{e(new_f.name)} " + |
332 |
if new_f.multiple_lines? |
if new_f.multiple_lines? |
333 |
'MEDIUMTEXT' |
'MEDIUMTEXT' |
346 |
case f |
case f |
347 |
when SelectionField |
when SelectionField |
348 |
keywords = f.keywords.join(',') |
keywords = f.keywords.join(',') |
349 |
q("INSERT INTO #{e(sf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(sf_table(project))}` VALUES ( \ |
350 |
'#{e(f.name)}', '#{e(f.display_name)}', '#{e(f.note)}', \ |
'#{e(f.name)}', '#{e(f.display_name)}', '#{e(f.note)}', \ |
351 |
#{if f.admin_only? then 1 else 0 end}, \ |
#{if f.admin_only? then 1 else 0 end}, \ |
352 |
#{if f.searchable? then 1 else 0 end}, \ |
#{if f.searchable? then 1 else 0 end}, \ |
356 |
#{if f.always_set? then 1 else 0 end}, \ |
#{if f.always_set? then 1 else 0 end}, \ |
357 |
0 \ |
0 \ |
358 |
)") |
)") |
359 |
q("ALTER TABLE #{e(bug_table(project))} ADD \ |
q("ALTER TABLE `#{e(bug_table(project))}` ADD \ |
360 |
sf_#{e(f.name)} TINYTEXT NOT NULL") |
sf_#{e(f.name)} TINYTEXT NOT NULL") |
361 |
else |
else |
362 |
q("INSERT INTO #{e(tf_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(tf_table(project))}` VALUES ( \ |
363 |
'#{e(f.name)}', '#{e(f.display_name)}', '#{e(f.note)}', \ |
'#{e(f.name)}', '#{e(f.display_name)}', '#{e(f.note)}', \ |
364 |
#{if f.admin_only? then 1 else 0 end}, \ |
#{if f.admin_only? then 1 else 0 end}, \ |
365 |
#{if f.searchable? then 1 else 0 end}, \ |
#{if f.searchable? then 1 else 0 end}, \ |
371 |
#{if f.searched_by_default? then 1 else 0 end}, \ |
#{if f.searched_by_default? then 1 else 0 end}, \ |
372 |
0 \ |
0 \ |
373 |
)") |
)") |
374 |
q("ALTER TABLE #{e(bug_table(project))} ADD \ |
q("ALTER TABLE `#{e(bug_table(project))}` ADD \ |
375 |
tf_#{e(f.name)} " + |
tf_#{e(f.name)} " + |
376 |
if f.multiple_lines? then 'MEDIUMTEXT' else 'TINYTEXT' end + |
if f.multiple_lines? then 'MEDIUMTEXT' else 'TINYTEXT' end + |
377 |
' NOT NULL') |
' NOT NULL') |
389 |
raise MalformedDataError, |
raise MalformedDataError, |
390 |
"the selection field `#{f.name}' was modified after the request" |
"the selection field `#{f.name}' was modified after the request" |
391 |
end |
end |
392 |
q("DELETE FROM #{e(sf_table(project))} WHERE \ |
q("DELETE FROM `#{e(sf_table(project))}` WHERE \ |
393 |
name = '#{e(f.name)}'") |
name = '#{e(f.name)}'") |
394 |
q("ALTER TABLE #{e(bug_table(project))} DROP sf_#{e(f.name)}") |
q("ALTER TABLE `#{e(bug_table(project))}` DROP sf_#{e(f.name)}") |
395 |
when TextField |
when TextField |
396 |
tmp = text_field(project, f.name) |
tmp = text_field(project, f.name) |
397 |
if tmp.nil? |
if tmp.nil? |
402 |
"the text field `#{f.name}' was modified after the request" |
"the text field `#{f.name}' was modified after the request" |
403 |
end |
end |
404 |
|
|
405 |
q("DELETE FROM #{e(tf_table(project))} WHERE \ |
q("DELETE FROM `#{e(tf_table(project))}` WHERE \ |
406 |
name = '#{e(f.name)}'") |
name = '#{e(f.name)}'") |
407 |
q("ALTER TABLE #{e(bug_table(project))} DROP tf_#{e(f.name)}") |
q("ALTER TABLE `#{e(bug_table(project))}` DROP tf_#{e(f.name)}") |
408 |
end |
end |
409 |
|
|
410 |
else |
else |
424 |
selection_fields = selection_fields(project) |
selection_fields = selection_fields(project) |
425 |
text_fields = text_fields(project) |
text_fields = text_fields(project) |
426 |
|
|
427 |
q("UPDATE #{e(bug_table(project))} SET mtime=NOW() \ |
q("UPDATE `#{e(bug_table(project))}` SET mtime=NOW() \ |
428 |
WHERE bug_id = #{e(bug_id.to_s)}") |
WHERE bug_id = #{e(bug_id.to_s)}") |
429 |
actions.each do |action| |
actions.each do |action| |
430 |
f = selection_fields.detect {|f| f.name == action.name} or |
f = selection_fields.detect {|f| f.name == action.name} or |
448 |
raise MalformedRequestError, |
raise MalformedRequestError, |
449 |
"invalid value `#{val}' for the selection field `#{f.name}'" |
"invalid value `#{val}' for the selection field `#{f.name}'" |
450 |
end |
end |
451 |
q("UPDATE #{e(bug_table(project))} SET sf_#{e(f.name)}='#{e(val)}' \ |
q("UPDATE `#{e(bug_table(project))}` SET sf_#{e(f.name)}='#{e(val)}' \ |
452 |
WHERE bug_id = #{e(bug_id.to_s)}") |
WHERE bug_id = #{e(bug_id.to_s)}") |
453 |
|
|
454 |
when TextField |
when TextField |
476 |
"too long text for the text field `#{f.name}'" |
"too long text for the text field `#{f.name}'" |
477 |
end |
end |
478 |
end |
end |
479 |
q("UPDATE #{e(bug_table(project))} SET tf_#{e(f.name)}='#{e(val)}' \ |
q("UPDATE `#{e(bug_table(project))}` SET tf_#{e(f.name)}='#{e(val)}' \ |
480 |
WHERE bug_id = #{e(bug_id.to_s)}") |
WHERE bug_id = #{e(bug_id.to_s)}") |
481 |
end |
end |
482 |
end |
end |
483 |
end |
end |
484 |
|
|
485 |
def selection_field(project, name) |
def selection_field(project, name) |
486 |
q("SELECT * FROM #{e(sf_table(project))} WHERE name = '#{e(name)}' \ |
q("SELECT * FROM `#{e(sf_table(project))}` WHERE name = '#{e(name)}' \ |
487 |
FOR UPDATE") |
FOR UPDATE") |
488 |
a = r().fetch_row() |
a = r().fetch_row() |
489 |
return nil if a.nil? |
return nil if a.nil? |
494 |
end |
end |
495 |
|
|
496 |
def selection_field?(project, name) |
def selection_field?(project, name) |
497 |
q("SELECT * FROM #{e(sf_table(project))} WHERE name = '#{e(name)}' \ |
q("SELECT * FROM `#{e(sf_table(project))}` WHERE name = '#{e(name)}' \ |
498 |
FOR UPDATE") |
FOR UPDATE") |
499 |
case r().num_rows() |
case r().num_rows() |
500 |
when 0 |
when 0 |
507 |
end |
end |
508 |
|
|
509 |
def text_field(project, name) |
def text_field(project, name) |
510 |
q("SELECT * FROM #{e(tf_table(project))} WHERE name = '#{e(name)}' \ |
q("SELECT * FROM `#{e(tf_table(project))}` WHERE name = '#{e(name)}' \ |
511 |
FOR UPDATE") |
FOR UPDATE") |
512 |
a = r().fetch_row() |
a = r().fetch_row() |
513 |
return nil if a.nil? |
return nil if a.nil? |
518 |
end |
end |
519 |
|
|
520 |
def text_field?(project, name) |
def text_field?(project, name) |
521 |
q("SELECT * FROM #{e(tf_table(project))} WHERE name = '#{e(name)}' \ |
q("SELECT * FROM `#{e(tf_table(project))}` WHERE name = '#{e(name)}' \ |
522 |
FOR UPDATE") |
FOR UPDATE") |
523 |
case r().num_rows() |
case r().num_rows() |
524 |
when 0 |
when 0 |
581 |
end |
end |
582 |
|
|
583 |
def add_followup(project, bug_id, message) |
def add_followup(project, bug_id, message) |
584 |
q("SELECT bug_id FROM #{e(bug_table(project))} \ |
q("SELECT bug_id `FROM #{e(bug_table(project))}` \ |
585 |
WHERE bug_id = #{e(bug_id.to_s)} FOR UPDATE") |
WHERE bug_id = #{e(bug_id.to_s)} FOR UPDATE") |
586 |
case r().num_rows() |
case r().num_rows() |
587 |
when 1 |
when 1 |
592 |
end |
end |
593 |
|
|
594 |
first_text = Followup.new(nil, bug_id, message).text() |
first_text = Followup.new(nil, bug_id, message).text() |
595 |
q("INSERT INTO #{e(followup_table(project))} \ |
q("INSERT INTO `#{e(followup_table(project))}` \ |
596 |
(bug_id, message, first_text) \ |
(bug_id, message, first_text) \ |
597 |
VALUES (#{e(bug_id.to_s)}, '#{e(message)}', '#{e(first_text)}')") |
VALUES (#{e(bug_id.to_s)}, '#{e(message)}', '#{e(first_text)}')") |
598 |
q("UPDATE #{e(bug_table(project))} SET mtime=NOW() \ |
q("UPDATE `#{e(bug_table(project))}` SET mtime=NOW() \ |
599 |
WHERE bug_id = #{e(bug_id.to_s)}") |
WHERE bug_id = #{e(bug_id.to_s)}") |
600 |
end |
end |
601 |
|
|
643 |
# If followups are searched, get the list of matched bugs. |
# If followups are searched, get the list of matched bugs. |
644 |
list = nil |
list = nil |
645 |
if (not keywords.empty?) and followups |
if (not keywords.empty?) and followups |
646 |
q("SELECT DISTINCT bug_id FROM #{e(followup_table(project))} WHERE " + |
q("SELECT DISTINCT bug_id FROM `#{e(followup_table(project))}` WHERE " + |
647 |
keywords.collect {|k| |
keywords.collect {|k| |
648 |
"(first_text LIKE '%#{e(k)}%')" |
"(first_text LIKE '%#{e(k)}%')" |
649 |
}.join(' AND ')) |
}.join(' AND ')) |
686 |
|
|
687 |
# Because of the limitation of SQL, need to query the number of |
# Because of the limitation of SQL, need to query the number of |
688 |
# matching rows separately. |
# matching rows separately. |
689 |
q("SELECT COUNT(*) FROM #{e(bug_table(project))}" + |
q("SELECT COUNT(*) FROM `#{e(bug_table(project))}`" + |
690 |
cond + |
cond + |
691 |
' LOCK IN SHARE MODE') |
' LOCK IN SHARE MODE') |
692 |
size = r().fetch_row().first.to_i - offset |
size = r().fetch_row().first.to_i - offset |
693 |
|
|
694 |
q("SELECT * FROM #{e(bug_table(project))}" + |
q("SELECT * FROM `#{e(bug_table(project))}`" + |
695 |
cond + |
cond + |
696 |
" ORDER BY bug_id LIMIT #{offset}, #{max} LOCK IN SHARE MODE") |
" ORDER BY bug_id LIMIT #{offset}, #{max} LOCK IN SHARE MODE") |
697 |
|
|
732 |
end |
end |
733 |
values += tf.collect {|f| if v = bug[f.name] then e(v) else '' end} |
values += tf.collect {|f| if v = bug[f.name] then e(v) else '' end} |
734 |
|
|
735 |
q("INSERT INTO #{e(bug_table(project))} (ctime, mtime, " + |
q("INSERT INTO `#{e(bug_table(project))}` (ctime, mtime, " + |
736 |
names.join(', ') + |
names.join(', ') + |
737 |
') VALUES (NOW(), NOW(), ' + |
') VALUES (NOW(), NOW(), ' + |
738 |
values.collect {|v| "'#{v}'"}.join(', ') + |
values.collect {|v| "'#{v}'"}.join(', ') + |
741 |
|
|
742 |
if bug.has_attachment? |
if bug.has_attachment? |
743 |
a = bug.attachment |
a = bug.attachment |
744 |
q("INSERT INTO #{e(attachment_table(project))} VALUES ( \ |
q("INSERT INTO `#{e(attachment_table(project))}` VALUES ( \ |
745 |
#{bug_id}, '#{e(a.name)}', '#{e(a.content_type)}', \ |
#{bug_id}, '#{e(a.name)}', '#{e(a.content_type)}', \ |
746 |
'#{e(a.description)}', #{a.size}, '#{e(a.contents)}' \ |
'#{e(a.description)}', #{a.size}, '#{e(a.contents)}' \ |
747 |
)") |
)") |
751 |
end |
end |
752 |
|
|
753 |
def selection_fields(project) |
def selection_fields(project) |
754 |
q("SELECT * FROM #{e(sf_table(project))} ORDER BY priority \ |
q("SELECT * FROM `#{e(sf_table(project))}` ORDER BY priority \ |
755 |
LOCK IN SHARE MODE") |
LOCK IN SHARE MODE") |
756 |
r().collect do |a| |
r().collect do |a| |
757 |
SelectionField.new(a[0], a[1], a[2], |
SelectionField.new(a[0], a[1], a[2], |
762 |
end |
end |
763 |
|
|
764 |
def text_fields(project) |
def text_fields(project) |
765 |
q("SELECT * FROM #{e(tf_table(project))} ORDER BY priority \ |
q("SELECT * FROM `#{e(tf_table(project))}` ORDER BY priority \ |
766 |
LOCK IN SHARE MODE") |
LOCK IN SHARE MODE") |
767 |
r().collect do |a| |
r().collect do |a| |
768 |
TextField.new(a[0], a[1], a[2], |
TextField.new(a[0], a[1], a[2], |
773 |
end |
end |
774 |
|
|
775 |
def admins(project, exclusive = false) |
def admins(project, exclusive = false) |
776 |
q("SELECT * FROM #{e(admins_table(project))} ORDER BY address " + |
q("SELECT * FROM `#{e(admins_table(project))}` ORDER BY address " + |
777 |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
778 |
r().collect {|a| a[0]} |
r().collect {|a| a[0]} |
779 |
end |
end |
780 |
|
|
781 |
def lists(project, exclusive = false) |
def lists(project, exclusive = false) |
782 |
q("SELECT * FROM #{e(lists_table(project))} ORDER BY address " + |
q("SELECT * FROM `#{e(lists_table(project))}` ORDER BY address " + |
783 |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
784 |
r().collect {|a| a[0]} |
r().collect {|a| a[0]} |
785 |
end |
end |
786 |
|
|
787 |
def bug(project, bug_id, exclusive = false) |
def bug(project, bug_id, exclusive = false) |
788 |
q("SELECT * FROM #{e(bug_table(project))} WHERE \ |
q("SELECT * FROM `#{e(bug_table(project))}` WHERE \ |
789 |
bug_id = #{e(bug_id.to_s)} " + |
bug_id = #{e(bug_id.to_s)} " + |
790 |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
if exclusive then 'FOR UPDATE' else 'LOCK IN SHARE MODE' end) |
791 |
h = r().fetch_hash() |
h = r().fetch_hash() |
800 |
end |
end |
801 |
end |
end |
802 |
|
|
803 |
q("SELECT * FROM #{e(attachment_table(project))} WHERE \ |
q("SELECT * FROM `#{e(attachment_table(project))}` WHERE \ |
804 |
bug_id = #{e(bug_id.to_s)} LOCK IN SHARE MODE") |
bug_id = #{e(bug_id.to_s)} LOCK IN SHARE MODE") |
805 |
a = r().fetch_row() |
a = r().fetch_row() |
806 |
attachment = if a |
attachment = if a |
809 |
nil |
nil |
810 |
end |
end |
811 |
|
|
812 |
q("SELECT f_id FROM #{e(followup_table(project))} WHERE \ |
q("SELECT f_id FROM `#{e(followup_table(project))}` WHERE \ |
813 |
bug_id = #{e(bug_id.to_s)} LOCK IN SHARE MODE") |
bug_id = #{e(bug_id.to_s)} LOCK IN SHARE MODE") |
814 |
f_ids = r().collect {|a| a[0]} |
f_ids = r().collect {|a| a[0]} |
815 |
|
|
818 |
end |
end |
819 |
|
|
820 |
def followup(project, f_id) |
def followup(project, f_id) |
821 |
q("SELECT bug_id, message FROM #{e(followup_table(project))} WHERE \ |
q("SELECT bug_id, message FROM `#{e(followup_table(project))}` WHERE \ |
822 |
f_id = '#{e(f_id.to_s)}' LOCK IN SHARE MODE") |
f_id = '#{e(f_id.to_s)}' LOCK IN SHARE MODE") |
823 |
a = r().fetch_row() |
a = r().fetch_row() |
824 |
Followup.new(f_id, a[0].to_i, a[1]) |
Followup.new(f_id, a[0].to_i, a[1]) |