From null+ranguba at clear-code.com Sat Jun 12 03:15:41 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Sat, 12 Jun 2010 07:15:41 +0000 Subject: [groonga-commit:1008] ranguba/rroonga [master] support version tag. Message-ID: <20100612071558.162241703F2@taiyaki.ru> Kouhei Sutou 2010-06-12 07:15:41 +0000 (Sat, 12 Jun 2010) New Revision: f2629c642067855ee46fa76dd689628e0a6dcef2 Log: support version tag. Modified files: ext/groonga/rb-groonga.c Modified: ext/groonga/rb-groonga.c (+51 -16) =================================================================== --- ext/groonga/rb-groonga.c 2010-06-08 06:52:08 +0000 (ed69d53) +++ ext/groonga/rb-groonga.c 2010-06-12 07:15:41 +0000 (4b6b566) @@ -31,11 +31,59 @@ finish_groonga (VALUE self, VALUE object_id) } static void +rb_grn_init_runtime_version (VALUE mGrn) +{ + const char *component_start, *component_end; + int component_length; + VALUE runtime_version; + VALUE major, minor, micro, tag; + + runtime_version = rb_ary_new(); + + component_start = grn_get_version(); + component_end = strstr(component_start, "."); + component_length = component_end - component_start; + major = rb_str_new(component_start, component_length); + rb_ary_push(runtime_version, rb_Integer(major)); + + component_start = component_end + 1; + component_end = strstr(component_start, "."); + component_length = component_end - component_start; + minor = rb_str_new(component_start, component_length); + rb_ary_push(runtime_version, rb_Integer(minor)); + + component_start = component_end + 1; + component_end = strstr(component_start, "-"); + if (component_end) { + component_length = component_end - component_start; + } else { + component_length = strlen(component_start); + } + micro = rb_str_new(component_start, component_length); + rb_ary_push(runtime_version, rb_Integer(micro)); + + if (component_end) { + tag = rb_str_new2(component_end + 1); + } else { + tag = Qnil; + } + rb_ary_push(runtime_version, tag); + + rb_obj_freeze(runtime_version); + /* + * ??????groonga???????[???????? + * ?, ?????????, ?????????, ??]? + * ??? + */ + rb_define_const(mGrn, "VERSION", runtime_version); +} + +static void rb_grn_init_version (VALUE mGrn) { - long i, runtime_version_length; - VALUE runtime_version, build_version, bindings_version; - VALUE *runtime_version_pointer; + VALUE build_version, bindings_version; + + rb_grn_init_runtime_version(mGrn); build_version = rb_ary_new3(3, INT2NUM(GRN_MAJOR_VERSION), @@ -48,19 +96,6 @@ rb_grn_init_version (VALUE mGrn) */ rb_define_const(mGrn, "BUILD_VERSION", build_version); - runtime_version = rb_str_split(rb_str_new2(grn_get_version()), "."); - runtime_version_length = RARRAY_LEN(runtime_version); - runtime_version_pointer = RARRAY_PTR(runtime_version); - for (i = 0; i < runtime_version_length; i++) { - runtime_version_pointer[i] = rb_Integer(runtime_version_pointer[i]); - } - rb_obj_freeze(runtime_version); - /* - * ??????groonga???????[???????? - * ?, ?????????, ?????????]???? - */ - rb_define_const(mGrn, "VERSION", runtime_version); - bindings_version = rb_ary_new3(3, INT2NUM(RB_GRN_MAJOR_VERSION), INT2NUM(RB_GRN_MINOR_VERSION), From null+ranguba at clear-code.com Sat Jun 12 22:57:08 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Sun, 13 Jun 2010 02:57:08 +0000 Subject: [groonga-commit:1009] ranguba/rroonga [master] follow grn_expr_exec() API change. Message-ID: <20100613025729.6B5171704BD@taiyaki.ru> Kouhei Sutou 2010-06-13 02:57:08 +0000 (Sun, 13 Jun 2010) New Revision: bc54b503b515bf3c8cb64e1dfec0fb22d8842085 Log: follow grn_expr_exec() API change. Modified files: ext/groonga/rb-grn-context.c ext/groonga/rb-grn-expression.c test/test-expression.rb Modified: ext/groonga/rb-grn-context.c (+1 -18) =================================================================== --- ext/groonga/rb-grn-context.c 2010-06-13 02:56:00 +0000 (1cfd82f) +++ ext/groonga/rb-grn-context.c 2010-06-13 02:57:08 +0000 (7c38eb1) @@ -1,6 +1,6 @@ /* -*- c-file-style: "ruby" -*- */ /* - Copyright (C) 2009 Kouhei Sutou + Copyright (C) 2010 Kouhei Sutou This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -610,21 +610,6 @@ rb_grn_context_array_reference (VALUE self, VALUE name_or_id) return GRNOBJECT2RVAL(Qnil, context, object, RB_GRN_FALSE); } -/* - * call-seq: - * context.pop -> ? - * - * ???????????????????????????? - * ???Groonga::Expression#execute???????????? - */ -static VALUE -rb_grn_context_pop (VALUE self) -{ - grn_ctx *context; - context = SELF(self); - return GRNOBJ2RVAL(Qnil, context, grn_ctx_pop(context), self); -} - void rb_grn_init_context (VALUE mGrn) { @@ -654,8 +639,6 @@ rb_grn_init_context (VALUE mGrn) rb_define_method(cGrnContext, "[]", rb_grn_context_array_reference, 1); - rb_define_method(cGrnContext, "pop", rb_grn_context_pop, 0); - rb_define_method(cGrnContext, "connect", rb_grn_context_connect, -1); rb_define_method(cGrnContext, "send", rb_grn_context_send, 1); rb_define_method(cGrnContext, "receive", rb_grn_context_receive, 0); Modified: ext/groonga/rb-grn-expression.c (+5 -6) =================================================================== --- ext/groonga/rb-grn-expression.c 2010-06-13 02:56:00 +0000 (0b2ca95) +++ ext/groonga/rb-grn-expression.c 2010-06-13 02:57:08 +0000 (ffdc0da) @@ -439,26 +439,25 @@ rb_grn_expression_parse (int argc, VALUE *argv, VALUE self) /* * call-seq: - * expression.execute + * expression.execute -> ? * - * _expression_?????? + * _expression_??????????????? */ static VALUE rb_grn_expression_execute (VALUE self) { grn_ctx *context = NULL; grn_obj *expression; - grn_rc rc; + grn_obj *result; rb_grn_expression_deconstruct(SELF(self), &expression, &context, NULL, NULL, NULL, NULL, NULL); - rc = grn_expr_exec(context, expression, 0); + result = grn_expr_exec(context, expression, 0); rb_grn_context_check(context, self); - rb_grn_rc_check(rc, self); - return Qnil; + return GRNOBJ2RVAL(Qnil, context, result, self); } /* Modified: test/test-expression.rb (+3 -6) =================================================================== --- test/test-expression.rb 2010-06-13 02:56:00 +0000 (7c6f792) +++ test/test-expression.rb 2010-06-13 02:57:08 +0000 (0d35527) @@ -45,8 +45,7 @@ class ExpressionTest < Test::Unit::TestCase expression.append_constant("name") expression.append_operation(Groonga::Operation::GET_VALUE, 2) expression.compile - expression.execute - assert_equal("mori daijiro", context.pop) + assert_equal("mori daijiro", expression.execute) end def test_get_value_with_variable @@ -63,12 +62,10 @@ class ExpressionTest < Test::Unit::TestCase expression.append_constant("name") expression.append_operation(Groonga::Operation::GET_VALUE, 2) expression.compile - expression.execute - assert_equal("mori daijiro", context.pop) + assert_equal("mori daijiro", expression.execute) variable.value = gunyara_kun.id - expression.execute - assert_equal("Tasuku SUENAGA", context.pop) + assert_equal("Tasuku SUENAGA", expression.execute) end def test_inspect From null+ranguba at clear-code.com Sat Jun 12 22:56:00 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Sun, 13 Jun 2010 02:56:00 +0000 Subject: [groonga-commit:1010] ranguba/rroonga [master] update required groonga version: 0.1.9 -> 0.7.3. Message-ID: <20100613025729.4B7C3170404@taiyaki.ru> Kouhei Sutou 2010-06-13 02:56:00 +0000 (Sun, 13 Jun 2010) New Revision: 92c78100426fd1f9ce8ba6e7ddc3e238c1dd6f7c Log: update required groonga version: 0.1.9 -> 0.7.3. Modified files: rroonga-build.rb Modified: rroonga-build.rb (+2 -2) =================================================================== --- rroonga-build.rb 2010-06-12 07:15:41 +0000 (f94977d) +++ rroonga-build.rb 2010-06-13 02:56:00 +0000 (5e1e970) @@ -18,8 +18,8 @@ module RroongaBuild module RequiredGroongaVersion MAJOR = 0 - MINOR = 1 - MICRO = 9 + MINOR = 7 + MICRO = 3 VERSION = [MAJOR, MINOR, MICRO] end From null+ranguba at clear-code.com Mon Jun 21 23:29:35 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Tue, 22 Jun 2010 03:29:35 +0000 Subject: [groonga-commit:1011] ranguba/rroonga [master] use record itself not ID. Message-ID: <20100622033021.2FE6A1703EF@taiyaki.ru> Kouhei Sutou 2010-06-22 03:29:35 +0000 (Tue, 22 Jun 2010) New Revision: 2a769ce85e7157c10fe1cb10cf51a81cc6b5baa7 Log: use record itself not ID. Modified files: test/test-record.rb Modified: test/test-record.rb (+1 -1) =================================================================== --- test/test-record.rb 2010-06-13 02:57:08 +0000 (6b2c534) +++ test/test-record.rb 2010-06-22 03:29:35 +0000 (71b8a87) @@ -95,7 +95,7 @@ class RecordTest < Test::Unit::TestCase groonga = @bookmarks.add daijiro = @users.add("daijiro") assert_nil(groonga["user"]) - groonga["user"] = daijiro.id + groonga["user"] = daijiro assert_equal(daijiro, groonga["user"]) end From null+ranguba at clear-code.com Mon Jun 21 23:30:10 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Tue, 22 Jun 2010 03:30:10 +0000 Subject: [groonga-commit:1012] ranguba/rroonga [master] support weight customize for reference column. Message-ID: <20100622033021.397311703F3@taiyaki.ru> Kouhei Sutou 2010-06-22 03:30:10 +0000 (Tue, 22 Jun 2010) New Revision: 7182e04cf6277de6ecbd341060846f24b667c128 Log: support weight customize for reference column. Modified files: lib/groonga/expression-builder.rb test/test-table-select-weight.rb Modified: lib/groonga/expression-builder.rb (+32 -4) =================================================================== --- lib/groonga/expression-builder.rb 2010-06-22 03:29:35 +0000 (5378c61) +++ lib/groonga/expression-builder.rb 2010-06-22 03:30:10 +0000 (fad399a) @@ -232,6 +232,21 @@ module Groonga end end + class MatchTargetColumnExpressionBuilder < ColumnValueExpressionBuilder # :nodoc: + def build(expression, variable) + if @column.is_a?(String) + expression.append_constant(@column) + else + expression.append_object(@column) + end + end + + private + def normalize(other) + other + end + end + class MatchTargetExpressionBuilder < ExpressionBuilder # :nodoc: def initialize(target) super() @@ -362,9 +377,7 @@ module Groonga "for table <#{@table.inspect}>" raise ArgumentError, message end - ColumnValueExpressionBuilder.new(column, - :table => @table, - :column_name => name) + column_expression_builder(column, name) end def id @@ -403,12 +416,18 @@ module Groonga private def build_match_target(&block) - sub_builder = self.class.new(@table, nil) + sub_builder = MatchTargetRecordExpressionBuilder.new(@table, nil) sub_builder.build do |record| block.call(record) end end + def column_expression_builder(column, name) + ColumnValueExpressionBuilder.new(column, + :table => @table, + :column_name => name) + end + def method_missing(name, *args, &block) return super if block return super unless args.empty? @@ -420,6 +439,15 @@ module Groonga end end + class MatchTargetRecordExpressionBuilder < RecordExpressionBuilder # :nodoc: + private + def column_expression_builder(column, name) + MatchTargetColumnExpressionBuilder.new(column, + :table => @table, + :column_name => name) + end + end + class ColumnExpressionBuilder # :nodoc: include ExpressionBuildable Modified: test/test-table-select-weight.rb (+28 -3) =================================================================== --- test/test-table-select-weight.rb 2010-06-22 03:29:35 +0000 (b82db3b) +++ test/test-table-select-weight.rb 2010-06-22 03:30:10 +0000 (76e3538) @@ -23,10 +23,12 @@ class TableSelectWeightTest < Test::Unit::TestCase setup def setup_tables Groonga::Schema.define do |schema| - schema.create_table("Users", :key_type => "ShortText") do |table| + schema.create_table("Users", + :type => :hash, + :key_type => "ShortText") do |table| end - schema.create_table("Comments", :type => :array) do |table| + schema.create_table("Comments") do |table| table.short_text("title") table.text("content") table.time("created_at") @@ -39,6 +41,10 @@ class TableSelectWeightTest < Test::Unit::TestCase table.index("Comments.title", :with_section => true) table.index("Comments.content", :with_section => true) end + + schema.change_table("Users") do |table| + table.index("Comments.user") + end end end @@ -64,7 +70,7 @@ class TableSelectWeightTest < Test::Unit::TestCase :user => "darashi") end - def test_weight + def test_full_text_search result = @comments.select do |record| record.match("Hello") do |match_record| (match_record.title * 100) | @@ -76,4 +82,23 @@ class TableSelectWeightTest < Test::Unit::TestCase [record.title, record.score] end end + + def test_reference + result = @comments.select do |record| + full_text_match = record.match("Hello") do |match_record| + (match_record.title * 100) | + match_record.content + end + reference_match = record.match("darashi") do |match_record| + match_record.user * 1000 + end + full_text_match | reference_match + end + assert_equal_select_result([["Hello", 101], + ["(no title)", 3], + ["???", 1000]], + result) do |record| + [record.title, record.score] + end + end end From null+ranguba at clear-code.com Wed Jun 23 02:12:38 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 06:12:38 +0000 Subject: [groonga-commit:1013] ranguba/racknga [master] use symbol instead of string. Message-ID: <20100623061245.141A61703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 06:12:38 +0000 (Wed, 23 Jun 2010) New Revision: ee6c3b43959b594833045ca38fe33f4ba385d3e2 Log: use symbol instead of string. Modified files: lib/racknga/exception_mail_notifier.rb Modified: lib/racknga/exception_mail_notifier.rb (+6 -6) =================================================================== --- lib/racknga/exception_mail_notifier.rb 2010-06-23 05:00:17 +0000 (5732c10) +++ lib/racknga/exception_mail_notifier.rb 2010-06-23 06:12:38 +0000 (83984f7) @@ -28,11 +28,11 @@ module Racknga end def notify(exception, environment) - host = @options["host"] + host = @options[:host] return if host.nil? return if to.empty? mail = format(exception, environment) - Net::SMTP.start(host, @options["port"]) do |smtp| + Net::SMTP.start(host, @options[:port]) do |smtp| smtp.send_message(mail, from, *to) end end @@ -96,11 +96,11 @@ EOE end def subject(exception, environment) - [@options["subject_label"], exception.to_s].compact.join(' ') + [@options[:subject_label], exception.to_s].compact.join(' ') end def to - @to ||= ensure_array(@options["to"]) || [] + @to ||= ensure_array(@options[:to]) || [] end def ensure_array(maybe_array) @@ -109,7 +109,7 @@ EOE end def from - @from ||= @options["from"] || guess_from + @from ||= @options[:from] || guess_from end def guess_from @@ -119,7 +119,7 @@ EOE end def charset - @options['charset'] || 'utf-8' + @options[:charset] || 'utf-8' end def transfer_encoding From null+ranguba at clear-code.com Wed Jun 23 02:13:54 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 06:13:54 +0000 Subject: [groonga-commit:1014] ranguba/racknga [master] exception handler -> exception notifier. Message-ID: <20100623061400.B276A1703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 06:13:54 +0000 (Wed, 23 Jun 2010) New Revision: 7ee3c4ab86fec45cd9af6c5d17ba6d8670ad39a8 Log: exception handler -> exception notifier. Modified files: lib/racknga.rb Modified: lib/racknga.rb (+1 -1) =================================================================== --- lib/racknga.rb 2010-06-23 06:12:38 +0000 (3684f21) +++ lib/racknga.rb 2010-06-23 06:13:54 +0000 (0126ca4) @@ -23,4 +23,4 @@ module Racknga end require 'racknga/utils' -require 'racknga/middleware/exception_handler' +require 'racknga/middleware/exception_notifier' From null+ranguba at clear-code.com Wed Jun 23 02:21:01 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 06:21:01 +0000 Subject: [groonga-commit:1015] ranguba/racknga [master] add selective deflater. Message-ID: <20100623062110.00B0E1703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 06:21:01 +0000 (Wed, 23 Jun 2010) New Revision: ff1d2da262ee473d229d68b9ae52c62a8d8bc4b3 Log: add selective deflater. Added files: lib/racknga/middleware/deflater.rb Added: lib/racknga/middleware/deflater.rb (+41 -0) 100644 =================================================================== --- /dev/null +++ lib/racknga/middleware/deflater.rb 2010-06-23 06:21:01 +0000 (8011ac2) @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2010 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +module Racknga + module Middleware + class Deflater + def initialize(application, options={}) + @application = application + @deflater = Rack::Deflater.new(@application) + @options = Utils.normalize_options(options || {}) + end + + def call(environment) + if ie6?(environment) + @application.call(environment) + else + @deflater.call(environment) + end + end + + private + def ie6?(environment) + /MSIE 6.0;/ =~ (environment["HTTP_USER_AGENT"] || '') + end + end + end +end From null+ranguba at clear-code.com Wed Jun 23 02:23:17 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 06:23:17 +0000 Subject: [groonga-commit:1016] ranguba/racknga [master] enable deflater. Message-ID: <20100623062324.E67101703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 06:23:17 +0000 (Wed, 23 Jun 2010) New Revision: b96534680d1d3228dcdc192f3d49a3b235c248b9 Log: enable deflater. Modified files: lib/racknga.rb Modified: lib/racknga.rb (+1 -0) =================================================================== --- lib/racknga.rb 2010-06-23 06:21:01 +0000 (0126ca4) +++ lib/racknga.rb 2010-06-23 06:23:17 +0000 (a6d1a65) @@ -23,4 +23,5 @@ module Racknga end require 'racknga/utils' +require 'racknga/middleware/deflater' require 'racknga/middleware/exception_notifier' From null+ranguba at clear-code.com Wed Jun 23 03:53:52 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 07:53:52 +0000 Subject: [groonga-commit:1017] ranguba/racknga [master] add cache middleware. Message-ID: <20100623075402.32D191703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 07:53:52 +0000 (Wed, 23 Jun 2010) New Revision: 73bd2651cf287a0f48de8835850fb7c2254fca65 Log: add cache middleware. Added files: lib/racknga/cache_database.rb lib/racknga/middleware/cache.rb Modified files: lib/racknga.rb Modified: lib/racknga.rb (+1 -0) =================================================================== --- lib/racknga.rb 2010-06-23 06:23:17 +0000 (a6d1a65) +++ lib/racknga.rb 2010-06-23 07:53:52 +0000 (e182420) @@ -23,5 +23,6 @@ module Racknga end require 'racknga/utils' +require 'racknga/middleware/cache' require 'racknga/middleware/deflater' require 'racknga/middleware/exception_notifier' Added: lib/racknga/cache_database.rb (+75 -0) 100644 =================================================================== --- /dev/null +++ lib/racknga/cache_database.rb 2010-06-23 07:53:52 +0000 (465292f) @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2010 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +module Racknga + class CacheDatabase + def initialize(database_path) + @database_path = database_path + @context = Groonga::Context.new(:encoding => :none) + ensure_database + end + + def responses + @context["Responses"] + end + + def purge_old_responses(threshold_time_stamp=nil) + threshold_time_stamp ||= Time.now + responses.each do |response| + response.remove if response.created_at < threshold_time_stamp + end + end + + def ensure_database + if File.exist?(@database_path) + @database = Groonga::Database.open(@database_path, :context => @context) + else + create_database + end + ensure_tables + end + + def close_database + @database.close + end + + private + def create_responses_table + Groonga::Schema.define(:context => @context) do |schema| + schema.create_table("Responses", + :type => :hash, + :key_type => "ShortText") do |table| + table.uint32("status") + table.short_text("headers") + table.text("body") + table.time("created_at") + end + end + end + + def create_database + FileUtils.mkdir_p(File.dirname(@database_path)) + @database = Groonga::Database.create(:path => @database_path, + :context => @context) + end + + def ensure_tables + return if responses + create_responses_table + end + end +end Added: lib/racknga/middleware/cache.rb (+114 -0) 100644 =================================================================== --- /dev/null +++ lib/racknga/middleware/cache.rb 2010-06-23 07:53:52 +0000 (ca8fb35) @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2010 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +require 'yaml' +require 'racknga/cache_database' + +module Racknga + module Middleware + class Cache + def initialize(application, options={}) + @application = application + @options = Utils.normalize_options(options || {}) + database_path = @options[:database_path] + raise ArgumentError, ":database_path is missing" if database_path.nil? + @database = CacheDatabase.new(database_path) + end + + def call(environment) + request = Rack::Request.new(environment) + key = "#{key_prefix(request)}:#{normalize_path(request.fullpath)}" + cache = @database.responses + record = cache[key] + if record + handle_request_with_cache(cache, key, record, request) + else + handle_request(cache, key, request) + end + end + + def ensure_database + @database.ensure_database + end + + def close_database + @database.close_database + end + + private + def key_prefix(request) + if request.respond_to?(:mobile?) and request.mobile? + last_component = request.mobile.class.name.split(/::/).last + "mobile:#{last_component.downcase}" + else + "pc" + end + end + + def normalize_path(path) + path.gsub(/&callback=jsonp\d+&_=\d+\z/, '') + end + + def skip_cache?(status, headers, body) + return true if status != 200 + + headers = Rack::Utils::HeaderHash.new(headers) + content_type = headers["Content-Type"] + if /\A(\w+)\/([\w.+\-]+)\b/ =~ content_type + media_type = $1 + sub_type = $2 + return false if media_type == "text" + return false if sub_type == "json" + return false if sub_type == "xml" + return false if /\+xml\z/ =~ sub_type + end + true + end + + def handle_request(cache, key, request) + status, headers, body = @application.call(request.env) + return [status, headers, body] if skip_cache?(status, headers, body) + + now = Time.now + headers = Rack::Utils::HeaderHash.new(headers) + headers["Last-Modified"] ||= now.httpdate + stringified_body = '' + body.each do |data| + stringified_body << data + end + headers = headers.to_hash + cache[key] = { + :status => status, + :headers => headers.to_yaml, + :body => stringified_body.force_encoding("ASCII-8BIT"), + :created_at => now, + } + body = [stringified_body] + [status, headers, body] + end + + def handle_request_with_cache(cache, key, record, request) + body = record["body"] + return handle_request(cache, key, request) if body.nil? + + status = record["status"] + headers = YAML.load(record["headers"]) + [status, headers, [body]] + end + end + end +end From null+ranguba at clear-code.com Wed Jun 23 04:06:02 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 08:06:02 +0000 Subject: [groonga-commit:1018] ranguba/racknga [master] fix a typo. Message-ID: <20100623080610.EFF651703FA@taiyaki.ru> Kouhei Sutou 2010-06-23 08:06:02 +0000 (Wed, 23 Jun 2010) New Revision: edfb274c1cebc9c0fc82c5af014cc70b0130e7e1 Log: fix a typo. Modified files: lib/racknga/cache_database.rb Modified: lib/racknga/cache_database.rb (+1 -1) =================================================================== --- lib/racknga/cache_database.rb 2010-06-23 07:53:52 +0000 (465292f) +++ lib/racknga/cache_database.rb 2010-06-23 08:06:02 +0000 (124dd17) @@ -30,7 +30,7 @@ module Racknga def purge_old_responses(threshold_time_stamp=nil) threshold_time_stamp ||= Time.now responses.each do |response| - response.remove if response.created_at < threshold_time_stamp + response.delete if response.created_at < threshold_time_stamp end end From null+ranguba at clear-code.com Wed Jun 23 05:17:06 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Wed, 23 Jun 2010 09:17:06 +0000 Subject: [groonga-commit:1019] ranguba/rroonga [master] add missing require 'English'. Message-ID: <20100623091721.F14EB170E1E@taiyaki.ru> Kouhei Sutou 2010-06-23 09:17:06 +0000 (Wed, 23 Jun 2010) New Revision: 8334357a7ee2855d46249b7ff30c7d9f62f6898c Log: add missing require 'English'. Modified files: lib/groonga/record.rb Modified: lib/groonga/record.rb (+2 -0) =================================================================== --- lib/groonga/record.rb 2010-06-22 03:30:10 +0000 (527fbcd) +++ lib/groonga/record.rb 2010-06-23 09:17:06 +0000 (37987a0) @@ -15,6 +15,8 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +require 'English' + module Groonga class Record # ????????????? From null+ranguba at clear-code.com Thu Jun 24 08:22:19 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 12:22:19 +0000 Subject: [groonga-commit:1020] ranguba/racknga [master] only cache GET or HEAD. Message-ID: <20100624122235.1C59C170400@taiyaki.ru> Kouhei Sutou 2010-06-24 12:22:19 +0000 (Thu, 24 Jun 2010) New Revision: 4383e614b0994021baf9a2f4b92d0fbacf262240 Log: only cache GET or HEAD. Modified files: lib/racknga/middleware/cache.rb Modified: lib/racknga/middleware/cache.rb (+10 -2) =================================================================== --- lib/racknga/middleware/cache.rb 2010-06-23 08:06:02 +0000 (ca8fb35) +++ lib/racknga/middleware/cache.rb 2010-06-24 12:22:19 +0000 (d24b0a0) @@ -31,6 +31,7 @@ module Racknga def call(environment) request = Rack::Request.new(environment) + return @application.call(environment) unless use_cache?(request) key = "#{key_prefix(request)}:#{normalize_path(request.fullpath)}" cache = @database.responses record = cache[key] @@ -50,6 +51,10 @@ module Racknga end private + def use_cache?(requeust) + requeust.get? or requeust.head? + end + def key_prefix(request) if request.respond_to?(:mobile?) and request.mobile? last_component = request.mobile.class.name.split(/::/).last @@ -63,7 +68,8 @@ module Racknga path.gsub(/&callback=jsonp\d+&_=\d+\z/, '') end - def skip_cache?(status, headers, body) + def skip_caching_response?(status, headers, body) + return true if status != 200 return true if status != 200 headers = Rack::Utils::HeaderHash.new(headers) @@ -81,7 +87,9 @@ module Racknga def handle_request(cache, key, request) status, headers, body = @application.call(request.env) - return [status, headers, body] if skip_cache?(status, headers, body) + if skip_caching_response?(status, headers, body) + return [status, headers, body] + end now = Time.now headers = Rack::Utils::HeaderHash.new(headers) From null+ranguba at clear-code.com Thu Jun 24 08:41:00 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 12:41:00 +0000 Subject: [groonga-commit:1021] ranguba/rroonga [master] TODO: support clever table creation schema. Message-ID: <20100624124117.A6C8E170400@taiyaki.ru> Kouhei Sutou 2010-06-24 12:41:00 +0000 (Thu, 24 Jun 2010) New Revision: 0215ab41ef6ae4e16970c86ab44bd6372a04976c Log: TODO: support clever table creation schema. Modified files: TODO lib/groonga/schema.rb Modified: TODO (+1 -1) =================================================================== --- TODO 2010-06-23 09:17:06 +0000 (061b4ba) +++ TODO 2010-06-24 12:41:00 +0000 (fca7989) @@ -1 +1 @@ -* improve Table#column_value and Table#set_column_value speed. +* support clever table creation schema. Modified: lib/groonga/schema.rb (+34 -3) =================================================================== --- lib/groonga/schema.rb 2010-06-23 09:17:06 +0000 (05a3200) +++ lib/groonga/schema.rb 2010-06-24 12:41:00 +0000 (d636f03) @@ -571,9 +571,17 @@ module Groonga if @options[:change] raise ArgumentError, "table doesn't exist: #{@name}" if table.nil? else - if table and @options[:force] - table.remove - table = nil + if table + unless same_table?(table, create_options) + if @options[:force] + table.remove + table = nil + else + message = "table already exist: " + + "#{table.inspect}: #{create_options.inspect}" + raise ArgumentError, message + end + end end table ||= @table_type.create(create_options) end @@ -903,6 +911,29 @@ module Groonga definition.options.merge!(column_options.merge(options)) self end + + def same_table?(table, options) + return false # TODO + + return false unless table.class == @table_type + return false unless table.range == options[:value_type] + return false unless table.sub_records == options[:sub_records] + + case table + when Groonga::Array + true + when Groonga::Hash, Groonga::PatriciaTrie + return false unless table.domain == options[:key_type] + return false unless table.default_tokenizer == options[:default_tokenizer] + if table.is_a?(Groonga::PatriciaTrie) + return false unless table.key_normalize == options[:key_normalize] + return false unless table.key_with_sis == options[:key_with_sis] + end + true + else + false + end + end end class TableRemoveDefinition # :nodoc: From null+ranguba at clear-code.com Thu Jun 24 17:41:47 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 21:41:47 +0000 Subject: [groonga-commit:1022] ranguba/racknga [master] fix a typo. Message-ID: <20100624214156.61AE2170400@taiyaki.ru> Kouhei Sutou 2010-06-24 21:41:47 +0000 (Thu, 24 Jun 2010) New Revision: 74082a2cfaac415f9b9e93927020fabf1eab3174 Log: fix a typo. Modified files: lib/racknga/utils.rb Modified: lib/racknga/utils.rb (+1 -1) =================================================================== --- lib/racknga/utils.rb 2010-06-24 21:40:14 +0000 (73de580) +++ lib/racknga/utils.rb 2010-06-24 21:41:47 +0000 (bbcc62f) @@ -30,7 +30,7 @@ module Racknga def normalize_options(options) normalized_options = {} options.each do |key, value| - value = normalized_options(value) if value.is_a?(Hash) + value = normalize_options(value) if value.is_a?(Hash) normalized_options[key.to_sym] = value end normalized_options From null+ranguba at clear-code.com Thu Jun 24 17:40:14 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 21:40:14 +0000 Subject: [groonga-commit:1023] ranguba/racknga [master] require 'racknga/utils' explicitly. Message-ID: <20100624214202.610421704BE@taiyaki.ru> Kouhei Sutou 2010-06-24 21:40:14 +0000 (Thu, 24 Jun 2010) New Revision: ee7b6537b691de6cad18bbd5a003765433596500 Log: require 'racknga/utils' explicitly. Modified files: lib/racknga/exception_mail_notifier.rb Modified: lib/racknga/exception_mail_notifier.rb (+2 -0) =================================================================== --- lib/racknga/exception_mail_notifier.rb 2010-06-24 21:22:21 +0000 (0df3a52) +++ lib/racknga/exception_mail_notifier.rb 2010-06-24 21:40:14 +0000 (190f0c8) @@ -20,6 +20,8 @@ require 'net/smtp' require 'etc' require 'socket' +require 'racknga/utils' + module Racknga # Ruby 1.9 only. 1.8 isn't supported. class ExceptionMailNotifier From null+ranguba at clear-code.com Thu Jun 24 17:22:21 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 21:22:21 +0000 Subject: [groonga-commit:1024] ranguba/racknga [master] use "localhost" as default host. Message-ID: <20100624214202.584D8170400@taiyaki.ru> Kouhei Sutou 2010-06-24 21:22:21 +0000 (Thu, 24 Jun 2010) New Revision: 3e86a0c9f2719beaf0474c09c7e84cccedc08e08 Log: use "localhost" as default host. Modified files: lib/racknga/exception_mail_notifier.rb Modified: lib/racknga/exception_mail_notifier.rb (+1 -2) =================================================================== --- lib/racknga/exception_mail_notifier.rb 2010-06-24 12:22:19 +0000 (83984f7) +++ lib/racknga/exception_mail_notifier.rb 2010-06-24 21:22:21 +0000 (0df3a52) @@ -28,8 +28,7 @@ module Racknga end def notify(exception, environment) - host = @options[:host] - return if host.nil? + host = @options[:host] || "localhost" return if to.empty? mail = format(exception, environment) Net::SMTP.start(host, @options[:port]) do |smtp| From null+ranguba at clear-code.com Thu Jun 24 17:41:47 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 24 Jun 2010 21:41:47 +0000 Subject: [groonga-commit:1025] ranguba/racknga [master] fix a typo. Message-ID: <20100624214202.6C9F3170E20@taiyaki.ru> Kouhei Sutou 2010-06-24 21:41:47 +0000 (Thu, 24 Jun 2010) New Revision: 74082a2cfaac415f9b9e93927020fabf1eab3174 Log: fix a typo. Modified files: lib/racknga/utils.rb Modified: lib/racknga/utils.rb (+1 -1) =================================================================== --- lib/racknga/utils.rb 2010-06-24 21:40:14 +0000 (73de580) +++ lib/racknga/utils.rb 2010-06-24 21:41:47 +0000 (bbcc62f) @@ -30,7 +30,7 @@ module Racknga def normalize_options(options) normalized_options = {} options.each do |key, value| - value = normalized_options(value) if value.is_a?(Hash) + value = normalize_options(value) if value.is_a?(Hash) normalized_options[key.to_sym] = value end normalized_options From null+ranguba at clear-code.com Wed Jun 30 21:40:43 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 01 Jul 2010 01:40:43 +0000 Subject: [groonga-commit:1026] ranguba/rroonga [master] follow 'select' command's json format change Message-ID: <20100701014237.27C62170404@taiyaki.ru> Ryo Onodera 2010-07-01 01:40:43 +0000 (Thu, 01 Jul 2010) New Revision: b25e432e853894b52e864fd5c7588b0cde7d0c57 Log: follow 'select' command's json format change Modified files: lib/groonga/context.rb Modified: lib/groonga/context.rb (+2 -13) =================================================================== --- lib/groonga/context.rb 2010-06-24 12:41:00 +0000 (6a6c2cf) +++ lib/groonga/context.rb 2010-07-01 01:40:43 +0000 (a0fa5fc) @@ -36,19 +36,12 @@ module Groonga select.exec end - class SelectResult < Struct.new(:return_code, :start_time, :elapsed, - :error_message, - :n_hits, :columns, :values, + class SelectResult < Struct.new(:n_hits, :columns, :values, :drill_down) class << self def parse(json, drill_down_keys) - status, (select_result, *drill_down_results) = parse_json(json) + select_result, *drill_down_results = parse_json(json) result = new - return_code, start_time, elapsed, error_message = status - result.return_code = return_code - result.start_time = Time.at(start_time) - result.elapsed = elapsed - result.error_message = error_message n_hits, columns, values = extract_result(select_result) result.n_hits = n_hits result.columns = columns @@ -118,10 +111,6 @@ module Groonga @records ||= self.class.create_records(columns, values) end - def success? - return_code.zero? - end - class DrillDownResult < Struct.new(:n_hits, :columns, :values) def records @records ||= SelectResult.create_records(columns, values) From null+ranguba at clear-code.com Wed Jun 30 22:49:34 2010 From: null+ranguba at clear-code.com (null+ranguba at clear-code.com) Date: Thu, 01 Jul 2010 02:49:34 +0000 Subject: [groonga-commit:1027] ranguba/rroonga [master] add test_drill_down_with_no_hit Message-ID: <20100701025734.4DD61170404@taiyaki.ru> Ryo Onodera 2010-07-01 02:49:34 +0000 (Thu, 01 Jul 2010) New Revision: 460727d2801ef988e745c6d1ea3cc1ccd361ba34 Log: add test_drill_down_with_no_hit Modified files: test/test-context-select.rb Modified: test/test-context-select.rb (+28 -5) =================================================================== --- test/test-context-select.rb 2010-07-01 01:40:43 +0000 (9fc1f0d) +++ test/test-context-select.rb 2010-07-01 02:49:34 +0000 (e85b759) @@ -63,10 +63,7 @@ class ContextSelectTest < Test::Unit::TestCase :drill_down => ["_key", "book"], :drill_down_output_columns => "_key", :drill_down_limit => 10) - normalized_drill_down = {} - result.drill_down.each do |key, drill_down| - normalized_drill_down[key] = [drill_down.n_hits, drill_down.records] - end + drill_down = normalize_drill_down(result.drill_down) assert_equal([3, [{"_key" => "morita"}, {"_key" => "gunyara-kun"}, @@ -78,7 +75,24 @@ class ContextSelectTest < Test::Unit::TestCase "book" => [1, [{"_key" => "the groonga book"}]], }, ], - [result.n_hits, result.records, normalized_drill_down]) + [result.n_hits, result.records, drill_down]) + end + + def test_drill_down_with_no_hit + result = context.select(@users, + :filter => "_key == \"no hit\"", + :output_columns => ["_key"], + :drill_down => ["_key", "book"], + :drill_down_output_columns => "_key", + :drill_down_limit => 10) + drill_down = normalize_drill_down(result.drill_down) + assert_equal([0, [], + { + "_key" => [0, []], + "book" => [0, []], + }, + ], + [result.n_hits, result.records, drill_down]) end def test_time @@ -90,4 +104,13 @@ class ContextSelectTest < Test::Unit::TestCase }], result.records) end + + private + def normalize_drill_down(drill_down) + normalized_drill_down = {} + drill_down.each do |key, drill_down| + normalized_drill_down[key] = [drill_down.n_hits, drill_down.records] + end + normalized_drill_down + end end