note description: "Database access to community data." author: "Marco Zietzling " date: "$Date$" revision: "$Revision$" class COMMUNITY_ACCESS inherit DATABASE_ACCESS create make feature -- Status is_found: BOOLEAN -- Did the last retrieve query find a community? feature -- Access last_community: COMMUNITY -- Last retrieved community by a retrieve query. last_community_list: LIST [COMMUNITY] -- Last retrieved community list. last_member_list: LIST [USER] -- Last retrieved member list. last_project_list: LIST [PROJECT] -- Last retrieved project list. last_wiki_page_title_list: DS_ARRAYED_LIST [STRING] -- Last retrieved wiki page title list. last_wiki_page: TUPLE [title: STRING; text: STRING; private: BOOLEAN] -- Last retrieved wiki page. feature -- Select queries retrieve_all_communities -- Retrieve all communities. local l_selection: DB_SELECTION l_list_filling: DB_ACTION [COMMUNITY] l_obj: COMMUNITY do create l_obj.make create l_selection.make l_selection.set_query ("SELECT * FROM community") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_obj) create l_list_filling.make (l_selection, l_obj) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate last_community_list := l_list_filling.list ensure last_community_list: last_community_list /= Void end retrieve_community_by_id (a_community_id: INTEGER) -- Retrieve a community with ID `a_community_id'. require an_id_ok: a_community_id > 0 local l_selection: DB_SELECTION l_list_filling: DB_ACTION [COMMUNITY] l_community: COMMUNITY l_communities: LIST [COMMUNITY] do create l_community.make create l_selection.make l_selection.set_map_name (a_community_id, "community_id") l_selection.set_query ("SELECT * FROM community WHERE community_id=:community_id") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_community) create l_list_filling.make (l_selection, l_community) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate l_communities := l_list_filling.list if l_communities.count = 1 then is_found := True last_community := l_communities.first else is_found := False end ensure is_found_implies_community: is_found implies last_community /= Void end retrieve_community_by_name (a_community_name: STRING) -- Retrieve a community with ID `a_community_name'. require a_name_ok: a_community_name /= Void and then not a_community_name.is_empty local l_selection: DB_SELECTION l_list_filling: DB_ACTION [COMMUNITY] l_community: COMMUNITY l_communities: LIST [COMMUNITY] do create l_community.make create l_selection.make l_selection.set_map_name (a_community_name, "community_name") l_selection.set_query ("SELECT * FROM community WHERE name=:community_name") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_community) create l_list_filling.make (l_selection, l_community) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate l_communities := l_list_filling.list if l_communities.count = 1 then is_found := True last_community := l_communities.first else is_found := False end ensure is_found_implies_community: is_found implies last_community /= Void end retrieve_members (a_community_id: INTEGER; an_access_group: INTEGER) -- Retrieve members of a community with ID a_community_id that are in an_access_group. require a_community_id_valid: a_community_id > 0 an_access_group_valid: an_access_group > 0 local l_selection: DB_SELECTION l_list_filling: DB_ACTION [USER] l_obj: USER do create l_obj.make create l_selection.make l_selection.set_map_name (a_community_id, "community_id") l_selection.set_map_name (an_access_group, "group_id") l_selection.set_query ("[ SELECT u.* FROM user_community_association a JOIN user u USING(user_id) WHERE community_id=:community_id AND group_id=:group_id ORDER BY u.name ]") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_obj) create l_list_filling.make (l_selection, l_obj) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate last_member_list := l_list_filling.list ensure last_member_list: last_member_list /= Void end retrieve_projects (a_community_id: INTEGER) -- Retrieve projects associated with a community with ID a_community_id. require a_community_id_valid: a_community_id > 0 local l_selection: DB_SELECTION l_list_filling: DB_ACTION [PROJECT] l_obj: PROJECT do create l_obj.make create l_selection.make l_selection.set_map_name (a_community_id, "community_id") l_selection.set_query ("[ SELECT p.* FROM project_community_association a JOIN project p USING(project_id) WHERE community_id=:community_id ]") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_obj) create l_list_filling.make (l_selection, l_obj) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate last_project_list := l_list_filling.list ensure last_project_list: last_project_list /= Void end retrieve_communities_of_user (a_user_id: INTEGER) -- Retrieve communities of a user with user_id a_user_id require user_id_valid: a_user_id > 0 local l_selection: DB_SELECTION l_list_filling: DB_ACTION [COMMUNITY] l_obj: COMMUNITY do create l_obj.make create l_selection.make l_selection.set_map_name (a_user_id, "user_id") l_selection.set_query ("[ SELECT c.* FROM community c JOIN user_community_association a USING (community_id) WHERE user_id=:user_id ]") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_obj) create l_list_filling.make (l_selection, l_obj) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate last_community_list := l_list_filling.list ensure last_community_list: last_community_list /= Void end retrieve_communities_of_project (a_project_id: INTEGER) -- Retrieve communities of a project with project_id a_project_id require project_id_valid: a_project_id > 0 local l_selection: DB_SELECTION l_list_filling: DB_ACTION [COMMUNITY] l_obj: COMMUNITY do create l_obj.make create l_selection.make l_selection.set_map_name (a_project_id, "project_id") l_selection.set_query ("[ SELECT c.* FROM community c JOIN project_community_association a USING (community_id) WHERE project_id=:project_id ]") l_selection.execute_query handle_errors_and_warnings l_selection.object_convert (l_obj) create l_list_filling.make (l_selection, l_obj) l_selection.set_action (l_list_filling) l_selection.load_result l_selection.terminate last_community_list := l_list_filling.list ensure last_community_list: last_community_list /= Void end retrieve_wiki_page_titles (a_community_id: INTEGER) -- Retrieve wiki page titles of a community with ID a_community_id. require a_community_id_valid: a_community_id > 0 local l_selection: SELECTION_RESULT do select_query.set_map_name (a_community_id, "community_id") l_selection := select_query.execute_query ("[ SELECT title FROM community_wiki WHERE community_id=:community_id ]") handle_errors_and_warnings create last_wiki_page_title_list.make (l_selection.count) from l_selection.start until l_selection.after loop last_wiki_page_title_list.force_last (l_selection.read_string ("title")) l_selection.forth end ensure last_wiki_page_title_list_not_void: last_wiki_page_title_list /= Void end retrieve_wiki_page (a_community_id: INTEGER; a_wiki_title: STRING) -- Retrieve latest revision of a wiki page of a community. require a_community_id_valid: a_community_id > 0 a_wiki_title_valid: a_wiki_title /= Void and then not a_wiki_title.is_empty local l_selection: SELECTION_RESULT l_selection_rev: SELECTION_RESULT l_selection_page: SELECTION_RESULT l_wiki_id: INTEGER l_latest_revision_id: INTEGER l_title: STRING l_text: STRING l_private: BOOLEAN do -- reset is_found status is_found := False -- get the corresponding wiki_id select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_wiki_title, "title") l_selection := select_query.execute_query ("[ SELECT * FROM community_wiki WHERE community_id=:community_id AND title=:title ]") handle_errors_and_warnings if l_selection.count = 1 then l_selection.start l_wiki_id := l_selection.read_integer ("wiki_id") l_private := l_selection.read_string ("private").is_equal ("true") -- get the latest wiki_revision_id select_query.set_map_name (l_wiki_id, "wiki_id") l_selection_rev := select_query.execute_query ("[ SELECT IFNULL(MAX(wiki_revision_id), 0) AS wiki_revision_id FROM community_wiki_revision WHERE wiki_id=:wiki_id ]") handle_errors_and_warnings check found_wiki_id: l_selection_rev.count = 1 end l_selection_rev.start l_latest_revision_id := l_selection_rev.read_integer ("wiki_revision_id") select_query.set_map_name (l_wiki_id, "wiki_id") select_query.set_map_name (l_latest_revision_id, "wiki_revision_id") l_selection_page := select_query.execute_query ("[ SELECT * FROM community_wiki_revision WHERE wiki_id=:wiki_id AND wiki_revision_id=:wiki_revision_id ]") if l_selection_page.count = 1 then is_found := True l_selection_page.start l_title := l_selection_page.read_string ("title") l_text := l_selection_page.read_string ("text") create last_wiki_page last_wiki_page.title := l_title last_wiki_page.text := l_text last_wiki_page.private := l_private end end ensure is_found_implies_last_wiki_page_not_void: is_found implies last_wiki_page /= Void end is_associated_with_project (a_community_id: INTEGER; a_project_id: INTEGER): BOOLEAN -- Is a community with ID `a_community_id' associated with a project with project ID `a_project_id'? require a_community_id_valid: a_community_id > 0 a_project_id_valid: a_project_id > 0 local l_qres: SELECTION_RESULT do select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_project_id, "project_id") l_qres := select_query.execute_query ("[ SELECT community_id FROM project_community_association WHERE community_id=:community_id AND project_id=:project_id ]") handle_errors_and_warnings if l_qres.count >= 1 then Result := True else Result := False end end has_admin (a_community_id: INTEGER; a_user_id: INTEGER): BOOLEAN -- Has a community with ID `a_community_id' an admin with user ID `a_user_id'? require a_community_id_valid: a_community_id > 0 a_user_id_valid: a_user_id > 0 local l_qres: SELECTION_RESULT do select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_user_id, "user_id") l_qres := select_query.execute_query ("[ SELECT community_id FROM user_community_association WHERE community_id=:community_id AND user_id=:user_id AND group_id=6 ]") handle_errors_and_warnings if l_qres.count >= 1 then Result := True else Result := False end end feature -- Insert queries insert_community (a_community: COMMUNITY) -- Add a_community as a new community. require a_community_not_void: a_community /= Void local l_store: DB_STORE do create l_store.make l_store.set_repository (db_handler.db_repositories.item ("community")) l_store.put (a_community) handle_errors_and_warnings end insert_community_project_association (a_community_id: INTEGER; a_project_id: INTEGER) -- Insert a community-project association. require community_id_valid: a_community_id > 0 project_id_valid: a_project_id > 0 local l_store: DB_CHANGE do create l_store.make l_store.set_map_name (a_community_id, "community_id") l_store.set_map_name (a_project_id, "project_id") l_store.modify ("INSERT INTO project_community_association SET community_id=:community_id, project_id=:project_id") handle_errors_and_warnings end insert_wiki_page (a_community_id: INTEGER; a_user_id: INTEGER; a_title: STRING; a_text: STRING; a_private: BOOLEAN) -- Insert a wiki page. require a_community_id_valid: a_community_id > 0 a_user_id_valid: a_user_id > 0 a_title_valid: a_title /= Void and then not a_title.is_empty a_text_valid: a_text /= Void local l_wiki: DB_CHANGE l_wiki_rev: DB_CHANGE l_selection: SELECTION_RESULT l_wiki_id: INTEGER do -- insert into community_wiki create l_wiki.make l_wiki.set_map_name (a_community_id, "community_id") l_wiki.set_map_name (a_title, "title") if a_private then l_wiki.set_map_name ("true", "private") else l_wiki.set_map_name ("false", "private") end l_wiki.modify ("INSERT INTO community_wiki SET community_id=:community_id, title=:title, private=:private") handle_errors_and_warnings -- retrieve generated wiki_id select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_title, "title") l_selection := select_query.execute_query ("[ SELECT wiki_id FROM community_wiki WHERE community_id=:community_id AND title=:title ]") handle_errors_and_warnings check found_wiki_id: l_selection.count = 1 end l_selection.start l_wiki_id := l_selection.read_integer ("wiki_id") -- insert first revision into community_wiki_revision create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (1, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (a_title, "title") l_wiki_rev.modify ("INSERT INTO community_wiki_revision SET wiki_id=:wiki_id, title=:title, user_id=:user_id, creation_time=UNIX_TIMESTAMP(), community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings -- now update this entry with the text -- this has to be done separately because otherwise empty text would not be possible create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (1, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (a_text, "text") l_wiki_rev.modify ("UPDATE community_wiki_revision SET text=:text WHERE wiki_id=:wiki_id AND user_id=:user_id AND community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings end feature -- Update queries update_community_description (a_community_id: INTEGER; a_description: STRING) -- Update the description of a community with ID a_community_id to the new value a_description. local l_change: DB_CHANGE do create l_change.make l_change.set_map_name (a_community_id, "community_id") l_change.set_map_name (a_description, "description") l_change.modify ("UPDATE community SET description=:description WHERE community_id=:community_id") handle_errors_and_warnings end update_wiki_page (a_community_id: INTEGER; a_user_id: INTEGER; a_title: STRING; a_text: STRING; a_private: BOOLEAN) -- Update a wiki page by creating a new revision. require a_community_id_valid: a_community_id > 0 a_user_id_valid: a_user_id > 0 a_title_valid: a_title /= Void and then not a_title.is_empty a_text_valid: a_text /= Void local l_wiki: DB_CHANGE l_wiki_rev: DB_CHANGE l_selection: SELECTION_RESULT l_selection_rev: SELECTION_RESULT l_wiki_id: INTEGER l_revision: INTEGER do -- update private flag in community_wiki create l_wiki.make l_wiki.set_map_name (a_community_id, "community_id") l_wiki.set_map_name (a_title, "title") if a_private then l_wiki.set_map_name ("true", "private") else l_wiki.set_map_name ("false", "private") end l_wiki.modify ("UPDATE community_wiki SET private=:private WHERE community_id=:community_id AND title=:title") handle_errors_and_warnings -- retrieve associated wiki_id select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_title, "title") l_selection := select_query.execute_query ("[ SELECT wiki_id FROM community_wiki WHERE community_id=:community_id AND title=:title ]") handle_errors_and_warnings check found_wiki_id: l_selection.count = 1 end l_selection.start l_wiki_id := l_selection.read_integer ("wiki_id") -- retrieve latest community_wiki_revision select_query.set_map_name (l_wiki_id, "wiki_id") l_selection_rev := select_query.execute_query ("[ SELECT IFNULL(MAX(community_wiki_revision), 0) AS community_wiki_revision FROM community_wiki_revision WHERE wiki_id=:wiki_id ]") handle_errors_and_warnings check found_wiki_id: l_selection_rev.count = 1 end l_selection_rev.start l_revision := l_selection_rev.read_integer ("community_wiki_revision") l_revision := l_revision + 1 -- insert new revision into community_wiki_revision create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (l_revision, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (a_title, "title") l_wiki_rev.modify ("INSERT INTO community_wiki_revision SET wiki_id=:wiki_id, title=:title, user_id=:user_id, creation_time=UNIX_TIMESTAMP(), community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings -- now update this entry with the text -- this has to be done separately because otherwise empty text would not be possible create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (l_revision, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (a_text, "text") l_wiki_rev.modify ("UPDATE community_wiki_revision SET text=:text WHERE wiki_id=:wiki_id AND user_id=:user_id AND community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings end rename_wiki_page (a_community_id: INTEGER; a_user_id: INTEGER; an_old_title: STRING; a_new_title: STRING) -- Rename a wiki page by creating a new revision. require a_community_id_valid: a_community_id > 0 a_user_id_valid: a_user_id > 0 an_old_title_valid: an_old_title /= Void and then not an_old_title.is_empty a_new_title_valid: a_new_title /= Void and then not a_new_title.is_empty local l_wiki: DB_CHANGE l_wiki_rev: DB_CHANGE l_selection: SELECTION_RESULT l_selection_rev: SELECTION_RESULT l_selection_text: SELECTION_RESULT l_wiki_id: INTEGER l_revision: INTEGER l_text: STRING do -- update title in community_wiki create l_wiki.make l_wiki.set_map_name (a_community_id, "community_id") l_wiki.set_map_name (an_old_title, "old_title") l_wiki.set_map_name (a_new_title, "new_title") l_wiki.modify ("UPDATE community_wiki SET title=:new_title WHERE community_id=:community_id AND title=:old_title") handle_errors_and_warnings -- retrieve associated wiki_id select_query.set_map_name (a_community_id, "community_id") select_query.set_map_name (a_new_title, "title") l_selection := select_query.execute_query ("[ SELECT wiki_id FROM community_wiki WHERE community_id=:community_id AND title=:title ]") handle_errors_and_warnings check found_wiki_id: l_selection.count = 1 end l_selection.start l_wiki_id := l_selection.read_integer ("wiki_id") -- retrieve latest community_wiki_revision select_query.set_map_name (l_wiki_id, "wiki_id") l_selection_rev := select_query.execute_query ("[ SELECT IFNULL(MAX(community_wiki_revision), 0) AS community_wiki_revision FROM community_wiki_revision WHERE wiki_id=:wiki_id ]") handle_errors_and_warnings check found_wiki_id: l_selection_rev.count = 1 end l_selection_rev.start l_revision := l_selection_rev.read_integer ("community_wiki_revision") -- get old text - will be copied into new revision select_query.set_map_name (l_wiki_id, "wiki_id") select_query.set_map_name (l_revision, "community_wiki_revision") l_selection_text := select_query.execute_query ("[ SELECT text FROM community_wiki_revision WHERE wiki_id=:wiki_id AND community_wiki_revision=:community_wiki_revision ]") handle_errors_and_warnings check found_text: l_selection_text.count = 1 end l_selection_text.start l_text := l_selection_text.read_string ("text") l_revision := l_revision + 1 -- insert new revision into community_wiki_revision create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (l_revision, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (a_new_title, "title") l_wiki_rev.modify ("INSERT INTO community_wiki_revision SET wiki_id=:wiki_id, title=:title, user_id=:user_id, creation_time=UNIX_TIMESTAMP(), community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings -- now update this entry with the old text -- this has to be done separately because otherwise empty text would not be possible create l_wiki_rev.make l_wiki_rev.set_map_name (l_wiki_id, "wiki_id") l_wiki_rev.set_map_name (l_revision, "community_wiki_revision") l_wiki_rev.set_map_name (a_user_id, "user_id") l_wiki_rev.set_map_name (l_text, "text") l_wiki_rev.modify ("UPDATE community_wiki_revision SET text=:text WHERE wiki_id=:wiki_id AND user_id=:user_id AND community_wiki_revision=:community_wiki_revision") handle_errors_and_warnings end feature -- Delete queries delete_community_project_association (a_community_id: INTEGER; a_project_id: INTEGER) -- Delete a community-project association. require community_id_valid: a_community_id > 0 project_id_valid: a_project_id > 0 local l_store: DB_CHANGE do create l_store.make l_store.set_map_name (a_community_id, "community_id") l_store.set_map_name (a_project_id, "project_id") l_store.modify ("DELETE FROM project_community_association WHERE community_id=:community_id AND project_id=:project_id") handle_errors_and_warnings end delete_community (a_community_id: INTEGER) -- Delete a community. require community_id_valid: a_community_id > 0 local l_store: DB_CHANGE do create l_store.make l_store.set_map_name (a_community_id, "community_id") l_store.modify ("DELETE FROM community WHERE community_id=:community_id") handle_errors_and_warnings end delete_wiki_page (a_community_id: INTEGER; a_wiki_title: STRING) -- Delete a wiki page of a community. require a_community_id_valid: a_community_id > 0 a_wiki_title_valid: a_wiki_title /= Void and then not a_wiki_title.is_empty local l_store: DB_CHANGE do create l_store.make l_store.set_map_name (a_community_id, "community_id") l_store.set_map_name (a_wiki_title, "title") l_store.modify ("DELETE FROM community_wiki WHERE community_id=:community_id AND title=:title") handle_errors_and_warnings end end