rroonga 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/NEWS.ja.rdoc +12 -1
- data/NEWS.rdoc +11 -0
- data/ext/groonga/rb-grn-column.c +84 -10
- data/ext/groonga/rb-grn-object.c +13 -12
- data/ext/groonga/rb-grn-utils.c +4 -3
- data/ext/groonga/rb-grn.h +1 -1
- data/html/index.html +1 -1
- data/lib/groonga/record.rb +33 -6
- data/lib/groonga/schema.rb +1 -0
- data/test/test-fix-size-column.rb +10 -2
- data/test/test-index-column.rb +24 -2
- data/test/test-record.rb +43 -0
- data/test/test-variable-size-column.rb +10 -2
- metadata +3 -3
data/NEWS.ja.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= お知らせ
|
2
2
|
|
3
|
-
== 1.0.
|
3
|
+
== 1.0.4: 2010-11-29
|
4
4
|
|
5
5
|
=== 改良
|
6
6
|
|
@@ -31,6 +31,15 @@
|
|
31
31
|
* Groonga::Database#touchを追加。
|
32
32
|
* Groonga::Table#exist?を追加。
|
33
33
|
* Groonga::Record#valid?を追加。
|
34
|
+
* Groonga::Column#vector?を追加。
|
35
|
+
* Groonga::Column#scalar?を追加。
|
36
|
+
* Groonga::Record#vector_column?を追加。
|
37
|
+
* Groonga::Record#scalar_column?を追加。
|
38
|
+
* レコードIDが必要なところにrecord_raw_idを持つオブジェクトなら
|
39
|
+
Groonga::Record以外も渡せるようにした。
|
40
|
+
* Groonga::Record#record_raw_idを追加。
|
41
|
+
* ベクタの参照カラムの値にArray以外でもto_aryを持つオブジェクトを
|
42
|
+
設定できるようにした。
|
34
43
|
|
35
44
|
== 変更
|
36
45
|
|
@@ -41,6 +50,8 @@
|
|
41
50
|
場合はShortTextを使用するようにした。
|
42
51
|
* Groonga::Schema#loadをGroonga::Schema#restoreに改名。
|
43
52
|
* pkg-config 1.0.7対応。
|
53
|
+
* Groonga::Column#index?を追加。Groonga::Column#index_column?は非推奨。
|
54
|
+
* Groonga::Column#reference?を追加。Groonga::Column#reference_column?は非推奨。
|
44
55
|
|
45
56
|
=== 修正
|
46
57
|
|
data/NEWS.rdoc
CHANGED
@@ -31,6 +31,14 @@
|
|
31
31
|
* Added Groonga::Database#touch.
|
32
32
|
* Added Groonga::Table#exist?.
|
33
33
|
* Added Groonga::Record#valid?.
|
34
|
+
* Added Groonga::Column#vector?.
|
35
|
+
* Added Groonga::Column#scalar?.
|
36
|
+
* Added Groonga::Record#vector_column?.
|
37
|
+
* Added Groonga::Record#scalar_column?.
|
38
|
+
* Accepted any object that has record_raw_id method for record ID required
|
39
|
+
location. Groonga::Record isn't required.
|
40
|
+
* Added Groonga::Record#record_raw_id.
|
41
|
+
* Accepted any object that as to_ary method for reference vector column value.
|
34
42
|
|
35
43
|
== Changes
|
36
44
|
|
@@ -41,6 +49,9 @@
|
|
41
49
|
Groonga::Hash#create and Groonga::PatriciaTrie#create.
|
42
50
|
* Renamed Groonga::Schema#load to Groonga::Schema#restore.
|
43
51
|
* Supported pkg-confg 1.0.7.
|
52
|
+
* Added Groonga::Column#index? and deprecated Groonga::Column#index_column?.
|
53
|
+
* Added Groonga::Column#reference? and deprecated
|
54
|
+
Groonga::Column#reference_column?.
|
44
55
|
|
45
56
|
=== Fixes
|
46
57
|
|
data/ext/groonga/rb-grn-column.c
CHANGED
@@ -553,16 +553,18 @@ rb_grn_column_is_locked (int argc, VALUE *argv, VALUE self)
|
|
553
553
|
}
|
554
554
|
|
555
555
|
/*
|
556
|
-
* Document-method:
|
556
|
+
* Document-method: reference?
|
557
557
|
*
|
558
558
|
* call-seq:
|
559
|
-
* column.
|
559
|
+
* column.reference? -> true/false
|
560
560
|
*
|
561
561
|
* _column_の値がテーブルのレコードとなる場合は+true+を返し、
|
562
562
|
* そうでない場合は+false+を返す。
|
563
|
+
*
|
564
|
+
* @since: 1.0.5
|
563
565
|
*/
|
564
566
|
static VALUE
|
565
|
-
|
567
|
+
rb_grn_column_reference_p (VALUE self)
|
566
568
|
{
|
567
569
|
grn_ctx *context;
|
568
570
|
grn_obj *column;
|
@@ -589,16 +591,18 @@ rb_grn_column_reference_column_p (VALUE self)
|
|
589
591
|
}
|
590
592
|
|
591
593
|
/*
|
592
|
-
* Document-method:
|
594
|
+
* Document-method: index?
|
593
595
|
*
|
594
596
|
* call-seq:
|
595
|
-
* column.
|
597
|
+
* column.index? -> true/false
|
596
598
|
*
|
597
599
|
* _column_がGroonga::IndexColumnの場合は+true+を返し、
|
598
600
|
* そうでない場合は+false+を返す。
|
601
|
+
*
|
602
|
+
* @since: 1.0.5
|
599
603
|
*/
|
600
604
|
static VALUE
|
601
|
-
|
605
|
+
rb_grn_column_index_p (VALUE self)
|
602
606
|
{
|
603
607
|
grn_ctx *context;
|
604
608
|
grn_obj *column;
|
@@ -614,6 +618,72 @@ rb_grn_column_index_column_p (VALUE self)
|
|
614
618
|
}
|
615
619
|
}
|
616
620
|
|
621
|
+
/*
|
622
|
+
* Document-method: vector?
|
623
|
+
*
|
624
|
+
* call-seq:
|
625
|
+
* column.vector? -> true/false
|
626
|
+
*
|
627
|
+
* _column_がベクターカラムの場合は+true+を返し、
|
628
|
+
* そうでない場合は+false+を返す。
|
629
|
+
*
|
630
|
+
* @since: 1.0.5
|
631
|
+
*/
|
632
|
+
static VALUE
|
633
|
+
rb_grn_column_vector_p (VALUE self)
|
634
|
+
{
|
635
|
+
grn_ctx *context;
|
636
|
+
grn_obj *column;
|
637
|
+
|
638
|
+
rb_grn_column_deconstruct(SELF(self), &column, &context,
|
639
|
+
NULL, NULL,
|
640
|
+
NULL, NULL, NULL);
|
641
|
+
|
642
|
+
if (column->header.type == GRN_COLUMN_VAR_SIZE &&
|
643
|
+
((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) ==
|
644
|
+
GRN_OBJ_COLUMN_VECTOR)) {
|
645
|
+
return Qtrue;
|
646
|
+
} else {
|
647
|
+
return Qfalse;
|
648
|
+
}
|
649
|
+
}
|
650
|
+
|
651
|
+
/*
|
652
|
+
* Document-method: scalar?
|
653
|
+
*
|
654
|
+
* call-seq:
|
655
|
+
* column.scalar? -> true/false
|
656
|
+
*
|
657
|
+
* _column_がスカラーカラムの場合は+true+を返し、
|
658
|
+
* そうでない場合は+false+を返す。
|
659
|
+
*
|
660
|
+
* @since: 1.0.5
|
661
|
+
*/
|
662
|
+
static VALUE
|
663
|
+
rb_grn_column_scalar_p (VALUE self)
|
664
|
+
{
|
665
|
+
grn_ctx *context;
|
666
|
+
grn_obj *column;
|
667
|
+
|
668
|
+
rb_grn_column_deconstruct(SELF(self), &column, &context,
|
669
|
+
NULL, NULL,
|
670
|
+
NULL, NULL, NULL);
|
671
|
+
|
672
|
+
switch (column->header.type) {
|
673
|
+
case GRN_COLUMN_FIX_SIZE:
|
674
|
+
return Qtrue;
|
675
|
+
case GRN_COLUMN_VAR_SIZE:
|
676
|
+
if ((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) ==
|
677
|
+
GRN_OBJ_COLUMN_SCALAR) {
|
678
|
+
return Qtrue;
|
679
|
+
} else {
|
680
|
+
return Qfalse;
|
681
|
+
}
|
682
|
+
default:
|
683
|
+
return Qfalse;
|
684
|
+
}
|
685
|
+
}
|
686
|
+
|
617
687
|
void
|
618
688
|
rb_grn_init_column (VALUE mGrn)
|
619
689
|
{
|
@@ -628,10 +698,14 @@ rb_grn_init_column (VALUE mGrn)
|
|
628
698
|
rb_define_method(rb_cGrnColumn, "unlock", rb_grn_column_unlock, -1);
|
629
699
|
rb_define_method(rb_cGrnColumn, "clear_lock", rb_grn_column_clear_lock, -1);
|
630
700
|
rb_define_method(rb_cGrnColumn, "locked?", rb_grn_column_is_locked, -1);
|
631
|
-
rb_define_method(rb_cGrnColumn, "
|
632
|
-
|
633
|
-
|
634
|
-
|
701
|
+
rb_define_method(rb_cGrnColumn, "reference?", rb_grn_column_reference_p, 0);
|
702
|
+
/* deprecated: backward compatibility */
|
703
|
+
rb_define_alias(rb_cGrnColumn, "reference_column?", "reference?");
|
704
|
+
rb_define_method(rb_cGrnColumn, "index?", rb_grn_column_index_p, 0);
|
705
|
+
/* deprecated: backward compatibility */
|
706
|
+
rb_define_alias(rb_cGrnColumn, "index_column?", "index?");
|
707
|
+
rb_define_method(rb_cGrnColumn, "vector?", rb_grn_column_vector_p, 0);
|
708
|
+
rb_define_method(rb_cGrnColumn, "scalar?", rb_grn_column_scalar_p, 0);
|
635
709
|
|
636
710
|
rb_grn_init_fix_size_column(mGrn);
|
637
711
|
rb_grn_init_variable_size_column(mGrn);
|
data/ext/groonga/rb-grn-object.c
CHANGED
@@ -1199,7 +1199,7 @@ rb_uvector_value_p (RbGrnObject *rb_grn_object, VALUE rb_value)
|
|
1199
1199
|
case GRN_TABLE_NO_KEY:
|
1200
1200
|
case GRN_TABLE_VIEW:
|
1201
1201
|
first_element = rb_ary_entry(rb_value, 0);
|
1202
|
-
if (
|
1202
|
+
if (rb_respond_to(first_element, rb_intern("record_raw_id"))) {
|
1203
1203
|
return RB_GRN_TRUE;
|
1204
1204
|
}
|
1205
1205
|
break;
|
@@ -1217,25 +1217,26 @@ rb_grn_object_set_raw (RbGrnObject *rb_grn_object, grn_id id,
|
|
1217
1217
|
grn_ctx *context;
|
1218
1218
|
grn_obj value;
|
1219
1219
|
grn_rc rc;
|
1220
|
-
VALUE exception;
|
1220
|
+
VALUE exception, rb_values;
|
1221
1221
|
|
1222
1222
|
context = rb_grn_object->context;
|
1223
|
-
|
1224
|
-
|
1225
|
-
GRN_OBJ_INIT(&value, GRN_UVECTOR, 0,
|
1226
|
-
rb_grn_object->object->header.domain);
|
1227
|
-
RVAL2GRNUVECTOR(rb_value, context, &value, related_object);
|
1228
|
-
} else {
|
1229
|
-
GRN_OBJ_INIT(&value, GRN_VECTOR, 0, GRN_ID_NIL);
|
1230
|
-
RVAL2GRNVECTOR(rb_value, context, &value);
|
1231
|
-
}
|
1232
|
-
} else {
|
1223
|
+
rb_values = rb_check_array_type(rb_value);
|
1224
|
+
if (NIL_P(rb_values)) {
|
1233
1225
|
if (NIL_P(rb_value)) {
|
1234
1226
|
GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
|
1235
1227
|
} else {
|
1236
1228
|
GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
|
1237
1229
|
RVAL2GRNBULK(rb_value, context, &value);
|
1238
1230
|
}
|
1231
|
+
} else {
|
1232
|
+
if (rb_uvector_value_p(rb_grn_object, rb_values)) {
|
1233
|
+
GRN_OBJ_INIT(&value, GRN_UVECTOR, 0,
|
1234
|
+
rb_grn_object->object->header.domain);
|
1235
|
+
RVAL2GRNUVECTOR(rb_values, context, &value, related_object);
|
1236
|
+
} else {
|
1237
|
+
GRN_OBJ_INIT(&value, GRN_VECTOR, 0, GRN_ID_NIL);
|
1238
|
+
RVAL2GRNVECTOR(rb_values, context, &value);
|
1239
|
+
}
|
1239
1240
|
}
|
1240
1241
|
rc = grn_obj_set_value(context, rb_grn_object->object, id,
|
1241
1242
|
&value, flags);
|
data/ext/groonga/rb-grn-utils.c
CHANGED
@@ -555,13 +555,14 @@ rb_grn_uvector_from_ruby_object (VALUE object, grn_ctx *context,
|
|
555
555
|
id = NUM2UINT(value);
|
556
556
|
break;
|
557
557
|
default:
|
558
|
-
if (
|
559
|
-
id = NUM2UINT(rb_funcall(value, rb_intern("
|
558
|
+
if (rb_respond_to(value, rb_intern("record_raw_id"))) {
|
559
|
+
id = NUM2UINT(rb_funcall(value, rb_intern("record_raw_id"), 0));
|
560
560
|
} else {
|
561
561
|
grn_obj_unlink(context, uvector);
|
562
562
|
rb_raise(rb_eArgError,
|
563
563
|
"uvector value should be one of "
|
564
|
-
"[Fixnum
|
564
|
+
"[Fixnum or object that has #record_raw_id]: "
|
565
|
+
"%s (%s): %s",
|
565
566
|
rb_grn_inspect(value),
|
566
567
|
rb_grn_inspect(object),
|
567
568
|
rb_grn_inspect(related_object));
|
data/ext/groonga/rb-grn.h
CHANGED
data/html/index.html
CHANGED
data/lib/groonga/record.rb
CHANGED
@@ -21,8 +21,6 @@ module Groonga
|
|
21
21
|
class Record
|
22
22
|
# レコードが所属するテーブル
|
23
23
|
attr_reader :table
|
24
|
-
# レコードのID
|
25
|
-
attr_reader :id
|
26
24
|
# _table_の_id_に対応するレコードを作成する。_values_には各
|
27
25
|
# カラムに設定する値を以下のような形式で指定する。
|
28
26
|
#
|
@@ -129,7 +127,7 @@ module Groonga
|
|
129
127
|
#
|
130
128
|
# 名前が_name_のカラムが参照カラムであるなら+true+を返す。
|
131
129
|
def reference_column?(name)
|
132
|
-
column(name).
|
130
|
+
column(name).reference?
|
133
131
|
end
|
134
132
|
|
135
133
|
# call-seq:
|
@@ -138,7 +136,27 @@ module Groonga
|
|
138
136
|
# 名前が_name_のカラムが索引カラム
|
139
137
|
# (Groonga::IndexColumn)であるなら+true+を返す。
|
140
138
|
def index_column?(name)
|
141
|
-
column(name).
|
139
|
+
column(name).index?
|
140
|
+
end
|
141
|
+
|
142
|
+
# call-seq:
|
143
|
+
# record.vector_column?(name) -> true/false
|
144
|
+
#
|
145
|
+
# 名前が_name_のカラムの値がベクターであるなら+true+を返す。
|
146
|
+
#
|
147
|
+
# @since: 1.0.5
|
148
|
+
def vector_column?(name)
|
149
|
+
column(name).vector?
|
150
|
+
end
|
151
|
+
|
152
|
+
# call-seq:
|
153
|
+
# record.scalar_column?(name) -> true/false
|
154
|
+
#
|
155
|
+
# 名前が_name_のカラムの値がスカラーであるなら+true+を返す。
|
156
|
+
#
|
157
|
+
# @since: 1.0.5
|
158
|
+
def scalar_column?(name)
|
159
|
+
column(name).scalar?
|
142
160
|
end
|
143
161
|
|
144
162
|
# call-seq:
|
@@ -181,13 +199,22 @@ module Groonga
|
|
181
199
|
end
|
182
200
|
end
|
183
201
|
|
202
|
+
# call-seq:
|
203
|
+
# record.record_raw_id -> ID
|
204
|
+
#
|
205
|
+
# レコードのIDを返す。
|
206
|
+
def record_raw_id
|
207
|
+
@id
|
208
|
+
end
|
209
|
+
alias_method :id, :record_raw_id
|
210
|
+
|
184
211
|
# call-seq:
|
185
212
|
# record.score -> スコア値
|
186
213
|
#
|
187
214
|
# レコードのスコア値を返す。検索結果として生成されたテーブル
|
188
215
|
# のみに定義される。
|
189
216
|
def score
|
190
|
-
self["
|
217
|
+
self["_score"]
|
191
218
|
end
|
192
219
|
|
193
220
|
# call-seq:
|
@@ -199,7 +226,7 @@ module Groonga
|
|
199
226
|
# Groonga::Record#support_sub_recordsでこの値を利用でき
|
200
227
|
# るかがわかる。
|
201
228
|
def n_sub_records
|
202
|
-
self["
|
229
|
+
self["_nsubrecs"]
|
203
230
|
end
|
204
231
|
|
205
232
|
# call-seq:
|
data/lib/groonga/schema.rb
CHANGED
@@ -32,8 +32,16 @@ class FixSizeColumnTest < Test::Unit::TestCase
|
|
32
32
|
:path => @viewed_column_path.to_s)
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
assert_not_predicate(@viewed, :
|
35
|
+
def test_index?
|
36
|
+
assert_not_predicate(@viewed, :index?)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_vector?
|
40
|
+
assert_not_predicate(@viewed, :vector?)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_scalar?
|
44
|
+
assert_predicate(@viewed, :scalar?)
|
37
45
|
end
|
38
46
|
|
39
47
|
def test_inspect
|
data/test/test-index-column.rb
CHANGED
@@ -22,7 +22,7 @@ class IndexColumnTest < Test::Unit::TestCase
|
|
22
22
|
setup_database
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def test_index?
|
26
26
|
articles = Groonga::Array.create(:name => "Articles")
|
27
27
|
articles.define_column("content", "Text")
|
28
28
|
|
@@ -30,7 +30,29 @@ class IndexColumnTest < Test::Unit::TestCase
|
|
30
30
|
:default_tokenizer => "TokenBigram")
|
31
31
|
content_index = terms.define_index_column("content", articles,
|
32
32
|
:with_section => true)
|
33
|
-
assert_predicate(content_index, :
|
33
|
+
assert_predicate(content_index, :index?)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_vector?
|
37
|
+
articles = Groonga::Array.create(:name => "Articles")
|
38
|
+
articles.define_column("content", "Text")
|
39
|
+
|
40
|
+
terms = Groonga::Hash.create(:name => "Terms",
|
41
|
+
:default_tokenizer => "TokenBigram")
|
42
|
+
content_index = terms.define_index_column("content", articles,
|
43
|
+
:with_section => true)
|
44
|
+
assert_not_predicate(content_index, :vector?)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_scalar?
|
48
|
+
articles = Groonga::Array.create(:name => "Articles")
|
49
|
+
articles.define_column("content", "Text")
|
50
|
+
|
51
|
+
terms = Groonga::Hash.create(:name => "Terms",
|
52
|
+
:default_tokenizer => "TokenBigram")
|
53
|
+
content_index = terms.define_index_column("content", articles,
|
54
|
+
:with_section => true)
|
55
|
+
assert_not_predicate(content_index, :scalar?)
|
34
56
|
end
|
35
57
|
|
36
58
|
def test_array_set_with_record
|
data/test/test-record.rb
CHANGED
@@ -171,6 +171,20 @@ class RecordTest < Test::Unit::TestCase
|
|
171
171
|
assert_true(index.index_column?("content"))
|
172
172
|
end
|
173
173
|
|
174
|
+
def test_vector_column?
|
175
|
+
bookmark = @bookmarks.add
|
176
|
+
assert_false(bookmark.vector_column?("uri"))
|
177
|
+
morita = @users.add("morita")
|
178
|
+
assert_true(morita.vector_column?("addresses"))
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_scalar_column?
|
182
|
+
bookmark = @bookmarks.add
|
183
|
+
assert_true(bookmark.scalar_column?("uri"))
|
184
|
+
morita = @users.add("morita")
|
185
|
+
assert_false(morita.scalar_column?("addresses"))
|
186
|
+
end
|
187
|
+
|
174
188
|
def test_score
|
175
189
|
groonga = @bookmarks.add
|
176
190
|
groonga["content"] = "full text search search search engine."
|
@@ -282,4 +296,33 @@ class RecordTest < Test::Unit::TestCase
|
|
282
296
|
users = @users.select {|record| record.key == "morita"}
|
283
297
|
assert_predicate(users.to_a[0], :support_sub_records?)
|
284
298
|
end
|
299
|
+
|
300
|
+
def test_set_record_like_object
|
301
|
+
kou_at_clear_code = @addresses.add(:mail => "kou@clear-code.com")
|
302
|
+
record_like_class = Class.new do
|
303
|
+
attr_reader :record_raw_id
|
304
|
+
def initialize(record_raw_id)
|
305
|
+
@record_raw_id = record_raw_id
|
306
|
+
end
|
307
|
+
end
|
308
|
+
record_like_object = record_like_class.new(kou_at_clear_code.record_raw_id)
|
309
|
+
kou = @users.add("kou")
|
310
|
+
kou.addresses = [record_like_object]
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_set_array_like_records
|
314
|
+
kou_at_clear_code = @addresses.add(:mail => "kou@clear-code.com")
|
315
|
+
array_like_class = Class.new do
|
316
|
+
def initialize(records)
|
317
|
+
@records = records
|
318
|
+
end
|
319
|
+
|
320
|
+
def to_ary
|
321
|
+
@records
|
322
|
+
end
|
323
|
+
end
|
324
|
+
array_like_object = array_like_class.new([kou_at_clear_code])
|
325
|
+
kou = @users.add("kou")
|
326
|
+
kou.addresses = array_like_object
|
327
|
+
end
|
285
328
|
end
|
@@ -50,8 +50,16 @@ class VariableSizeColumnTest < Test::Unit::TestCase
|
|
50
50
|
@yu = @users.add(:name => "Yutaro Shimamura")
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
assert_not_predicate(@nick_names, :
|
53
|
+
def test_index?
|
54
|
+
assert_not_predicate(@nick_names, :index?)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_vector?
|
58
|
+
assert_predicate(@nick_names, :vector?)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_scalar?
|
62
|
+
assert_not_predicate(@nick_names, :scalar?)
|
55
63
|
end
|
56
64
|
|
57
65
|
def test_inspect
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rroonga
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 4
|
10
|
+
version: 1.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kouhei Sutou
|