sequel-tstzrange-fields 0.1.1 → 0.2.1
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.
- checksums.yaml +4 -4
- data/lib/sequel/plugins/tstzrange_fields.rb +18 -17
- data/lib/sequel_tstzrange_fields/version.rb +5 -0
- metadata +15 -69
- data/spec/sequel/plugins/tstzrange_fields_spec.rb +0 -179
- data/spec/spec_helper.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 602f1c9282af7052d0c4b5131a2f9872a383a51783f8f43bfd601066c5121136
|
4
|
+
data.tar.gz: 9d3594a668a50adb1ab8f88a33db59d4fc779d4012f281f01791f98ae74c302d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 327f56f8a6e62c01fd7c86620859a375fa3243f2019ce20e466f9e0651277803070618f4573f3272571c23b1defbee1a599826d2406507358e50e7c1d58c47b0
|
7
|
+
data.tar.gz: 18b71bc1c26e4913d4fb9f81f88ca2368c12f5bc9ff38ae483f8482566d67a9a080f7109abd4d8e36863897132a02c9cc5e7a28af09d6a690c20e205e0aa2a00
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
3
|
+
require "sequel"
|
4
|
+
require "sequel/model"
|
5
|
+
|
6
|
+
require_relative "../../sequel_tstzrange_fields/version"
|
6
7
|
|
7
8
|
# Plugin for adding methods for working with time ranges.
|
8
9
|
#
|
@@ -32,12 +33,12 @@ require 'yajl'
|
|
32
33
|
module Sequel
|
33
34
|
module Plugins
|
34
35
|
module TstzrangeFields
|
35
|
-
VERSION =
|
36
|
+
VERSION = SequelTstzrangeFields::VERSION
|
36
37
|
|
37
38
|
def self.configure(model, *args)
|
38
39
|
unless model.db.schema_type_class(:tstzrange)
|
39
|
-
msg =
|
40
|
-
|
40
|
+
msg = "tstzrange_fields plugin requires pg_range db extension to be installed. " \
|
41
|
+
"Use db.extension(:pg_range) after the db = Sequel.connect call."
|
41
42
|
raise msg
|
42
43
|
end
|
43
44
|
args << :period if args.empty?
|
@@ -81,17 +82,17 @@ module Sequel
|
|
81
82
|
|
82
83
|
model.define_method(set_column_method) do |value|
|
83
84
|
case value
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
when Sequel::Postgres::PGRange
|
86
|
+
self[column] = value
|
87
|
+
when Float::INFINITY
|
88
|
+
range = Sequel::Postgres::PGRange.new(nil, nil, empty: false, db_type: :tstzrange)
|
89
|
+
self[column] = range
|
90
|
+
when "empty"
|
91
|
+
self[column] = Sequel::Postgres::PGRange.empty(:tstzrange)
|
91
92
|
else
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
beg = value.respond_to?(:begin) ? value.begin : (value[:begin] || value["begin"])
|
94
|
+
en = value.respond_to?(:end) ? value.end : (value[:end] || value["end"])
|
95
|
+
self[column] = self.class.new_tstzrange(beg, en)
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
@@ -106,7 +107,7 @@ module Sequel
|
|
106
107
|
|
107
108
|
model.define_method(get_end_method) do
|
108
109
|
r = send(get_column_method)
|
109
|
-
return r
|
110
|
+
return r&.end
|
110
111
|
end
|
111
112
|
|
112
113
|
model.define_method(set_end_method) do |new_time|
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-tstzrange-fields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lithic Tech
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: pg
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +38,6 @@ dependencies:
|
|
52
38
|
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: yajl-ruby
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
41
|
- !ruby/object:Gem::Dependency
|
70
42
|
name: rake
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,44 +70,16 @@ dependencies:
|
|
98
70
|
name: rubocop
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
100
72
|
requirements:
|
101
|
-
- - "
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop-rake
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rubocop-rspec
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
73
|
+
- - "~>"
|
130
74
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
75
|
+
version: '1.48'
|
132
76
|
type: :development
|
133
77
|
prerelease: false
|
134
78
|
version_requirements: !ruby/object:Gem::Requirement
|
135
79
|
requirements:
|
136
|
-
- - "
|
80
|
+
- - "~>"
|
137
81
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
82
|
+
version: '1.48'
|
139
83
|
- !ruby/object:Gem::Dependency
|
140
84
|
name: rubocop-sequel
|
141
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,7 +94,9 @@ dependencies:
|
|
150
94
|
- - ">="
|
151
95
|
- !ruby/object:Gem::Version
|
152
96
|
version: '0'
|
153
|
-
description:
|
97
|
+
description: 'Gem for enabling time ranges when working with postgres
|
98
|
+
|
99
|
+
'
|
154
100
|
email:
|
155
101
|
- hello@lithic.tech
|
156
102
|
executables: []
|
@@ -158,12 +104,12 @@ extensions: []
|
|
158
104
|
extra_rdoc_files: []
|
159
105
|
files:
|
160
106
|
- lib/sequel/plugins/tstzrange_fields.rb
|
161
|
-
-
|
162
|
-
|
163
|
-
homepage:
|
107
|
+
- lib/sequel_tstzrange_fields/version.rb
|
108
|
+
homepage: https://github.com/lithictech/sequel-tstzrange-fields
|
164
109
|
licenses:
|
165
110
|
- MIT
|
166
|
-
metadata:
|
111
|
+
metadata:
|
112
|
+
rubygems_mfa_required: 'true'
|
167
113
|
post_install_message:
|
168
114
|
rdoc_options: []
|
169
115
|
require_paths:
|
@@ -172,14 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
118
|
requirements:
|
173
119
|
- - ">="
|
174
120
|
- !ruby/object:Gem::Version
|
175
|
-
version: 2.
|
121
|
+
version: 2.7.0
|
176
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
123
|
requirements:
|
178
124
|
- - ">="
|
179
125
|
- !ruby/object:Gem::Version
|
180
126
|
version: '0'
|
181
127
|
requirements: []
|
182
|
-
rubygems_version: 3.
|
128
|
+
rubygems_version: 3.3.3
|
183
129
|
signing_key:
|
184
130
|
specification_version: 4
|
185
131
|
summary: Gem for enabling time ranges when working with postgres
|
@@ -1,179 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/integer/time'
|
4
|
-
require 'sequel'
|
5
|
-
require 'sequel/model'
|
6
|
-
require 'sequel/extensions/pg_range'
|
7
|
-
require 'sequel/plugins/tstzrange_fields'
|
8
|
-
|
9
|
-
RSpec.describe Sequel::Plugins::TstzrangeFields do
|
10
|
-
before(:each) do
|
11
|
-
@db = Sequel.connect('postgres://sequel_tstzrange:sequel_tstzrange@localhost:18101/sequel_tstzrange_test')
|
12
|
-
@db.extension(:pg_range)
|
13
|
-
end
|
14
|
-
after(:each) do
|
15
|
-
@db.disconnect
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'errors if the db does not have pg_range registered' do
|
19
|
-
db = Sequel.connect('postgres://sequel_tstzrange:sequel_tstzrange@localhost:18101/sequel_tstzrange_test')
|
20
|
-
db.create_table(:tstzrange_fields_test, temp: true) do
|
21
|
-
primary_key :id
|
22
|
-
end
|
23
|
-
expect do
|
24
|
-
mc = Class.new(Sequel::Model(db[:tstzrange_fields_test]))
|
25
|
-
mc.plugin(:tstzrange_fields)
|
26
|
-
end.to raise_error(/tstzrange_fields plugin requires/)
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'with no fields given' do
|
30
|
-
let(:model_class) do
|
31
|
-
@db.create_table(:tstzrange_fields_test, temp: true) do
|
32
|
-
primary_key :id
|
33
|
-
tstzrange :period
|
34
|
-
end
|
35
|
-
mc = Class.new(Sequel::Model(@db[:tstzrange_fields_test]))
|
36
|
-
mc.class_eval do
|
37
|
-
def initialize(*)
|
38
|
-
super
|
39
|
-
self[:period] ||= self.class.new_tstzrange(nil, nil)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
mc.plugin(:tstzrange_fields)
|
43
|
-
mc
|
44
|
-
end
|
45
|
-
|
46
|
-
let(:model_object) { model_class.new }
|
47
|
-
|
48
|
-
it 'uses :period as the high-level accessor' do
|
49
|
-
expect(model_object).to respond_to(:period, :period=, :period_begin, :period_begin=, :period_end, :period_end=)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'sets a default empty range' do
|
53
|
-
expect(model_object.period).to be_empty
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'for the given field' do
|
58
|
-
let(:model_class) do
|
59
|
-
@db.create_table(:tstzrange_fields_test, temp: true) do
|
60
|
-
primary_key :id
|
61
|
-
tstzrange :range
|
62
|
-
end
|
63
|
-
mc = Class.new(Sequel::Model(@db[:tstzrange_fields_test]))
|
64
|
-
mc.plugin(:tstzrange_fields, :range)
|
65
|
-
mc.class_eval do
|
66
|
-
def initialize(*)
|
67
|
-
super
|
68
|
-
self[:range] ||= self.class.new_tstzrange(nil, nil)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
mc
|
72
|
-
end
|
73
|
-
|
74
|
-
let(:model_object) { model_class.new }
|
75
|
-
|
76
|
-
let(:t) { Time.at(3.years.ago.to_i) }
|
77
|
-
let(:ts) { t.to_s }
|
78
|
-
|
79
|
-
it 'sets a default empty range' do
|
80
|
-
expect(model_object.range).to be_empty
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'can set an infinite range by assigning the field to Float::INFINITY' do
|
84
|
-
expect(model_object.range).to be_empty
|
85
|
-
|
86
|
-
model_object.range = Float::INFINITY
|
87
|
-
expect(model_object.range_begin).to be_nil
|
88
|
-
expect(model_object.range_end).to be_nil
|
89
|
-
expect(model_object.range).not_to be_empty
|
90
|
-
model_object.save_changes
|
91
|
-
expect(model_class.where(Sequel.function(:lower_inf, :range)).count).to eq(1)
|
92
|
-
expect(model_class.where(Sequel.function(:upper_inf, :range)).count).to eq(1)
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'can set an empty range by assigning the field to the string "empty"' do
|
96
|
-
model_object.range_begin = t
|
97
|
-
model_object.range_end = t + 1.day
|
98
|
-
expect(model_object.range).not_to be_empty
|
99
|
-
|
100
|
-
model_object.range = 'empty'
|
101
|
-
expect(model_object.range).to be_empty
|
102
|
-
expect(model_object.range_begin).to be_nil
|
103
|
-
expect(model_object.range_end).to be_nil
|
104
|
-
model_object.save_changes
|
105
|
-
expect(model_class.where(Sequel.function(:lower_inf, :range)).count).to eq(0)
|
106
|
-
expect(model_class.where(Sequel.function(:upper_inf, :range)).count).to eq(0)
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'can get/set the start' do
|
110
|
-
model_object.range_begin = t
|
111
|
-
expect(model_object.range_begin).to eq(t)
|
112
|
-
expect(model_object.save_changes.refresh.range_begin).to eq(t)
|
113
|
-
|
114
|
-
model_object.range_begin = ts
|
115
|
-
expect(model_object.range_begin).to eq(t)
|
116
|
-
expect(model_object.save_changes.refresh.range_begin).to eq(t)
|
117
|
-
|
118
|
-
model_object.range_begin = nil
|
119
|
-
expect(model_object.range_begin).to be_nil
|
120
|
-
expect(model_object.save_changes.refresh.range_begin).to be_nil
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'can get/set the end' do
|
124
|
-
model_object.range_end = t
|
125
|
-
expect(model_object.range_end).to eq(t)
|
126
|
-
expect(model_object.save_changes.refresh.range_end).to eq(t)
|
127
|
-
|
128
|
-
model_object.range_end = ts
|
129
|
-
expect(model_object.range_end).to eq(t)
|
130
|
-
expect(model_object.save_changes.refresh.range_end).to eq(t)
|
131
|
-
|
132
|
-
model_object.range_end = nil
|
133
|
-
expect(model_object.range_end).to be_nil
|
134
|
-
expect(model_object.save_changes.refresh.range_end).to be_nil
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'can initialize an instance using accessors' do
|
138
|
-
o = model_class.create(range_begin: nil, range_end: nil)
|
139
|
-
expect(o.range).to be_empty
|
140
|
-
|
141
|
-
o = model_class.create(range_begin: Time.now, range_end: 1.hour.from_now)
|
142
|
-
expect(o.range).not_to be_cover(30.minutes.ago)
|
143
|
-
expect(o.range).to be_cover(30.minutes.from_now)
|
144
|
-
expect(o.range).not_to be_cover(90.minutes.from_now)
|
145
|
-
|
146
|
-
o = model_class.create(range_begin: nil, range_end: Time.now)
|
147
|
-
expect(o.range).to be_cover(30.minutes.ago)
|
148
|
-
expect(o.range).not_to be_cover(30.minutes.from_now)
|
149
|
-
|
150
|
-
o = model_class.create(range_begin: Time.now, range_end: nil)
|
151
|
-
expect(o.range).not_to be_cover(30.minutes.ago)
|
152
|
-
expect(o.range).to be_cover(30.minutes.from_now)
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'can be assigned to directly with an object with begin/end methods or keys' do
|
156
|
-
early = 1.day.ago
|
157
|
-
late = 2.days.from_now
|
158
|
-
|
159
|
-
forms = [
|
160
|
-
early...late,
|
161
|
-
OpenStruct.new(begin: early, end: late),
|
162
|
-
{ begin: early, end: late },
|
163
|
-
{ 'begin' => early, 'end' => late }
|
164
|
-
]
|
165
|
-
|
166
|
-
forms.each do |value|
|
167
|
-
model_object.range = value
|
168
|
-
model_object.save_changes.refresh
|
169
|
-
expect(model_object.range_begin).to be_within(1).of(early)
|
170
|
-
expect(model_object.range_end).to be_within(1).of(late)
|
171
|
-
end
|
172
|
-
|
173
|
-
model_object.range = {}
|
174
|
-
expect(model_object.range).to be_empty
|
175
|
-
|
176
|
-
expect { model_object.range = 1 }.to raise_error(TypeError)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'sequel/plugins/tstzrange_fields'
|
4
|
-
|
5
|
-
RSpec.configure do |config|
|
6
|
-
# config.full_backtrace = true
|
7
|
-
|
8
|
-
# RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = 600
|
9
|
-
|
10
|
-
config.expect_with :rspec do |expectations|
|
11
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
12
|
-
end
|
13
|
-
|
14
|
-
config.mock_with :rspec do |mocks|
|
15
|
-
mocks.verify_partial_doubles = true
|
16
|
-
end
|
17
|
-
|
18
|
-
config.order = :random
|
19
|
-
Kernel.srand config.seed
|
20
|
-
|
21
|
-
config.filter_run :focus
|
22
|
-
config.run_all_when_everything_filtered = true
|
23
|
-
config.disable_monkey_patching!
|
24
|
-
config.default_formatter = 'doc' if config.files_to_run.one?
|
25
|
-
end
|