torque-postgresql 0.2.16 → 1.0.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/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
|