rroonga 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/groonga/rb-grn.h CHANGED
@@ -84,7 +84,7 @@ RB_GRN_BEGIN_DECLS
84
84
 
85
85
  #define RB_GRN_MAJOR_VERSION 4
86
86
  #define RB_GRN_MINOR_VERSION 0
87
- #define RB_GRN_MICRO_VERSION 0
87
+ #define RB_GRN_MICRO_VERSION 1
88
88
 
89
89
  #define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
90
90
 
@@ -96,6 +96,7 @@ RB_GRN_BEGIN_DECLS
96
96
  #define RB_GRN_TABLE_KEY_SUPPORT(object) ((RbGrnTableKeySupport *)(object))
97
97
  #define RB_GRN_TABLE_CURSOR(object) ((RbGrnTableCursort *)(object))
98
98
  #define RB_GRN_COLUMN(object) ((RbGrnColumn *)(object))
99
+ #define RB_GRN_VARIABLE_SIZE_COLUMN(object) ((RbGrnVariableSizeColumn *)(object))
99
100
  #define RB_GRN_INDEX_COLUMN(object) ((RbGrnIndexColumn *)(object))
100
101
  #define RB_GRN_ACCESSOR(object) ((RbGrnAccessor *)(object))
101
102
  #define RB_GRN_EXPRESSION(object) ((RbGrnExpression *)(object))
@@ -159,11 +160,19 @@ struct _RbGrnColumn
159
160
  grn_obj *value;
160
161
  };
161
162
 
163
+ typedef struct _RbGrnVariableSizeColumn RbGrnVariableSizeColumn;
164
+ struct _RbGrnVariableSizeColumn
165
+ {
166
+ RbGrnColumn parent;
167
+ grn_obj *element_value;
168
+ };
169
+
162
170
  typedef struct _RbGrnIndexColumn RbGrnIndexColumn;
163
171
  struct _RbGrnIndexColumn
164
172
  {
165
173
  RbGrnColumn parent;
166
174
  grn_obj *old_value;
175
+ grn_obj *set_value;
167
176
  grn_obj *id_query;
168
177
  grn_obj *string_query;
169
178
  };
@@ -490,6 +499,13 @@ void rb_grn_column_deconstruct (RbGrnColumn *rb_grn_column,
490
499
  grn_id *range_id,
491
500
  grn_obj **range);
492
501
 
502
+ void rb_grn_variable_size_column_bind (RbGrnVariableSizeColumn *rb_grn_column,
503
+ grn_ctx *context,
504
+ grn_obj *column);
505
+ void rb_grn_variable_size_column_finalizer(grn_ctx *context,
506
+ grn_obj *column,
507
+ RbGrnVariableSizeColumn *rb_grn_column);
508
+
493
509
  void rb_grn_index_column_bind (RbGrnIndexColumn *rb_grn_index_column,
494
510
  grn_ctx *context,
495
511
  grn_obj *object);
