indexing description: "Provide an interface to issue data." author: "Peter Wyss " date: "$Date: 2007-07-14 03:45:53 +0200 (Sat, 14 Jul 2007) $" revision: "$Revision: 509 $" class ISSUE_INTERFACE inherit BASE_INTERFACE redefine make end O_WORKITEM_CONSTANTS O_CONSTANTS create make feature {NONE} -- Initialization make (a_node: like node; a_db_handler: like db_handler; a_policy_cache: like policy_cache) is -- Initialize. do Precursor (a_node, a_db_handler, a_policy_cache) end feature -- Commands issue_add (a_msg: O_MESSAGE) is -- Add a new issue and issue workitem according to a_msg. require a_msg_ok: a_msg /= Void local l_pc_msg: O_ISSUE_ADD_MESSAGE l_workitem: WORKITEM l_workitem_issue: WORKITEM_ISSUE l_issue: ISSUE l_issue_revision: ISSUE_REVISION l_status: O_GENERAL_STATUS_MESSAGE l_user_ret: USER l_project_ret: PROJECT l_workitem_id: INTEGER l_issue_id: INTEGER l_issue_revision_id: INTEGER l_workitem_add_reply: O_GENERIC_MESSAGE l_date: DATE_TIME l_tags: LIST [STRING] l_tag: STRING l_tag_id: INTEGER l_timestamp: INTEGER do l_pc_msg ?= a_msg check issue_add_message: l_pc_msg /= Void end user_access.retrieve_user_by_session (l_pc_msg.session) if user_access.is_found then l_user_ret := user_access.last_user project_access.retrieve_project_by_id (l_pc_msg.project) if project_access.is_found then l_project_ret := project_access.last_project create l_date.make_now_utc l_timestamp := l_date.definite_duration (create {DATE_TIME}.make (1970, 1, 1, 0, 0, 0)).seconds_count.as_integer_32 create l_issue.make l_issue.set_project_id (l_project_ret.project_id) l_issue.set_title (l_pc_msg.title) l_issue.set_project_issue_id (issue_access.next_project_issue_id (l_project_ret.project_id)) l_issue.set_private (l_pc_msg.is_private) l_issue.set_last_modified (l_timestamp) issue_access.insert_issue (l_issue) l_issue_id := issue_access.last_insert_id -- create main revision (holds description) create l_issue_revision.make l_issue_revision.set_creation_time (l_timestamp) l_issue_revision.set_issue_id (l_issue_id) l_issue_revision.set_text (l_pc_msg.description) l_issue_revision.set_user_id (l_user_ret.user_id) issue_access.insert_issue_revision (l_issue_revision) l_issue_revision_id := issue_access.last_insert_id -- insert tags l_tags := l_pc_msg.tags.split (',') from l_tags.start until l_tags.after loop l_tag := l_tags.item l_tag.right_adjust l_tag.left_adjust if l_tag.count > 0 then l_tag_id := workitem_access.retrieve_tag_id (l_tag) if l_tag_id = 0 then workitem_access.insert_tag_text (l_tag) l_tag_id := workitem_access.retrieve_tag_id (l_tag) end if l_tag_id > 0 then issue_access.insert_issue_tag_association (l_issue_revision_id, l_tag_id) end end l_tags.forth end -- Create workitem create l_workitem.make l_workitem.set_type_id (1) l_workitem.set_user_id (l_user_ret.user_id) l_workitem.set_project_id (l_project_ret.project_id) workitem_access.insert_workitem (l_workitem) l_workitem_id := workitem_access.last_insert_id create l_workitem_issue.make l_workitem_issue.set_workitem_id (l_workitem_id) l_workitem_issue.set_issue_revision_id (l_issue_revision_id) issue_access.insert_issue_workitem(l_workitem_issue) -- send reply message create l_workitem_add_reply.make (workitem_namespace, workitem_add_reply_type) l_workitem_add_reply.add_argument ("workitem_id", l_workitem_id.out) l_workitem_add_reply.add_argument ("user", l_user_ret.name) l_workitem_add_reply.add_argument ("project_id", l_project_ret.project_id.out) l_workitem_add_reply.add_argument ("project_name", l_project_ret.name) l_workitem_add_reply.add_argument ("project_issue_id", l_issue.project_issue_id.out) node.send_message_reply (l_workitem_add_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_update (a_msg: O_MESSAGE) is -- Update a issue and create issue workitem according to `a_msg'. require a_msg_ok: a_msg /= Void local l_pc_msg: O_ISSUE_UPDATE_MESSAGE l_workitem: WORKITEM l_workitem_issue: WORKITEM_ISSUE l_last_rev_id: INTEGER l_status: O_GENERAL_STATUS_MESSAGE l_user_ret: USER l_project_ret: PROJECT l_workitem_id: INTEGER l_issue_id: INTEGER l_workitem_add_reply: O_GENERIC_MESSAGE l_tags: LIST [STRING] l_tag: STRING l_tag_id: INTEGER do l_pc_msg ?= a_msg check issue_update_message: l_pc_msg /= Void end user_access.retrieve_user_by_session (l_pc_msg.session) if user_access.is_found then l_user_ret := user_access.last_user project_access.retrieve_project_by_id (l_pc_msg.project) if project_access.is_found then l_project_ret := project_access.last_project issue_access.retrieve_issue_by_project_issue_id (l_pc_msg.project, l_pc_msg.project_issue_id) if issue_access.is_found then l_issue_id := issue_access.last_issue.issue_id issue_access.update_issue (l_issue_id, l_pc_msg.title, l_pc_msg.is_private) issue_access.update_first_revision(l_issue_id, l_pc_msg.description) l_last_rev_id := issue_access.retrieve_last_revision (l_issue_id) issue_access.remove_tags_for_revision(l_last_rev_id) -- insert tags l_tags := l_pc_msg.tags.split (',') from l_tags.start until l_tags.after loop l_tag := l_tags.item l_tag.right_adjust l_tag.left_adjust if l_tag.count > 0 then l_tag_id := workitem_access.retrieve_tag_id (l_tag) if l_tag_id = 0 then workitem_access.insert_tag_text (l_tag) l_tag_id := workitem_access.retrieve_tag_id (l_tag) end if l_tag_id > 0 then issue_access.insert_issue_tag_association (l_last_rev_id, l_tag_id) end end l_tags.forth end -- Create workitem create l_workitem.make l_workitem.set_type_id (1) l_workitem.set_user_id (l_user_ret.user_id) l_workitem.set_project_id (l_pc_msg.project) workitem_access.insert_workitem (l_workitem) l_workitem_id := workitem_access.last_insert_id create l_workitem_issue.make l_workitem_issue.set_workitem_id (l_workitem_id) l_workitem_issue.set_issue_revision_id (l_last_rev_id) issue_access.insert_issue_workitem(l_workitem_issue) -- send reply message create l_workitem_add_reply.make (workitem_namespace, workitem_add_reply_type) l_workitem_add_reply.add_argument ("workitem_id", l_workitem_id.out) l_workitem_add_reply.add_argument ("user", l_user_ret.name) l_workitem_add_reply.add_argument ("project_id", l_pc_msg.project.out) l_workitem_add_reply.add_argument ("project_name", l_project_ret.name) l_workitem_add_reply.add_argument ("project_issue_id", l_pc_msg.project_issue_id.out) node.send_message_reply (l_workitem_add_reply, a_msg) end else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_comment (a_msg: O_MESSAGE) is -- Add a new issue comment and issue workitem according to a_msg. require a_msg_ok: a_msg /= Void local l_pc_msg: O_ISSUE_COMMENT_MESSAGE l_workitem: WORKITEM l_workitem_issue: WORKITEM_ISSUE l_issue_revision: ISSUE_REVISION l_status: O_GENERAL_STATUS_MESSAGE l_user_ret: USER l_project_ret: PROJECT l_issue_ret: TUPLE [issue_id: INTEGER; project_issue_id: INTEGER; project_id: INTEGER; creation_time: INTEGER; last_modified: INTEGER; user: STRING; title: STRING; tags: STRING; is_private: BOOLEAN; revisions: ARRAYED_LIST [TUPLE [creation_time: INTEGER; text: STRING; tags: STRING]]] l_workitem_id: INTEGER l_issue_id: INTEGER l_issue_revision_id: INTEGER l_workitem_add_reply: O_GENERIC_MESSAGE l_date: DATE_TIME l_tags: LIST [STRING] l_tag: STRING l_tag_id: INTEGER do l_pc_msg ?= a_msg check issue_comment_message: l_pc_msg /= Void end user_access.retrieve_user_by_session (l_pc_msg.session) if user_access.is_found then l_user_ret := user_access.last_user project_access.retrieve_project_by_id (l_pc_msg.project) if project_access.is_found then l_project_ret := project_access.last_project issue_access.retrieve_issue_by_project_issue_id (l_pc_msg.project, l_pc_msg.project_issue_id) if issue_access.is_found then l_issue_ret := issue_access.last_issue l_issue_id := l_issue_ret.issue_id create l_issue_revision.make create l_date.make_now_utc l_issue_revision.set_creation_time (l_date.definite_duration (create {DATE_TIME}.make (1970, 1, 1, 0, 0, 0)).seconds_count.as_integer_32) l_issue_revision.set_issue_id (l_issue_id) l_issue_revision.set_text (l_pc_msg.description) l_issue_revision.set_user_id (l_user_ret.user_id) issue_access.insert_issue_revision (l_issue_revision) -- Update last_modified timestamp issue_access.update_last_modified_timestamp (l_issue_id, l_date) l_issue_revision_id := issue_access.last_insert_id if (l_pc_msg.is_extended) then -- use new tags from this revision l_tags := l_pc_msg.tags.split (',') else -- use existing tags from the last issue l_tags := l_issue_ret.tags.split (',') end -- insert tags from l_tags.start until l_tags.after loop l_tag := l_tags.item l_tag.right_adjust l_tag.left_adjust if l_tag.count > 0 then l_tag_id := workitem_access.retrieve_tag_id (l_tag) if l_tag_id = 0 then workitem_access.insert_tag_text (l_tag) l_tag_id := workitem_access.retrieve_tag_id (l_tag) end if l_tag_id > 0 then issue_access.insert_issue_tag_association (l_issue_revision_id, l_tag_id) end end l_tags.forth end -- Create workitem create l_workitem.make l_workitem.set_type_id (1) l_workitem.set_user_id (l_user_ret.user_id) l_workitem.set_project_id (l_project_ret.project_id) workitem_access.insert_workitem (l_workitem) l_workitem_id := workitem_access.last_insert_id create l_workitem_issue.make l_workitem_issue.set_workitem_id (l_workitem_id) l_workitem_issue.set_issue_revision_id (l_issue_revision_id) issue_access.insert_issue_workitem(l_workitem_issue) -- send reply message create l_workitem_add_reply.make (workitem_namespace, workitem_add_reply_type) l_workitem_add_reply.add_argument ("workitem_id", l_workitem_id.out) l_workitem_add_reply.add_argument ("user", l_user_ret.name) l_workitem_add_reply.add_argument ("project_id", l_project_ret.project_id.out) l_workitem_add_reply.add_argument ("project_name", l_project_ret.name) l_workitem_add_reply.add_argument ("project_issue_id", l_issue_ret.project_issue_id.out) l_workitem_add_reply.add_argument ("title", l_issue_ret.title) -- Add tags to the message because they are needed to update the frontend -- (speed optimization, prevents another call to the storage node to retrieve the issue tags) if (l_pc_msg.is_extended) then -- use new tags from this comment (only called from the web) l_workitem_add_reply.add_argument ("tags", l_pc_msg.tags) else -- use existing tags from the last issue l_workitem_add_reply.add_argument ("tags", l_issue_ret.tags) end node.send_message_reply (l_workitem_add_reply, a_msg) else create l_status.make (False, err_invalid_issue) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_retrieve (a_msg: O_MESSAGE) is -- Retrieve issue. require a_msg_ok: a_msg /= Void local l_msg: O_ISSUE_RETRIEVE_MESSAGE l_status: O_GENERAL_STATUS_MESSAGE l_reply: O_ISSUE_RETRIEVE_REPLY_MESSAGE l_issue_t: TUPLE [issue_id: INTEGER; project_issue_id: INTEGER; project_id: INTEGER; creation_time: INTEGER; last_modified: INTEGER; user: STRING; title: STRING; tags: STRING; is_private: BOOLEAN; revisions: ARRAYED_LIST [TUPLE [creation_time: INTEGER; user: STRING; text: STRING; tags: STRING]]] do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project) if project_access.is_found then -- retrieve issue issue_access.retrieve_issue_by_project_issue_id (l_msg.project, l_msg.issue_id) if issue_access.is_found then l_issue_t := issue_access.last_issue create l_reply.make (l_issue_t.creation_time, l_issue_t.last_modified, l_issue_t.user, l_issue_t.title, l_issue_t.tags, l_issue_t.is_private, l_issue_t.revisions) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_issue) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_list (a_msg: O_MESSAGE) is -- List issues. require a_msg_ok: a_msg /= Void local l_msg: O_ISSUE_LIST_MESSAGE l_status: O_GENERAL_STATUS_MESSAGE l_reply: O_ISSUE_LIST_REPLY_MESSAGE l_issues: DS_HASH_TABLE [TUPLE [issue_id: INTEGER; creation_time: INTEGER; last_modified: INTEGER; user: STRING; title: STRING; tags: STRING], INTEGER] do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project) if project_access.is_found then -- retrieve issues l_issues := issue_access.retrieve_project_issues (l_msg.project) create l_reply.make(l_issues) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_list_changed (a_msg: O_MESSAGE) is -- List changed issues since a given date. require a_msg_ok: a_msg /= Void local l_msg: O_ISSUE_LIST_CHANGED_MESSAGE l_status: O_GENERAL_STATUS_MESSAGE l_reply: O_ISSUE_LIST_REPLY_MESSAGE l_issues: DS_HASH_TABLE [TUPLE [issue_id: INTEGER; creation_time: INTEGER; last_modified: INTEGER; user: STRING; title: STRING; tags: STRING], INTEGER] do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project) if project_access.is_found then -- retrieve changed issues l_issues := issue_access.retrieve_changed_issues (l_msg.project, l_msg.date) create l_reply.make(l_issues) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_list_tags (a_msg: O_MESSAGE) is -- List tags of a project require a_msg_ok: a_msg /= Void local l_msg: O_ISSUE_LIST_TAGS_MESSAGE l_status: O_GENERAL_STATUS_MESSAGE l_reply: O_ISSUE_LIST_TAGS_REPLY_MESSAGE l_tags: ARRAY[STRING] do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project) if project_access.is_found then -- retrieve tags l_tags := issue_access.retrieve_project_tags(l_msg.project) create l_reply.make(l_tags) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end issue_search (a_msg: O_MESSAGE) is -- Search issues. require a_msg_ok: a_msg /= Void local l_msg: O_ISSUE_SEARCH_MESSAGE l_status: O_GENERAL_STATUS_MESSAGE l_reply: O_ISSUE_LIST_REPLY_MESSAGE l_issues: DS_HASH_TABLE [TUPLE [issue_id: INTEGER; creation_time: INTEGER; last_modified: INTEGER; user: STRING; title: STRING; tags: STRING], INTEGER] l_search_criteria: DS_HASH_TABLE [STRING, STRING] do l_msg ?= a_msg check valid_message: l_msg /= Void end user_access.retrieve_user_by_session (l_msg.session) if user_access.is_found then project_access.retrieve_project_by_id (l_msg.project) if project_access.is_found then -- retrieve matching issues l_issues := issue_access.search_issues (l_msg.project, l_msg.search_criteria) l_search_criteria := l_msg.search_criteria create l_reply.make(l_issues) node.send_message_reply (l_reply, a_msg) else create l_status.make (False, err_invalid_project) node.send_message_reply (l_status, a_msg) end else create l_status.make (False, err_session_timeout) node.send_message_reply (l_status, a_msg) end end end