From 223a1f9de33ffd0baa1e654afc3dad5ab8e83822 Mon Sep 17 00:00:00 2001 From: Alexey Verkhovsky Date: Tue, 27 Sep 2005 13:46:02 +0000 Subject: [PATCH] Speeding up some stuff --- app/controllers/wiki_controller.rb | 3 ++- app/models/page.rb | 6 +----- app/models/page_set.rb | 9 ++++----- app/models/web.rb | 21 ++++++++++++++++++++- app/models/wiki.rb | 1 + app/models/wiki_reference.rb | 3 ++- app/views/wiki/authors.rhtml | 2 +- lib/page_renderer.rb | 25 +++++++++++++++++-------- script/reset_references | 2 +- test/functional/wiki_controller_test.rb | 3 +++ test/unit/web_test.rb | 8 ++++++++ 11 files changed, 60 insertions(+), 23 deletions(-) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 787f8c6a..13d76598 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -46,7 +46,8 @@ class WikiController < ApplicationController # Within a single web --------------------------------------------------------- def authors - @authors = @web.select.authors.sort + @page_names_by_author = @web.page_names_by_author + @authors = @page_names_by_author.keys.sort end def export_html diff --git a/app/models/page.rb b/app/models/page.rb index a44b5558..e45b609e 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -16,7 +16,7 @@ class Page < ActiveRecord::Base # Try to render content to make sure that markup engine can take it, renderer.revision = Revision.new( :page => self, :content => content, :author => author, :revised_at => time) - renderer.display_content + renderer.display_content(update_references = true) # A user may change a page, look at it and make some more changes - several times. # Not to record every such iteration as a new revision, if the previous revision was done @@ -59,10 +59,6 @@ class Page < ActiveRecord::Base end end - def authors - revisions.collect { |rev| rev.author } - end - def references web.select.pages_that_reference(name) end diff --git a/app/models/page_set.rb b/app/models/page_set.rb index 873e4c49..9589b36c 100644 --- a/app/models/page_set.rb +++ b/app/models/page_set.rb @@ -46,6 +46,9 @@ class PageSet < Array end def pages_authored_by(author) + all_pages_authored_by_the_author = + Page.connection.select_all(sanitize_sql([ + "SELECT page_id FROM revision WHERE author = '?'", author])) self.select { |page| page.authors.include?(author) } end @@ -59,7 +62,7 @@ class PageSet < Array # references and so cannot be orphans # Pages that refer to themselves and have no links from outside are oprphans. def orphaned_pages - never_orphans = web.select.authors + ['HomePage'] + never_orphans = web.authors + ['HomePage'] self.select { |page| if never_orphans.include? page.name false @@ -88,8 +91,4 @@ class PageSet < Array }.flatten.uniq end - def authors - self.inject([]) { |authors, page| authors << page.authors }.flatten.uniq.sort - end - end diff --git a/app/models/web.rb b/app/models/web.rb index 65a97832..c38c8061 100644 --- a/app/models/web.rb +++ b/app/models/web.rb @@ -21,7 +21,11 @@ class Web < ActiveRecord::Base end def authors - select.authors + connection.select_all( + 'SELECT DISTINCT r.author AS author ' + + 'FROM revisions r ' + + 'JOIN pages p ON p.id = r.page_id ' + + 'ORDER by 1').collect { |row| row['author'] } end def categories @@ -44,6 +48,21 @@ class Web < ActiveRecord::Base read_attribute('markup').to_sym end + def page_names_by_author + connection.select_all( + 'SELECT DISTINCT r.author AS author, p.name AS page_name ' + + 'FROM revisions r ' + + 'JOIN pages p ON r.page_id = p.id ' + + "WHERE p.web_id = #{self.id} " + + 'ORDER by p.name' + ).inject({}) { |result, row| + author, page_name = row['author'], row['page_name'] + result[author] = [] unless result.has_key?(author) + result[author] << page_name + result + } + end + def remove_pages(pages_to_be_removed) pages_to_be_removed.each { |p| p.destroy } end diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 773fd011..e0da8644 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -1,4 +1,5 @@ class Wiki + cattr_accessor :storage_path, :logger self.storage_path = "#{RAILS_ROOT}/storage/" self.logger = RAILS_DEFAULT_LOGGER diff --git a/app/models/wiki_reference.rb b/app/models/wiki_reference.rb index 6ebe1d55..9f4534a7 100644 --- a/app/models/wiki_reference.rb +++ b/app/models/wiki_reference.rb @@ -4,9 +4,10 @@ class WikiReference < ActiveRecord::Base WANTED_PAGE = 'W' INCLUDED_PAGE = 'I' CATEGORY = 'C' + AUTHOR = 'A' belongs_to :page - validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY] + validates_inclusion_of :link_type, :in => [LINKED_PAGE, WANTED_PAGE, INCLUDED_PAGE, CATEGORY, AUTHOR] # FIXME all finders below MUST restrict their results to pages belonging to a particular web diff --git a/app/views/wiki/authors.rhtml b/app/views/wiki/authors.rhtml index 97eb5c9d..57f529ee 100644 --- a/app/views/wiki/authors.rhtml +++ b/app/views/wiki/authors.rhtml @@ -5,7 +5,7 @@
  • <%= link_to_page author %> co- or authored: - <%= @web.select.pages_authored_by(author).collect { |page| link_to_page(page.name) }.sort.join ', ' %> + <%= @page_names_by_author[author].collect { |page_name| link_to_page(page_name) }.sort.join ', ' %>
  • <% end %> diff --git a/lib/page_renderer.rb b/lib/page_renderer.rb index 374da3f3..f47238f4 100644 --- a/lib/page_renderer.rb +++ b/lib/page_renderer.rb @@ -20,11 +20,12 @@ class PageRenderer def revision=(r) @revision = r - @wiki_words_cache = @wiki_includes_cache = @wiki_references_cache = nil + @display_content = @display_published = @wiki_words_cache = @wiki_includes_cache = + @wiki_references_cache = nil end - def display_content - @display_content ||= render + def display_content(update_references = false) + @display_content ||= render(:update_references => update_references) end def display_content_for_export @@ -87,12 +88,21 @@ class PageRenderer private def render(options = {}) - result = WikiContent.new(@revision, @@url_generator, options).render! + + rendering_result = WikiContent.new(@revision, @@url_generator, options).render! + + if options[:update_references] + update_references(rendering_result) + end + rendering_result + end + + def update_references(rendering_result) WikiReference.delete_all ['page_id = ?', @revision.page_id] references = @revision.page.wiki_references - wiki_word_chunks = result.find_chunks(WikiChunk::WikiLink) + wiki_word_chunks = rendering_result.find_chunks(WikiChunk::WikiLink) wiki_words = wiki_word_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq wiki_words.each do |referenced_name| @@ -105,17 +115,16 @@ class PageRenderer references.create :referenced_name => referenced_name, :link_type => link_type end - include_chunks = result.find_chunks(Include) + include_chunks = rendering_result.find_chunks(Include) includes = include_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq includes.each do |included_page_name| references.create :referenced_name => included_page_name, :link_type => WikiReference::INCLUDED_PAGE end - categories = result.find_chunks(Category).map { |cat| cat.list }.flatten + categories = rendering_result.find_chunks(Category).map { |cat| cat.list }.flatten categories.each do |category| references.create :referenced_name => category, :link_type => WikiReference::CATEGORY end - result end end diff --git a/script/reset_references b/script/reset_references index 0e21b0c9..176f3430 100644 --- a/script/reset_references +++ b/script/reset_references @@ -16,7 +16,7 @@ Web.find_all.each do |web| web.pages.find(:all, :order => 'name').each do |page| $stderr.puts "Processing page '#{page.name}'" begin - PageRenderer.new(page.current_revision).display_content + PageRenderer.new(page.current_revision).display_content(update_references = true) rescue => e puts e puts e.backtrace diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index 8be34cb4..9d39fa23 100755 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -53,6 +53,9 @@ class WikiControllerTest < Test::Unit::TestCase assert_success assert_equal %w(AnAuthor BreakingTheOrder DavidHeinemeierHansson Guest Me TreeHugger), r.template_objects['authors'] + page_names_by_author = r.template_objects['page_names_by_author'] + assert_equal r.template_objects['authors'], page_names_by_author.keys.sort + assert_equal %w(FirstPage HomePage), page_names_by_author['DavidHeinemeierHansson'] end def test_cancel_edit diff --git a/test/unit/web_test.rb b/test/unit/web_test.rb index 875c0bb3..57f47ea7 100644 --- a/test/unit/web_test.rb +++ b/test/unit/web_test.rb @@ -86,6 +86,14 @@ class WebTest < Test::Unit::TestCase @web.select.orphaned_pages.collect{ |page| page.name }.sort end + def test_page_names_by_author + page_names_by_author = webs(:test_wiki).page_names_by_author + assert_equal %w(AnAuthor DavidHeinemeierHansson Guest Me TreeHugger), + page_names_by_author.keys.sort + assert_equal %w(FirstPage HomePage), page_names_by_author['DavidHeinemeierHansson'] + assert_equal %w(Oak), page_names_by_author['TreeHugger'] + end + private def add_sample_pages