@@ -503,6 +519,7 @@ void rb_grn_index_column_deconstruct (RbGrnIndexColumn *rb_grn_in
503
519
  grn_obj **domain,
504
520
  grn_obj **value,
505
521
  grn_obj **old_value,
522
+ grn_obj **set_value,
506
523
  grn_id *range_id,
507
524
  grn_obj **range,
508
525
  grn_obj **id_query,
@@ -395,10 +395,6 @@ module Groonga
395
395
  return nil if normalizer.nil?
396
396
  normalizer.name
397
397
  end
398
-
399
- def default_normalizer?(normalizer_name)
400
- normalizer_name == "NormalizerAuto"
401
- end
402
398
  end
403
399
 
404
400
  # @private
@@ -418,15 +414,12 @@ module Groonga
418
414
  end
419
415
  if table.domain
420
416
  parameters << ":key_type => #{table.domain.name.dump}"
421
- if default_normalizer?(_normalizer_name)
422
- parameters << ":key_normalize => true"
423
- end
424
417
  end
425
418
  default_tokenizer = table.default_tokenizer
426
419
  if default_tokenizer
427
420
  parameters << ":default_tokenizer => #{default_tokenizer.name.dump}"
428
421
  end
429
- if _normalizer_name and not default_normalizer?(_normalizer_name)
422
+ if _normalizer_name
430
423
  parameters << ":normalizer => #{_normalizer_name.dump}"
431
424
  end
432
425
  end
@@ -460,9 +453,11 @@ module Groonga
460
453
  name = column.local_name
461
454
  reference = column.range
462
455
  options = column_options(column)
463
- arguments = [dump_object(name),
464
- dump_object(reference.name),
465
- options].compact.join(", ")
456
+ arguments = [
457
+ dump_object(name),
458
+ dump_object(reference.name),
459
+ options,
460
+ ].compact.join(", ")
466
461
  write(" table.reference(#{arguments})\n")
467
462
  end
468
463
 
@@ -477,9 +472,17 @@ module Groonga
477
472
  end
478
473
  dump_object(name)
479
474
  end.join(", ")
480
- arguments = [dump_object(target_table_name),
481
- sources.size == 1 ? source_names : "[#{source_names}]",
482
- ":name => #{dump_object(column.local_name)}"]
475
+ options = {
476
+ :name => column.local_name,
477
+ }
478
+ options[:with_section] = true if column.with_section?
479
+ options[:with_weight] = true if column.with_weight?
480
+ options[:with_position] = true if column.with_position?
481
+ arguments = [
482
+ dump_object(target_table_name),
483
+ sources.size == 1 ? source_names : "[#{source_names}]",
484
+ dump_options(options),
485
+ ]
483
486
  write(" table.index(#{arguments.join(', ')})\n")
484
487
  end
485
488
 
@@ -514,15 +517,19 @@ module Groonga
514
517
  def column_options(column)
515
518
  options = {}
516
519
  options[:type] = :vector if column.vector?
520
+ options[:with_weight] = true if column.with_weight?
517
521
  return nil if options.empty?
518
522
 
519
- dumped_options = ""
520
- options.each do |key, value|
523
+ dump_options(options)
524
+ end
525
+
526
+ def dump_options(options)
527
+ dumped_options = options.collect do |key, value|
521
528
  dumped_key = dump_object(key)
522
529
  dumped_value = dump_object(value)
523
- dumped_options << "#{dumped_key} => #{dumped_value}"
530
+ "#{dumped_key} => #{dumped_value}"
524
531
  end
525
- dumped_options
532
+ dumped_options.join(", ")
526
533
  end
527
534
 
528
535
  def dump_object(object)
@@ -552,7 +559,6 @@ module Groonga
552
559
  flags << "TABLE_DAT_KEY"
553
560
  end
554
561
  if table.domain
555
- flags << "KEY_NORMALIZE" if default_normalizer?(_normalizer_name)
556
562
  if table.is_a?(Groonga::PatriciaTrie) and table.register_key_with_sis?
557
563
  flags << "KEY_WITH_SIS"
558
564
  end
@@ -570,7 +576,7 @@ module Groonga
570
576
  parameters << "--default_tokenizer #{default_tokenizer.name}"
571
577
  end
572
578
  end
573
- if _normalizer_name and not default_normalizer?(_normalizer_name)
579
+ if _normalizer_name
574
580
  parameters << "--normalizer #{_normalizer_name}"
575
581
  end
576
582
  write("table_create #{table.name} #{parameters.join(' ')}\n")
@@ -595,6 +601,7 @@ module Groonga
595
601
  elsif column.vector?
596
602
  flags << "COLUMN_VECTOR"
597
603
  end
604
+ flags << "WITH_WEIGHT" if column.with_weight?
598
605
  # TODO: support COMPRESS_ZLIB and COMPRESS_LZO?
599
606
  parameters << "#{flags.join('|')}"
600
607
  parameters << "#{column.range.name}"
@@ -687,8 +694,12 @@ module Groonga
687
694
  def resolve_value(record, column, value)
688
695
  case value
689
696
  when ::Array
690
- value.collect do |v|
691
- resolve_value(record, column, v)
697
+ if column.vector? and column.with_weight?
698
+ resolve_weight_vector_value(record, column, value)
699
+ else
700
+ value.collect do |v|
701
+ resolve_value(record, column, v)
702
+ end
692
703
  end
693
704
  when Groonga::Record
694
705
  if value.support_key?
@@ -726,6 +737,19 @@ module Groonga
726
737
  end
727
738
  end
728
739
 
740
+ def resolve_weight_vector_value(record, column, entries)
741
+ resolved_weight_vector_entries = {}
742
+ sorted_entries = entries.sort_by do |entry|
743
+ entry[:value]
744
+ end
745
+ sorted_entries.each do |entry|
746
+ resolved_value = resolve_value(record, column, entry[:value])
747
+ resolved_weight = resolve_value(record, column, entry[:weight])
748
+ resolved_weight_vector_entries[resolved_value] = resolved_weight
749
+ end
750
+ resolved_weight_vector_entries
751
+ end
752
+
729
753
  def fix_encoding(value)
730
754
  if value.encoding == ::Encoding::ASCII_8BIT
731
755
  value.force_encoding(@table.context.ruby_encoding)
@@ -79,10 +79,8 @@ module Groonga
79
79
  end
80
80
  end
81
81
 
82
- if builders.empty? or builders == [self]
83
- expression.append_constant(1)
84
- expression.append_constant(1)
85
- expression.append_operation(Groonga::Operation::OR, 2)
82
+ if builders.empty?
83
+ expression.append_constant(true)
86
84
  else
87
85
  combined_builder = builders.inject(nil) do |previous, builder|
88
86
  if previous.nil?
@@ -470,82 +470,6 @@ module Groonga
470
470
  end
471
471
  end
472
472
 
473
- # 名前が_name_のビューを作成する。以下の省略形。
474
- #
475
- # <pre>
476
- # !!!ruby
477
- # Groonga::Schema.define do |schema|
478
- # schema.create_view(name, options) do |view|
479
- # # ...
480
- # end
481
- # end
482
- # </pre>
483
- # ブロックには {Groonga::Schema::ViewDefinition} オブジェ
484
- # クトがわたるので、そのオブジェクトを利用してビュー
485
- # の詳細を定義する。
486
- #
487
- # @param options [::Hash] The name and value
488
- # pairs. Omitted names are initialized as the default value.
489
- # @option options :force The force
490
- #
491
- # +true+ を指定すると既存の同名のビューが
492
- # 存在していても、強制的にビューを作成する。
493
- # @option options :context (Groonga::Context.default) The context
494
- #
495
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
496
- # @option options :path The path
497
- #
498
- # ビューを保存するパスを指定する。
499
- # パスを指定すると永続ビューになる。
500
- # @option options :persistent (true) The persistent
501
- #
502
- # ビューを永続ビューとする。 +:path:+ を省略した場
503
- # 合はパス名は自動的に作成される。デフォルトでは永続
504
- # ビューとなる。
505
- def create_view(name, options={}, &block)
506
- define do |schema|
507
- schema.create_view(name, options, &block)
508
- end
509
- end
510
-
511
- # 名前が _name_ のテーブルを削除する。
512
- #
513
- # @param options [::Hash] The name and value
514
- # pairs. Omitted names are initialized as the default value.
515
- # @option options :context (Groonga::context.default) The context
516
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
517
- def remove_view(name, options={})
518
- define do |schema|
519
- schema.remove_view(name, options)
520
- end
521
- end
522
-
523
- # 名前が _name_ のビューを変更する。以下の省略形。
524
- #
525
- # <pre>
526
- # !!!ruby
527
- # Groonga::Schema.define do |schema|
528
- # schema.change_view(name, options) do |view|
529
- # # ...
530
- # end
531
- # end
532
- # </pre>
533
- #
534
- # ブロックには {Groonga::Schema::ViewDefinition} オブジェ
535
- # クトがわたるので、そのオブジェクトを利用してテーブル
536
- # の詳細を定義する。
537
- #
538
- # @param options [::Hash] The name and value
539
- # pairs. Omitted names are initialized as the default value.
540
- # @option options :context (Groonga::Context.default) The context
541
- #
542
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
543
- def change_view(name, options={}, &block)
544
- define do |schema|
545
- schema.change_view(name, options, &block)
546
- end
547
- end
548
-
549
473
  # 以下と同様:
550
474
  #
551
475
  # <pre>
@@ -825,69 +749,6 @@ module Groonga
825
749
  @definitions << definition
826
750
  end
827
751
 
828
- # 名前が _name_ のビューを作成する。
829
- #
830
- # ビューの作成は {#define} を呼び出すまでは実行されないこ
831
- # とに注意すること。
832
- #
833
- # @param options [::Hash] The name and value
834
- # pairs. Omitted names are initialized as the default value.
835
- # @option options :force The force
836
- #
837
- # +true+ を指定すると既存の同名の
838
- # ビューが存在していても、強制的にビューを作成する。
839
- # @option options [Groonga::Context] :context (Groonga::Schema.new) The context
840
- #
841
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
842
- # {Groonga::Schema.new} で指定していない場合は
843
- # {Groonga::Context.default} を使用する。
844
- # @option options :path The path
845
- #
846
- # テーブルを保存するパスを指定する。パスを指定すると
847
- # 永続テーブルになる。
848
- # @option options :persistent (true) The persistent
849
- #
850
- # テーブルを永続テーブルとする。 +:path:+ を省略した場合は
851
- # パス名は自動的に作成される。デフォルトでは永続テーブルとなる。
852
- def create_view(name, options={})
853
- definition = ViewDefinition.new(name, @options.merge(options || {}))
854
- yield(definition)
855
- @definitions << definition
856
- end
857
-
858
- # 名前が _name_ のビューを削除する。
859
- #
860
- # ビューの削除は {#define} を呼び出すまでは実行されないことに
861
- # 注意すること。
862
- #
863
- # @param options [::Hash] The name and value
864
- # pairs. Omitted names are initialized as the default value.
865
- # @option options [Groonga::Context] :context (Groonga::Context.default)
866
- # The context
867
- #
868
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
869
- def remove_view(name, options={})
870
- definition = ViewRemoveDefinition.new(name, @options.merge(options || {}))
871
- @definitions << definition
872
- end
873
-
874
- # 名前が _name_ のビューを変更する。
875
- #
876
- # ビューの変更は {#define} を呼び出すまでは実行されないこ
877
- # とに注意すること。
878
- #
879
- # @param options [::Hash] The name and value
880
- # pairs. Omitted names are initialized as the default value.
881
- # @option options :context (Groonga::Context.default) The context
882
- #
883
- # スキーマ定義時に使用する {Groonga::Context} を指定する。
884
- def change_view(name, options={})
885
- options = @options.merge(options || {}).merge(:change => true)
886
- definition = ViewDefinition.new(name, options)
887
- yield(definition)
888
- @definitions << definition
889
- end
890
-
891
752
  # 以下と同様:
892
753
  #
893
754
  # <pre>
@@ -1010,6 +871,11 @@ module Groonga
1010
871
  #
1011
872
  # - :scalar := スカラ値(単独の値)を格納する。
1012
873
  # - :vector := 値の配列を格納する。
874
+ # @option options [Boolean] :with_weight (false)
875
+ # It specifies whether making the column weight vector column or not.
876
+ # Weight vector column can store weight for each element.
877
+ #
878
+ # You can't use this option for scalar column.
1013
879
  # @option options :compress
1014
880
  #
1015
881
  # 値の圧縮方法を指定する。省略した場合は、圧縮しない。
@@ -1445,7 +1311,7 @@ module Groonga
1445
1311
  target_column_full_name = target_column_full_name.name
1446
1312
  end
1447
1313
  target_table, target_column = target_column_full_name.split(/\./, 2)
1448
- target_columns = [target_column]
1314
+ target_columns = [target_column].compact
1449
1315
  key = [target_table, target_columns]
1450
1316
  else
1451
1317
  target_table_name = target_table_or_target_column_full_name
@@ -1591,99 +1457,6 @@ module Groonga
1591
1457
  end
1592
1458
  end
1593
1459
 
1594
- # スキーマ定義時に {Groonga::Schema.create_view} や
1595
- # {Groonga::Schema#create_view} からブロックに渡されてくる
1596
- # オブジェクト
1597
- class ViewDefinition
1598
- # ビューの名前
1599
- attr_reader :name
1600
-
1601
- # @private
1602
- def initialize(name, options)
1603
- @name = name
1604
- @name = @name.to_s if @name.is_a?(Symbol)
1605
- @tables = []
1606
- validate_options(options)
1607
- @options = options
1608
- end
1609
-
1610
- # @private
1611
- def define
1612
- view = context[@name]
1613
- if @options[:change]
1614
- raise TableNotExists.new(@name) if view.nil?
1615
- else
1616
- if view and @options[:force]
1617
- view.remove
1618
- view = nil
1619
- end
1620
- view ||= Groonga::View.create(create_options)
1621
- end
1622
- @tables.each do |table|
1623
- unless table.is_a?(Groonga::Table)
1624
- table_name = table
1625
- table = context[table_name]
1626
- raise TableNotExists.new(table_name) if table.nil?
1627
- end
1628
- view.add_table(table)
1629
- end
1630
- view
1631
- end
1632
-
1633
- # 名前が _table_ のテーブルをビューに追加する。
1634
- def add(table)
1635
- table = table.to_s if table.is_a?(Symbol)
1636
- @tables << table
1637
- self
1638
- end
1639
-
1640
- # @private
1641
- def context
1642
- @options[:context] || Groonga::Context.default
1643
- end
1644
-
1645
- private
1646
- # @private
1647
- AVAILABLE_OPTION_KEYS = [:context, :change, :force,
1648
- :path, :persistent, :named_path]
1649
- # @private
1650
- def validate_options(options)
1651
- return if options.nil?
1652
- unknown_keys = options.keys - AVAILABLE_OPTION_KEYS
1653
- unless unknown_keys.empty?
1654
- raise UnknownOptions.new(options, unknown_keys, AVAILABLE_OPTION_KEYS)
1655
- end
1656
- end
1657
-
1658
- # @private
1659
- def create_options
1660
- {
1661
- :name => @name,
1662
- :path => @options[:path],
1663
- :persistent => persistent?,
1664
- :context => context,
1665
- }
1666
- end
1667
-
1668
- # @private
1669
- def persistent?
1670
- @options[:persistent].nil? ? true : @options[:persistent]
1671
- end
1672
- end
1673
-
1674
- # @private
1675
- class ViewRemoveDefinition
1676
- def initialize(name, options={})
1677
- @name = name
1678
- @options = options
1679
- end
1680
-
1681
- def define
1682
- context = @options[:context] || Groonga::Context.default
1683
- context[@name].remove
1684
- end
1685
- end
1686
-
1687
1460
  # @private
1688
1461
  class ColumnDefinition
1689
1462
  include Path
@@ -1729,13 +1502,22 @@ module Groonga
1729
1502
  end
1730
1503
 
1731
1504
  def same_column?(context, column)
1732
- column.range == resolved_type(context)
1505
+ return false unless column.range == resolved_type(context)
1506
+ if column.scalar?
1507
+ [nil, :scalar].include?(@options[:type])
1508
+ else
1509
+ return false unless @options[:type] == :vector
1510
+ with_weight = @options[:with_weight]
1511
+ with_weight = false if with_weight.nil?
1512
+ column.with_weight? == with_weight
1513
+ end
1733
1514
  end
1734
1515
 
1735
1516
  def define_options(context, table)
1736
1517
  {
1737
1518
  :path => path(context, table),
1738
1519
  :type => @options[:type],
1520
+ :with_weight => @options[:with_weight],
1739
1521
  :compress => @options[:compress],
1740
1522
  }
1741
1523
  end