[Groonga-commit] droonga/droonga-engine at cefa754 [master] dump: support dumping schema

Back to archive index

Kouhei Sutou null+****@clear*****
Fri May 16 18:03:52 JST 2014


Kouhei Sutou	2014-05-16 18:03:52 +0900 (Fri, 16 May 2014)

  New Revision: cefa7540d11d2b2dfdf388c80332a17d91a06109
  https://github.com/droonga/droonga-engine/commit/cefa7540d11d2b2dfdf388c80332a17d91a06109

  Message:
    dump: support dumping schema

  Modified files:
    lib/droonga/plugins/dump.rb

  Modified: lib/droonga/plugins/dump.rb (+149 -2)
===================================================================
--- lib/droonga/plugins/dump.rb    2014-05-16 18:03:34 +0900 (9c7654f)
+++ lib/droonga/plugins/dump.rb    2014-05-16 18:03:52 +0900 (62b7c30)
@@ -69,6 +69,8 @@ module Droonga
       end
 
       class Dumper
+        include Loggable
+
         def initialize(context, loop, messenger, request)
           @context = context
           @loop = loop
@@ -82,16 +84,27 @@ module Droonga
           forward("dump.start")
 
           dumper = Fiber.new do
+            dump_schema
             dump_records
+            dump_indexes
             forward("dump.end")
           end
 
+          on_error = lambda do |exception|
+            message = "failed to dump"
+            logger.exception(message, $!)
+            error("DumpFailure", message)
+          end
+
           timer = Coolio::TimerWatcher.new(0.1, true)
           timer.on_timer do
             begin
               dumper.resume
             rescue FiberError
               timer.detach
+            rescue
+              timer.detach
+              on_error.call($!)
             end
           end
 
@@ -109,6 +122,20 @@ module Droonga
           @messages_per_100msec =****@reque*****_per_seconds / 10
         end
 
+        def error(name, message)
+          message = {
+            "statusCode" => ErrorMessages::InternalServerError::STATUS_CODE,
+            "body" => {
+              "name"    => name,
+              "message" => message,
+            },
+          }
+          error_message = @base_forward_message.merge(message)
+          @messenger.forward(error_message,
+                             "to"   => @forward_to,
+                             "type" => "dump.error")
+        end
+
         def forward(type, body=nil)
           forward_message = @base_forward_message
           if body
@@ -123,8 +150,103 @@ module Droonga
           Fiber.yield if @n_forwarded_messages.zero?
         end
 
+        def dump_schema
+          reference_tables = []
+          each_table do |table|
+            if reference_table?(table)
+              reference_tables << table
+              next
+            end
+            dump_table(table)
+          end
+
+          reference_tables.each do |table|
+            dump_table(table)
+          end
+        end
+
+        def dump_table(table)
+          forward("dump.table", table_body(table))
+
+          columns = table.columns.sort_by(&:name)
+          columns.each do |column|
+            dump_column(column)
+          end
+        end
+
+        def table_body(table)
+          body = {
+            "type" => table_type(table),
+            "name" => table.name,
+          }
+          if table.support_key?
+            body["keyType"] = table.domain.name
+          end
+          if body["keyType"] == "ShortText"
+            if table.default_tokenizer
+              body["tokenizer"] = table.default_tokenizer.name
+            end
+            if table.normalizer
+              body["normalizer"] = table.normalizer.name
+            end
+          end
+          body
+        end
+
+        def table_type(table)
+          table.class.name.split(/::/).last
+        end
+
+        def dump_column(column)
+          forward("dump.column", column_body(column))
+        end
+
+        def column_body(column)
+          body = {
+            "table"     => column.domain.name,
+            "name"      => column.local_name,
+            "type"      => column_type(column),
+            "valueType" => column.range.name,
+          }
+          case body["type"]
+          when "Index"
+            body["indexOptions"] = {
+              "section"  => column.with_section?,
+              "weight"   => column.with_weight?,
+              "position" => column.with_position?,
+              "sources"  => index_column_sources(column),
+            }
+          when "Vector"
+            body["vectorOptions"] = {
+              "weight" => column.with_weight?,
+            }
+          end
+          body
+        end
+
+        def column_type(column)
+          if column.is_a?(::Groonga::IndexColumn)
+            "Index"
+          elsif column.vector?
+            "Vector"
+          else
+            "Scalar"
+          end
+        end
+
+        def index_column_sources(index_column)
+          index_column.sources.collect do |source|
+            if source.is_a?(::Groonga::Table)
+              "_key"
+            else
+              source.local_name
+            end
+          end
+        end
+
         def dump_records
           each_table do |table|
+            next if index_only_table?(table)
             table.each do |record|
               values = {}
               record.attributes.each do |key, value|
@@ -140,10 +262,19 @@ module Droonga
           end
         end
 
+        def dump_indexes
+          each_index_columns do |column|
+            dump_column(column)
+          end
+        end
+
         def each_table
-          @context.database.each(:ignore_missing_object => true) do |object|
+          options = {
+            :ignore_missing_object => true,
+            :order_by => :key,
+          }
+          @context.database.each(options) do |object|
             next unless object.is_a?(::Groonga::Table)
-            next if index_only_table?(object)
             yield(object)
           end
         end
@@ -153,6 +284,22 @@ module Droonga
             column.is_a?(::Groonga::IndexColumn)
           end
         end
+
+        def reference_table?(table)
+          table.support_key? and table.domain.is_a?(::Groonga::Table)
+        end
+
+        def each_index_columns
+          each_table do |table|
+            table.columns.each do |column|
+              yield(column) if column.is_a?(::Groonga::IndexColumn)
+            end
+          end
+        end
+
+        def log_tag
+          "[#{Process.ppid}][#{Process.pid}] dumper"
+        end
       end
 
       define_single_step do |step|
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index