activerecord-multirange 0.1.0 → 1.1.0
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/.rubocop.yml +50 -7
- data/CHANGELOG.md +5 -1
- data/Gemfile +0 -6
- data/Gemfile.lock +18 -2
- data/README.md +2 -0
- data/config.ru +9 -0
- data/lib/activerecord-multirange/adapter.rb +44 -7
- data/lib/activerecord-multirange/oid/multi_range.rb +18 -5
- data/lib/activerecord-multirange/schema_statements.rb +11 -11
- data/lib/activerecord-multirange/type_map.rb +16 -4
- data/lib/activerecord-multirange/version.rb +1 -1
- data/lib/activerecord-multirange.rb +17 -11
- metadata +74 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f84a86677dd7f4427b636524b7dc09ea1c5eb049db16ebc727e86b8801847245
|
4
|
+
data.tar.gz: e7d313979f6e205f7cc07685b6fad56d6e483e99ae8cf985eb04c5fd0c2a3acb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80c306db18783b1f27457706731efa67594c06ac8a7efd7fbcf5e368befbe2166ba136a676026fa6bab076fe191de1563b36cdaab3690a3b01bf9ca0d97007a3
|
7
|
+
data.tar.gz: 6eb784fa47af4ad1fb395d0e5f4dc56bb9e2a8f2a48b85d24bf036e5bcebc93ed128d9a9f24d75144eb05f285089d8b47e27820571e6b4cece2b43ca33f9af41
|
data/.rubocop.yml
CHANGED
@@ -1,13 +1,56 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2
|
2
|
+
TargetRubyVersion: 3.1.2
|
3
|
+
EnabledByDefault: true
|
4
|
+
Exclude:
|
5
|
+
- 'db/**/*'
|
6
|
+
- 'config/**/*'
|
7
|
+
- 'script/**/*'
|
8
|
+
- 'bin/{rails,rake}'
|
3
9
|
|
4
|
-
|
10
|
+
require:
|
11
|
+
- rubocop-rails
|
12
|
+
|
13
|
+
inherit_from:
|
14
|
+
- node_modules/@prettier/plugin-ruby/rubocop.yml
|
15
|
+
|
16
|
+
Style:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Metrics:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Lint:
|
5
23
|
Enabled: true
|
6
|
-
EnforcedStyle: double_quotes
|
7
24
|
|
8
|
-
|
25
|
+
Lint/ConstantResolution:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Lint/AssignmentInCondition:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Lint/NumberConversion:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Rails:
|
9
35
|
Enabled: true
|
10
|
-
EnforcedStyle: double_quotes
|
11
36
|
|
12
|
-
|
13
|
-
|
37
|
+
Rails/SkipsModelValidations:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Rails/DefaultScope:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Rails/HasManyOrHasOneDependent:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Rails/InverseOf:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Rails/Date:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Rails/TimeZone:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Rails/RequestReferer:
|
56
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
activerecord-multirange (
|
4
|
+
activerecord-multirange (1.1.0)
|
5
5
|
pg (>= 1)
|
6
6
|
rails (>= 6)
|
7
7
|
|
@@ -76,8 +76,16 @@ GEM
|
|
76
76
|
ast (2.4.2)
|
77
77
|
builder (3.2.4)
|
78
78
|
coderay (1.1.3)
|
79
|
+
combustion (1.3.7)
|
80
|
+
activesupport (>= 3.0.0)
|
81
|
+
railties (>= 3.0.0)
|
82
|
+
thor (>= 0.14.6)
|
79
83
|
concurrent-ruby (1.2.2)
|
80
84
|
crass (1.0.6)
|
85
|
+
database_cleaner-active_record (2.1.0)
|
86
|
+
activerecord (>= 5.a)
|
87
|
+
database_cleaner-core (~> 2.0.0)
|
88
|
+
database_cleaner-core (2.0.1)
|
81
89
|
date (3.3.3)
|
82
90
|
diff-lcs (1.5.0)
|
83
91
|
erubi (1.12.0)
|
@@ -108,8 +116,12 @@ GEM
|
|
108
116
|
net-smtp (0.3.3)
|
109
117
|
net-protocol
|
110
118
|
nio4r (2.5.9)
|
119
|
+
nokogiri (1.15.4-arm64-darwin)
|
120
|
+
racc (~> 1.4)
|
111
121
|
nokogiri (1.15.4-x86_64-darwin)
|
112
122
|
racc (~> 1.4)
|
123
|
+
nokogiri (1.15.4-x86_64-linux)
|
124
|
+
racc (~> 1.4)
|
113
125
|
parallel (1.23.0)
|
114
126
|
parser (3.2.2.1)
|
115
127
|
ast (~> 2.4.1)
|
@@ -190,14 +202,18 @@ GEM
|
|
190
202
|
zeitwerk (2.6.11)
|
191
203
|
|
192
204
|
PLATFORMS
|
205
|
+
arm64-darwin-23
|
193
206
|
x86_64-darwin-22
|
207
|
+
x86_64-linux
|
194
208
|
|
195
209
|
DEPENDENCIES
|
196
210
|
activerecord-multirange!
|
211
|
+
combustion (~> 1.3)
|
212
|
+
database_cleaner-active_record
|
197
213
|
pry
|
198
214
|
rake (~> 13.0)
|
199
215
|
rspec (~> 3.0)
|
200
|
-
rubocop
|
216
|
+
rubocop
|
201
217
|
|
202
218
|
BUNDLED WITH
|
203
219
|
2.4.13
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
This gem adds full suppport of [Postgress Multiranges](https://www.postgresql.org/docs/14/rangetypes.html#RANGETYPES-BUILTIN) types.
|
4
4
|
|
5
|
+
[](https://badge.fury.io/rb/activerecord-multirange)
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Install the gem and add to the application's Gemfile by executing:
|
data/config.ru
ADDED
@@ -8,17 +8,54 @@ module Activerecord
|
|
8
8
|
load_multirange_types
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.native_database_types
|
12
|
+
super.merge(
|
13
|
+
{
|
14
|
+
datemultirange: {
|
15
|
+
name: 'datemultirange'
|
16
|
+
},
|
17
|
+
nummultirange: {
|
18
|
+
name: 'nummultirange'
|
19
|
+
},
|
20
|
+
tsmultirange: {
|
21
|
+
name: 'tsmultirange'
|
22
|
+
},
|
23
|
+
tstzmultirange: {
|
24
|
+
name: 'tstzmultirange'
|
25
|
+
},
|
26
|
+
int4multirange: {
|
27
|
+
name: 'int4multirange'
|
28
|
+
},
|
29
|
+
int8multirange: {
|
30
|
+
name: 'int8multirange'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
11
36
|
def load_multirange_types
|
12
|
-
initializer =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
37
|
+
initializer =
|
38
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::TypeMapInitializer
|
39
|
+
.new(type_map)
|
40
|
+
|
41
|
+
# Query for multirange types and their corresponding base types (not range types)
|
42
|
+
# We need to get the range's subtype (e.g., date) not the range type itself
|
43
|
+
query = <<-QUERY.squish
|
44
|
+
SELECT m.oid, m.typname, m.typelem, m.typdelim, m.typinput,
|
45
|
+
pr.rngsubtype, m.typtype, m.typbasetype
|
46
|
+
FROM pg_type m
|
47
|
+
JOIN pg_type r ON REPLACE(m.typname, 'multirange', 'range') = r.typname
|
48
|
+
JOIN pg_range pr ON r.oid = pr.rngtypid
|
49
|
+
WHERE m.typtype = 'm';
|
17
50
|
QUERY
|
18
51
|
|
19
|
-
|
20
|
-
|
52
|
+
# Use exec_query for all Rails versions since execute_and_clear is private
|
53
|
+
result = exec_query(query, 'SCHEMA', [])
|
54
|
+
# Convert rows to hash format with column names as keys
|
55
|
+
records = result.rows.map do |row|
|
56
|
+
result.columns.zip(row).to_h
|
21
57
|
end
|
58
|
+
initializer.register_multirange_type(records)
|
22
59
|
end
|
23
60
|
end
|
24
61
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_model"
|
4
|
+
|
3
5
|
module Activerecord
|
4
6
|
module Multirange
|
5
7
|
module OID # :nodoc:
|
@@ -11,6 +13,8 @@ module Activerecord
|
|
11
13
|
def initialize(subtype, type = :multirange)
|
12
14
|
@subtype = subtype
|
13
15
|
@type = type
|
16
|
+
|
17
|
+
super()
|
14
18
|
end
|
15
19
|
|
16
20
|
def deserialize(value)
|
@@ -74,6 +78,8 @@ module Activerecord
|
|
74
78
|
# * https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-IO
|
75
79
|
# * https://www.postgresql.org/docs/current/rowtypes.html#ROWTYPES-IO-SYNTAX
|
76
80
|
def unquote(value)
|
81
|
+
return value if value.nil?
|
82
|
+
|
77
83
|
if value.start_with?('"') && value.end_with?('"')
|
78
84
|
unquoted_value = value[1..-2]
|
79
85
|
unquoted_value.gsub!('""', '"')
|
@@ -85,15 +91,21 @@ module Activerecord
|
|
85
91
|
end
|
86
92
|
|
87
93
|
def parse_lower(value)
|
88
|
-
return infinity_value(value, negative: true) if ["", "-infinity"].include?(value)
|
94
|
+
return infinity_value(value, negative: true) if value.nil? || ["", "-infinity"].include?(value)
|
89
95
|
|
90
|
-
|
96
|
+
unquoted = unquote(value)
|
97
|
+
return nil if unquoted.nil?
|
98
|
+
|
99
|
+
@subtype.deserialize(unquoted)
|
91
100
|
end
|
92
101
|
|
93
102
|
def parse_upper(value)
|
94
|
-
return infinity_value(value) if ["", "infinity"].include?(value)
|
103
|
+
return infinity_value(value) if value.nil? || ["", "infinity"].include?(value)
|
95
104
|
|
96
|
-
|
105
|
+
unquoted = unquote(value)
|
106
|
+
return nil if unquoted.nil?
|
107
|
+
|
108
|
+
@subtype.deserialize(unquoted)
|
97
109
|
end
|
98
110
|
|
99
111
|
def extract_range_data(value)
|
@@ -113,7 +125,8 @@ module Activerecord
|
|
113
125
|
|
114
126
|
if !infinity?(extracted[:from]) && extracted[:exclude_start]
|
115
127
|
raise ArgumentError,
|
116
|
-
"The Ruby Range object does not support excluding the beginning of a Range.
|
128
|
+
"The Ruby Range object does not support excluding the beginning of a Range.
|
129
|
+
(unsupported value: '#{value}')"
|
117
130
|
end
|
118
131
|
|
119
132
|
::Range.new(extracted[:from], extracted[:to], extracted[:exclude_end])
|
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
module Activerecord
|
4
4
|
module Multirange
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
5
|
+
module SchemaStatements
|
6
|
+
def native_database_types
|
7
|
+
super.merge({
|
8
|
+
tsmultirange: { name: "tsmultirange" },
|
9
|
+
datemultirange: { name: "datemultirange" },
|
10
|
+
tstzmultirange: { name: "tstzmultirange" },
|
11
|
+
nummultirange: { name: "nummultirange" },
|
12
|
+
int8multirange: { name: "int8multirange" },
|
13
|
+
int4multirange: { name: "int4multirange" }
|
14
|
+
})
|
16
15
|
end
|
17
16
|
end
|
17
|
+
end
|
18
18
|
end
|
@@ -1,15 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'activerecord-multirange/oid/multi_range'
|
4
4
|
|
5
5
|
module Activerecord
|
6
6
|
module Multirange
|
7
7
|
module TypeMap
|
8
8
|
def register_multirange_type(records)
|
9
9
|
records.each do |row|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
multirange_oid = row['oid']
|
11
|
+
range_oid = row['rngsubtype']
|
12
|
+
type_name = row['typname']
|
13
|
+
|
14
|
+
# Get the range subtype from the type map
|
15
|
+
range_type = @store.lookup(range_oid)
|
16
|
+
next unless range_type
|
17
|
+
|
18
|
+
# Create and register the multirange type
|
19
|
+
multirange_type = Activerecord::Multirange::OID::MultiRange.new(
|
20
|
+
range_type,
|
21
|
+
type_name.to_sym
|
22
|
+
)
|
23
|
+
|
24
|
+
register(multirange_oid, multirange_type)
|
13
25
|
end
|
14
26
|
end
|
15
27
|
end
|
@@ -1,24 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
3
|
+
require 'activerecord-multirange/version'
|
4
|
+
require 'activerecord-multirange/adapter'
|
5
|
+
require 'activerecord-multirange/quoting'
|
6
|
+
require 'activerecord-multirange/schema_statements'
|
7
|
+
require 'activerecord-multirange/table_definition'
|
8
|
+
require 'activerecord-multirange/type_map'
|
9
|
+
require 'active_record'
|
10
10
|
|
11
11
|
module Activerecord
|
12
12
|
module Multirange
|
13
|
-
class Error < StandardError
|
13
|
+
class Error < StandardError
|
14
|
+
end
|
14
15
|
|
15
16
|
def self.add_multirange_column_type
|
16
17
|
ActiveSupport.on_load(:active_record) do
|
17
18
|
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(Adapter)
|
18
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::TypeMapInitializer
|
19
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::TypeMapInitializer
|
20
|
+
.prepend(TypeMap)
|
19
21
|
ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting.prepend(Quoting)
|
20
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(
|
21
|
-
|
22
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(
|
23
|
+
SchemaStatements
|
24
|
+
)
|
25
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition.prepend(
|
26
|
+
TableDefinition
|
27
|
+
)
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-multirange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gustavo Warmling Teixeira
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-06-03 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: pg
|
@@ -38,6 +37,76 @@ dependencies:
|
|
38
37
|
- - ">="
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '6'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: combustion
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.3'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: database_cleaner-active_record
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: pry
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rspec
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '3.0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: rubocop
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
41
110
|
description: Add PostgreSQL multiranges support
|
42
111
|
email:
|
43
112
|
- gustavowt@gmail.com
|
@@ -53,6 +122,7 @@ files:
|
|
53
122
|
- LICENSE.txt
|
54
123
|
- README.md
|
55
124
|
- Rakefile
|
125
|
+
- config.ru
|
56
126
|
- lib/activerecord-multirange.rb
|
57
127
|
- lib/activerecord-multirange/adapter.rb
|
58
128
|
- lib/activerecord-multirange/oid/multi_range.rb
|
@@ -68,7 +138,6 @@ licenses:
|
|
68
138
|
metadata:
|
69
139
|
homepage_uri: https://github.com/gustavowt/activerecord-multirange
|
70
140
|
source_code_uri: https://github.com/gustavowt/activerecord-multirange
|
71
|
-
post_install_message:
|
72
141
|
rdoc_options: []
|
73
142
|
require_paths:
|
74
143
|
- lib
|
@@ -83,8 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
152
|
- !ruby/object:Gem::Version
|
84
153
|
version: '0'
|
85
154
|
requirements: []
|
86
|
-
rubygems_version: 3.
|
87
|
-
signing_key:
|
155
|
+
rubygems_version: 3.6.6
|
88
156
|
specification_version: 4
|
89
157
|
summary: PostgreSQL multiranges support
|
90
158
|
test_files: []
|