torque-postgresql 0.2.16 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +76 -3
- data/lib/torque-postgresql.rb +1 -0
- data/lib/torque/postgresql.rb +6 -0
- data/lib/torque/postgresql/adapter.rb +2 -4
- data/lib/torque/postgresql/adapter/database_statements.rb +23 -9
- data/lib/torque/postgresql/adapter/oid.rb +12 -1
- data/lib/torque/postgresql/adapter/oid/box.rb +28 -0
- data/lib/torque/postgresql/adapter/oid/circle.rb +37 -0
- data/lib/torque/postgresql/adapter/oid/enum.rb +9 -5
- data/lib/torque/postgresql/adapter/oid/enum_set.rb +44 -0
- data/lib/torque/postgresql/adapter/oid/line.rb +59 -0
- data/lib/torque/postgresql/adapter/oid/range.rb +52 -0
- data/lib/torque/postgresql/adapter/oid/segment.rb +73 -0
- data/lib/torque/postgresql/adapter/quoting.rb +21 -0
- data/lib/torque/postgresql/adapter/schema_definitions.rb +7 -0
- data/lib/torque/postgresql/adapter/schema_dumper.rb +10 -1
- data/lib/torque/postgresql/arel.rb +3 -0
- data/lib/torque/postgresql/arel/infix_operation.rb +42 -0
- data/lib/torque/postgresql/arel/nodes.rb +32 -0
- data/lib/torque/postgresql/arel/operations.rb +18 -0
- data/lib/torque/postgresql/arel/visitors.rb +28 -2
- data/lib/torque/postgresql/associations.rb +8 -0
- data/lib/torque/postgresql/associations/association.rb +30 -0
- data/lib/torque/postgresql/associations/association_scope.rb +116 -0
- data/lib/torque/postgresql/associations/belongs_to_many_association.rb +117 -0
- data/lib/torque/postgresql/associations/builder.rb +2 -0
- data/lib/torque/postgresql/associations/builder/belongs_to_many.rb +121 -0
- data/lib/torque/postgresql/associations/builder/has_many.rb +15 -0
- data/lib/torque/postgresql/associations/join_dependency/join_association.rb +15 -0
- data/lib/torque/postgresql/associations/preloader.rb +25 -0
- data/lib/torque/postgresql/associations/preloader/association.rb +64 -0
- data/lib/torque/postgresql/attributes.rb +2 -0
- data/lib/torque/postgresql/attributes/builder.rb +1 -0
- data/lib/torque/postgresql/attributes/builder/enum.rb +23 -15
- data/lib/torque/postgresql/attributes/builder/period.rb +452 -0
- data/lib/torque/postgresql/attributes/enum.rb +11 -8
- data/lib/torque/postgresql/attributes/enum_set.rb +256 -0
- data/lib/torque/postgresql/attributes/lazy.rb +1 -1
- data/lib/torque/postgresql/attributes/period.rb +31 -0
- data/lib/torque/postgresql/attributes/type_map.rb +3 -5
- data/lib/torque/postgresql/autosave_association.rb +40 -0
- data/lib/torque/postgresql/auxiliary_statement.rb +201 -198
- data/lib/torque/postgresql/auxiliary_statement/settings.rb +20 -12
- data/lib/torque/postgresql/base.rb +161 -2
- data/lib/torque/postgresql/config.rb +91 -9
- data/lib/torque/postgresql/geometry_builder.rb +92 -0
- data/lib/torque/postgresql/i18n.rb +1 -1
- data/lib/torque/postgresql/railtie.rb +18 -5
- data/lib/torque/postgresql/reflection.rb +21 -0
- data/lib/torque/postgresql/reflection/abstract_reflection.rb +109 -0
- data/lib/torque/postgresql/reflection/association_reflection.rb +30 -0
- data/lib/torque/postgresql/reflection/belongs_to_many_reflection.rb +44 -0
- data/lib/torque/postgresql/reflection/has_many_reflection.rb +13 -0
- data/lib/torque/postgresql/reflection/runtime_reflection.rb +12 -0
- data/lib/torque/postgresql/reflection/through_reflection.rb +11 -0
- data/lib/torque/postgresql/relation.rb +11 -10
- data/lib/torque/postgresql/relation/auxiliary_statement.rb +11 -18
- data/lib/torque/postgresql/relation/inheritance.rb +2 -2
- data/lib/torque/postgresql/relation/merger.rb +11 -7
- data/lib/torque/postgresql/schema_cache.rb +1 -1
- data/lib/torque/postgresql/version.rb +1 -1
- data/lib/torque/range.rb +40 -0
- metadata +41 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b0809f9b876678e23210f46f24f06fd04191a0f
|
4
|
+
data.tar.gz: 854147b9660c9f30979224d3d92949ddeb0dcae0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8a7c3422d3592263efdb14a76063a6bfd78fb573cf6bc904b1a8053c0baa5272924576a61b87319d28ef8b44c9de6562ef98c669f16733c6e9c4fa1a5246787
|
7
|
+
data.tar.gz: 4b5c5dec025229542565c9ba2f5de62b983cf442bb040d547012e7c0a55e52f3c0093a6c720b3aa78d0437dc8ce67e965ead58f6b5cf903868ad034a07233136
|
data/README.rdoc
CHANGED
@@ -16,7 +16,7 @@ A short rundown of some of the major features:
|
|
16
16
|
It creates a separated class to hold each enum set that can be used by multiple
|
17
17
|
models, it also keeps the database consistent. The enum type is known to have
|
18
18
|
better performance against string- and integer-like enums.
|
19
|
-
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.
|
19
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/static/datatype-enum.html]
|
20
20
|
|
21
21
|
create_enum :roles, %i(visitor manager admin)
|
22
22
|
|
@@ -28,11 +28,84 @@ better performance against string- and integer-like enums.
|
|
28
28
|
|
29
29
|
{Learn more}[link:classes/Torque/PostgreSQL/Attributes/Enum.html]
|
30
30
|
|
31
|
+
* Enum set type manager
|
32
|
+
|
33
|
+
The enum type is known to have a better performance against string- and integer-
|
34
|
+
like enums. Now with the array option, which behaves like binary assignment,
|
35
|
+
each record can have multiple enum values.
|
36
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/static/datatype-enum.html]
|
37
|
+
|
38
|
+
create_enum :permissions, %i(read write exec)
|
39
|
+
|
40
|
+
add_column :posts, :creator_permissions, :permissions, array: true
|
41
|
+
|
42
|
+
Enum::PermissionsSet.new(3) # [:read, :write]
|
43
|
+
|
44
|
+
post.creator_permissions.write?
|
45
|
+
|
46
|
+
{Learn more}[link:classes/Torque/PostgreSQL/Attributes/EnumSet.html]
|
47
|
+
|
48
|
+
* Period complex queries
|
49
|
+
|
50
|
+
This provides extended and complex calculations over date and time ranges. In a
|
51
|
+
few words, you can now store `start_time` and `finish_time` in the same column
|
52
|
+
and relies on the methods provided here to fo your magic.
|
53
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/functions-range.html]
|
54
|
+
|
55
|
+
add_column :events, :period, :tsrange
|
56
|
+
add_column :events, :interval, :interval
|
57
|
+
|
58
|
+
Event.create(title: 'Test', period: ['2019-01-01 12:00:00', '2019-01-01 14:00:00'], interval: 15.minutes)
|
59
|
+
|
60
|
+
Event.overlapping('2019-01-01 13:00:00', '2019-01-01 15:00:00').count
|
61
|
+
|
62
|
+
Event.not_real_overlapping('2019-01-01 11:00:00', '2019-01-01 13:00:00').empty?
|
63
|
+
|
64
|
+
{Learn more}[link:classes/Torque/PostgreSQL/Attributes/Builder/Period.html]
|
65
|
+
|
66
|
+
* Has many array association
|
67
|
+
|
68
|
+
The idea is simple, one table stores all the ids and the other one says that
|
69
|
+
`has many` records on that table because its records ids exist in the column of
|
70
|
+
the array. Like: `Tag has many Videos connected through an array`.
|
71
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/arrays.html]
|
72
|
+
|
73
|
+
add_column :videos, :tag_ids, :bigint, array: true
|
74
|
+
|
75
|
+
Tag.has_many :videos, array: true
|
76
|
+
|
77
|
+
Tag.videos.size
|
78
|
+
|
79
|
+
Tag.videos << another_video
|
80
|
+
|
81
|
+
{Learn more}[link:classes/Torque/PostgreSQL/Reflection/AbstractReflection.html]
|
82
|
+
|
83
|
+
* Belongs to many association
|
84
|
+
|
85
|
+
The original `belongs_to` associations define a `SingularAssociation`, which
|
86
|
+
means that it could be extended with `array: true`. In this case, I decided to
|
87
|
+
create my own `CollectionAssociation` called `belongs_to_many`, which behaves
|
88
|
+
similar to the single one, but storing and returning a list of records.
|
89
|
+
|
90
|
+
With this, now you can say things like `Project belongs to many employees`,
|
91
|
+
which is more syntactically correct than `Project has many employees`
|
92
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/arrays.html]
|
93
|
+
|
94
|
+
add_column :videos, :tag_ids, :bigint, array: true
|
95
|
+
|
96
|
+
Video.belongs_to_many :tags
|
97
|
+
|
98
|
+
Video.tags.size
|
99
|
+
|
100
|
+
Video.tags << Tag.new(title: 'rails')
|
101
|
+
|
102
|
+
{Learn more}[link:classes/Torque/PostgreSQL/Reflection/BelongsToManyReflection.html]
|
103
|
+
|
31
104
|
* Distinct On
|
32
105
|
|
33
106
|
MySQL-like group by statement on queries. It keeps only the first row of each
|
34
107
|
set of rows where the given expressions evaluate to equal.
|
35
|
-
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.
|
108
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/static/sql-select.html#SQL-DISTINCT]
|
36
109
|
|
37
110
|
User.distinct_on(:name).all
|
38
111
|
|
@@ -42,7 +115,7 @@ set of rows where the given expressions evaluate to equal.
|
|
42
115
|
|
43
116
|
Provides a way to write auxiliary statements for use in a larger query. It's
|
44
117
|
reconfigured on the model, and then can be used during querying process.
|
45
|
-
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.
|
118
|
+
{PostgreSQL Docs}[https://www.postgresql.org/docs/9.6/static/queries-with.html]
|
46
119
|
|
47
120
|
class User < ActiveRecord::Base
|
48
121
|
auxiliary_statement :last_comment do |cte|
|
data/lib/torque-postgresql.rb
CHANGED
data/lib/torque/postgresql.rb
CHANGED
@@ -4,23 +4,29 @@ require 'active_model'
|
|
4
4
|
require 'active_record'
|
5
5
|
require 'active_support'
|
6
6
|
|
7
|
+
require 'active_support/core_ext/date/acts_like'
|
8
|
+
require 'active_support/core_ext/time/zones'
|
7
9
|
require 'active_support/core_ext/hash/compact'
|
8
10
|
require 'active_record/connection_adapters/postgresql_adapter'
|
9
11
|
|
10
12
|
require 'torque/postgresql/config'
|
11
13
|
require 'torque/postgresql/version'
|
12
14
|
require 'torque/postgresql/collector'
|
15
|
+
require 'torque/postgresql/geometry_builder'
|
13
16
|
|
14
17
|
require 'torque/postgresql/i18n'
|
15
18
|
require 'torque/postgresql/arel'
|
16
19
|
require 'torque/postgresql/adapter'
|
20
|
+
require 'torque/postgresql/associations'
|
17
21
|
require 'torque/postgresql/attributes'
|
22
|
+
require 'torque/postgresql/autosave_association'
|
18
23
|
require 'torque/postgresql/auxiliary_statement'
|
19
24
|
require 'torque/postgresql/base'
|
20
25
|
require 'torque/postgresql/inheritance'
|
21
26
|
require 'torque/postgresql/coder'
|
22
27
|
require 'torque/postgresql/migration'
|
23
28
|
require 'torque/postgresql/relation'
|
29
|
+
require 'torque/postgresql/reflection'
|
24
30
|
require 'torque/postgresql/schema_cache'
|
25
31
|
require 'torque/postgresql/schema_dumper'
|
26
32
|
|
@@ -9,7 +9,6 @@ require_relative 'adapter/schema_statements'
|
|
9
9
|
module Torque
|
10
10
|
module PostgreSQL
|
11
11
|
module Adapter
|
12
|
-
|
13
12
|
include Quoting
|
14
13
|
include ColumnDumper unless Torque::PostgreSQL::AR521
|
15
14
|
include DatabaseStatements
|
@@ -18,10 +17,9 @@ module Torque
|
|
18
17
|
# Get the current PostgreSQL version as a Gem Version.
|
19
18
|
def version
|
20
19
|
@version ||= Gem::Version.new(
|
21
|
-
select_value('SELECT version()')
|
22
|
-
|
20
|
+
select_value('SELECT version()').match(/#{Adapter::ADAPTER_NAME} ([\d\.]+)/)[1]
|
21
|
+
)
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
24
|
|
27
25
|
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend Adapter
|
@@ -3,7 +3,7 @@ module Torque
|
|
3
3
|
module Adapter
|
4
4
|
module DatabaseStatements
|
5
5
|
|
6
|
-
EXTENDED_DATABASE_TYPES = %i(enum interval)
|
6
|
+
EXTENDED_DATABASE_TYPES = %i(enum enum_set interval)
|
7
7
|
|
8
8
|
# Switch between dump mode or not
|
9
9
|
def dump_mode!
|
@@ -35,7 +35,11 @@ module Torque
|
|
35
35
|
# Change some of the types being mapped
|
36
36
|
def initialize_type_map(m = type_map)
|
37
37
|
super
|
38
|
+
m.register_type 'box', OID::Box.new
|
39
|
+
m.register_type 'circle', OID::Circle.new
|
38
40
|
m.register_type 'interval', OID::Interval.new
|
41
|
+
m.register_type 'line', OID::Line.new
|
42
|
+
m.register_type 'segment', OID::Segment.new
|
39
43
|
end
|
40
44
|
|
41
45
|
# :nodoc:
|
@@ -57,7 +61,8 @@ module Torque
|
|
57
61
|
|
58
62
|
query = <<-SQL
|
59
63
|
SELECT a.typelem AS oid, t.typname, t.typelem,
|
60
|
-
t.typdelim, t.typbasetype, t.typtype
|
64
|
+
t.typdelim, t.typbasetype, t.typtype,
|
65
|
+
t.typarray
|
61
66
|
FROM pg_type t
|
62
67
|
INNER JOIN pg_type a ON (a.oid = t.typarray)
|
63
68
|
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
@@ -76,14 +81,9 @@ module Torque
|
|
76
81
|
|
77
82
|
execute_and_clear(query, 'SCHEMA', []) do |records|
|
78
83
|
records.each do |row|
|
79
|
-
|
80
|
-
|
81
|
-
case
|
82
|
-
when typtype == 'e' then OID::Enum.create(row)
|
83
|
-
end
|
84
|
+
case row['typtype']
|
85
|
+
when 'e' then OID::Enum.create(row, type_map)
|
84
86
|
end
|
85
|
-
|
86
|
-
type_map.register_type row['oid'].to_i, type
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
@@ -156,6 +156,20 @@ module Torque
|
|
156
156
|
SQL
|
157
157
|
end
|
158
158
|
|
159
|
+
# Extracts the value from a PostgreSQL column default definition.
|
160
|
+
def extract_value_from_default(default)
|
161
|
+
case default
|
162
|
+
# Array elements
|
163
|
+
when /\AARRAY\[(.*)\]\z/
|
164
|
+
# TODO: Improve this since it's not the most safe approach
|
165
|
+
eval(default.gsub(/ARRAY|::\w+(\[\])?/, ''))
|
166
|
+
else
|
167
|
+
super
|
168
|
+
end
|
169
|
+
rescue SyntaxError
|
170
|
+
# If somethin goes wrong with the eval, just return nil
|
171
|
+
end
|
172
|
+
|
159
173
|
end
|
160
174
|
end
|
161
175
|
end
|
@@ -1,5 +1,11 @@
|
|
1
|
+
require_relative 'oid/box'
|
2
|
+
require_relative 'oid/circle'
|
1
3
|
require_relative 'oid/enum'
|
4
|
+
require_relative 'oid/enum_set'
|
2
5
|
require_relative 'oid/interval'
|
6
|
+
require_relative 'oid/line'
|
7
|
+
require_relative 'oid/range'
|
8
|
+
require_relative 'oid/segment'
|
3
9
|
|
4
10
|
module Torque
|
5
11
|
module PostgreSQL
|
@@ -7,8 +13,13 @@ module Torque
|
|
7
13
|
module OID
|
8
14
|
end
|
9
15
|
|
10
|
-
ActiveRecord::Type.register(:
|
16
|
+
ActiveRecord::Type.register(:box, OID::Box, adapter: :postgresql)
|
17
|
+
ActiveRecord::Type.register(:circle, OID::Circle, adapter: :postgresql)
|
18
|
+
ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
|
19
|
+
ActiveRecord::Type.register(:enum_set, OID::EnumSet, adapter: :postgresql)
|
11
20
|
ActiveRecord::Type.register(:interval, OID::Interval, adapter: :postgresql)
|
21
|
+
ActiveRecord::Type.register(:line, OID::Line, adapter: :postgresql)
|
22
|
+
ActiveRecord::Type.register(:segment, OID::Segment, adapter: :postgresql)
|
12
23
|
end
|
13
24
|
end
|
14
25
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Torque
|
2
|
+
module PostgreSQL
|
3
|
+
class Box < Struct.new(:x1, :y1, :x2, :y2)
|
4
|
+
def points
|
5
|
+
klass = Torque::PostgreSQL.config.geometry.point_class
|
6
|
+
[
|
7
|
+
klass.new(x1, y1),
|
8
|
+
klass.new(x1, y2),
|
9
|
+
klass.new(x2, y1),
|
10
|
+
klass.new(x2, y2),
|
11
|
+
]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
config.geometry.box_class ||= ::ActiveRecord.const_set('Box', Class.new(Box))
|
16
|
+
|
17
|
+
module Adapter
|
18
|
+
module OID
|
19
|
+
class Box < Torque::PostgreSQL::GeometryBuilder
|
20
|
+
|
21
|
+
PIECES = %i[x1 y1 x2 y2].freeze
|
22
|
+
FORMATION = '((%s,%s),(%s,%s))'.freeze
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Torque
|
2
|
+
module PostgreSQL
|
3
|
+
class Circle < Struct.new(:x, :y, :r)
|
4
|
+
alias radius r
|
5
|
+
alias radius= r=
|
6
|
+
|
7
|
+
def center
|
8
|
+
point_class.new(x, y)
|
9
|
+
end
|
10
|
+
|
11
|
+
def center=(value)
|
12
|
+
parts = value.is_a?(point_class) ? [value.x, value.y] : value[0..1]
|
13
|
+
self.x = parts.first
|
14
|
+
self.y = parts.last
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def point_class
|
20
|
+
Torque::PostgreSQL.config.geometry.point_class
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
config.geometry.circle_class ||= ::ActiveRecord.const_set('Circle', Class.new(Circle))
|
25
|
+
|
26
|
+
module Adapter
|
27
|
+
module OID
|
28
|
+
class Circle < Torque::PostgreSQL::GeometryBuilder
|
29
|
+
|
30
|
+
PIECES = %i[x y r].freeze
|
31
|
+
FORMATION = '<(%s,%s),%s>'.freeze
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -6,12 +6,16 @@ module Torque
|
|
6
6
|
|
7
7
|
attr_reader :name, :klass
|
8
8
|
|
9
|
-
def self.create(row)
|
10
|
-
|
11
|
-
|
9
|
+
def self.create(row, type_map)
|
10
|
+
name = row['typname']
|
11
|
+
oid = row['oid'].to_i
|
12
|
+
arr_oid = row['typarray'].to_i
|
13
|
+
|
14
|
+
oid_klass = Enum.new(name)
|
15
|
+
oid_set_klass = EnumSet.new(name, oid_klass.klass)
|
12
16
|
|
13
|
-
|
14
|
-
|
17
|
+
type_map.register_type(oid, oid_klass)
|
18
|
+
type_map.register_type(arr_oid, oid_set_klass)
|
15
19
|
end
|
16
20
|
|
17
21
|
def initialize(name)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Torque
|
2
|
+
module PostgreSQL
|
3
|
+
module Adapter
|
4
|
+
module OID
|
5
|
+
class EnumSet < Enum
|
6
|
+
|
7
|
+
attr_reader :enum_klass
|
8
|
+
|
9
|
+
def initialize(name, enum_klass)
|
10
|
+
@name = name + '[]'
|
11
|
+
@klass = Attributes::EnumSet.lookup(name, enum_klass)
|
12
|
+
@enum_klass = enum_klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def type
|
16
|
+
:enum_set
|
17
|
+
end
|
18
|
+
|
19
|
+
def serialize(value)
|
20
|
+
return if value.blank?
|
21
|
+
value = cast_value(value)
|
22
|
+
value.map(&:to_s) unless value.blank?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Always use symbol values for schema dumper
|
26
|
+
def type_cast_for_schema(value)
|
27
|
+
cast_value(value).map(&:to_sym).inspect
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def cast_value(value)
|
33
|
+
return if value.blank?
|
34
|
+
return value if value.is_a?(@klass)
|
35
|
+
@klass.new(value)
|
36
|
+
rescue Attributes::EnumSet::EnumError
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Torque
|
2
|
+
module PostgreSQL
|
3
|
+
class Line < Struct.new(:slope, :intercept)
|
4
|
+
alias c intercept
|
5
|
+
alias c= intercept=
|
6
|
+
|
7
|
+
def a=(value)
|
8
|
+
self.slope = vertical? \
|
9
|
+
? Float::INFINITY \
|
10
|
+
: Rational(value, b)
|
11
|
+
end
|
12
|
+
|
13
|
+
def a
|
14
|
+
slope.numerator
|
15
|
+
end
|
16
|
+
|
17
|
+
def b=(value)
|
18
|
+
self.slope = value.zero? \
|
19
|
+
? Float::INFINITY \
|
20
|
+
: Rational(a, value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def b
|
24
|
+
vertical? ? 0 : slope.denominator
|
25
|
+
end
|
26
|
+
|
27
|
+
def horizontal?
|
28
|
+
slope.zero?
|
29
|
+
end
|
30
|
+
|
31
|
+
def vertical?
|
32
|
+
!slope.try(:infinite?).eql?(nil)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
config.geometry.line_class ||= ::ActiveRecord.const_set('Line', Class.new(Line))
|
37
|
+
|
38
|
+
module Adapter
|
39
|
+
module OID
|
40
|
+
class Line < Torque::PostgreSQL::GeometryBuilder
|
41
|
+
|
42
|
+
PIECES = %i[a b c].freeze
|
43
|
+
FORMATION = '{%s,%s,%s}'.freeze
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def build_klass(*args)
|
48
|
+
return nil if args.empty?
|
49
|
+
check_invalid_format!(args)
|
50
|
+
|
51
|
+
a, b, c = args.try(:first, pieces.size)&.map(&:to_f)
|
52
|
+
slope = b.zero? ? Float::INFINITY : Rational(a, b)
|
53
|
+
config_class.new(slope, c)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|