diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb b/ruby/red-arrow-format/lib/arrow-format/array.rb index 2cccb7013ba..bc79edf9eb0 100644 --- a/ruby/red-arrow-format/lib/arrow-format/array.rb +++ b/ruby/red-arrow-format/lib/arrow-format/array.rb @@ -192,6 +192,9 @@ def initialize(*args) expected_n_args = "1 or 3" else type = args.shift + unless type.is_a?(Type) + type = self.class.type_class.try_convert(type) || type + end expected_n_args = "2 or 4" end args = build_data(args[0], type) if args.size == 1 @@ -461,12 +464,27 @@ class TimeArray < TemporalArray end class Time32Array < TimeArray + class << self + def type_class + Time32Type + end + end end class Time64Array < TimeArray + class << self + def type_class + Time64Type + end + end end class TimestampArray < TemporalArray + class << self + def type_class + TimestampType + end + end end class IntervalArray < TemporalArray diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb b/ruby/red-arrow-format/lib/arrow-format/type.rb index 0e57e62c321..6711f995fdb 100644 --- a/ruby/red-arrow-format/lib/arrow-format/type.rb +++ b/ruby/red-arrow-format/lib/arrow-format/type.rb @@ -476,6 +476,20 @@ def to_flatbuffers end class Time32Type < TimeType + class << self + def try_convert(value) + case value + when Symbol + unit = value + new(unit) + when self + value + else + nil + end + end + end + def initialize(unit) super(32, unit) end @@ -488,12 +502,30 @@ def buffer_type :s32 end + def pack_template + "l" + end + def build_array(...) Time32Array.new(self, ...) end end class Time64Type < TimeType + class << self + def try_convert(value) + case value + when Symbol + unit = value + new(unit) + when self + value + else + nil + end + end + end + def initialize(unit) super(64, unit) end @@ -506,6 +538,10 @@ def buffer_type :s64 end + def pack_template + "q" + end + def build_array(...) Time64Array.new(self, ...) end diff --git a/ruby/red-arrow-format/test/test-time32-array.rb b/ruby/red-arrow-format/test/test-time32-array.rb new file mode 100644 index 00000000000..98e865d9e25 --- /dev/null +++ b/ruby/red-arrow-format/test/test-time32-array.rb @@ -0,0 +1,60 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +class TestTime32Array < Test::Unit::TestCase + def setup + @time_00_00_10 = 10 + @time_00_01_10 = 60 + 10 + end + + sub_test_case("#initialize") do + def test_no_null + values = [@time_00_00_10, @time_00_01_10] + assert_equal(values, + ArrowFormat::Time32Array.new(:second, values).to_a) + end + + def test_mixed + values = [@time_00_00_10, nil, @time_00_01_10] + assert_equal(values, + ArrowFormat::Time32Array.new(:second, values).to_a) + end + end + + sub_test_case("#==") do + def test_no_slice + values = [@time_00_00_10, nil, @time_00_01_10] + array1 = ArrowFormat::Time32Array.new(:second, values) + array2 = ArrowFormat::Time32Array.new(:second, values) + assert_equal(array1, array2) + end + + def test_sliced + values = [@time_00_00_10, nil, @time_00_01_10] + array1 = ArrowFormat::Time32Array.new(:second, values) + array2 = ArrowFormat::Time32Array.new(:second, [0, *values, 0]) + assert_equal(array1, array2.slice(1, 3)) + end + + def test_sliced_different_content + values = [@time_00_00_10, nil, @time_00_01_10] + array1 = ArrowFormat::Time32Array.new(:second, values) + array2 = ArrowFormat::Time32Array.new(:second, [0, 0, *values, 0]) + assert_not_equal(array1, array2.slice(1, 3)) + end + end +end diff --git a/ruby/red-arrow-format/test/test-time64-array.rb b/ruby/red-arrow-format/test/test-time64-array.rb new file mode 100644 index 00000000000..3625a1917f2 --- /dev/null +++ b/ruby/red-arrow-format/test/test-time64-array.rb @@ -0,0 +1,60 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +class TestTime64Array < Test::Unit::TestCase + def setup + @time_00_00_10_000_000 = 10 * 1_000_000 + @time_00_01_10_000_000 = (60 + 10) * 1_000_000 + end + + sub_test_case("#initialize") do + def test_no_null + values = [@time_00_00_10_000_000, @time_00_01_10_000_000] + assert_equal(values, + ArrowFormat::Time64Array.new(:microsecond, values).to_a) + end + + def test_mixed + values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000] + assert_equal(values, + ArrowFormat::Time64Array.new(:microsecond, values).to_a) + end + end + + sub_test_case("#==") do + def test_no_slice + values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000] + array1 = ArrowFormat::Time64Array.new(:microsecond, values) + array2 = ArrowFormat::Time64Array.new(:microsecond, values) + assert_equal(array1, array2) + end + + def test_sliced + values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000] + array1 = ArrowFormat::Time64Array.new(:microsecond, values) + array2 = ArrowFormat::Time64Array.new(:microsecond, [0, *values, 0]) + assert_equal(array1, array2.slice(1, 3)) + end + + def test_sliced_different_content + values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000] + array1 = ArrowFormat::Time64Array.new(:microsecond, values) + array2 = ArrowFormat::Time64Array.new(:microsecond, [0, 0, *values, 0]) + assert_not_equal(array1, array2.slice(1, 3)) + end + end +end