aerospike 2.9.0 → 2.13.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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -4
  3. data/README.md +1 -1
  4. data/lib/aerospike.rb +12 -4
  5. data/lib/aerospike/aerospike_exception.rb +7 -1
  6. data/lib/aerospike/atomic/atomic.rb +1 -1
  7. data/lib/aerospike/bin.rb +1 -1
  8. data/lib/aerospike/cdt/list_operation.rb +1 -1
  9. data/lib/aerospike/cdt/map_operation.rb +1 -1
  10. data/lib/aerospike/cdt/map_order.rb +1 -1
  11. data/lib/aerospike/cdt/map_policy.rb +1 -1
  12. data/lib/aerospike/cdt/map_return_type.rb +1 -1
  13. data/lib/aerospike/cdt/map_write_mode.rb +1 -1
  14. data/lib/aerospike/client.rb +10 -11
  15. data/lib/aerospike/cluster.rb +92 -17
  16. data/lib/aerospike/cluster/partition.rb +1 -1
  17. data/lib/aerospike/cluster/partition_parser.rb +169 -0
  18. data/lib/aerospike/command/admin_command.rb +2 -3
  19. data/lib/aerospike/command/batch_direct_command.rb +1 -1
  20. data/lib/aerospike/command/batch_direct_exists_command.rb +1 -1
  21. data/lib/aerospike/command/batch_direct_node.rb +3 -3
  22. data/lib/aerospike/command/batch_index_command.rb +10 -2
  23. data/lib/aerospike/command/batch_index_node.rb +2 -2
  24. data/lib/aerospike/command/batch_item.rb +1 -1
  25. data/lib/aerospike/command/command.rb +102 -11
  26. data/lib/aerospike/command/delete_command.rb +21 -5
  27. data/lib/aerospike/command/execute_command.rb +1 -1
  28. data/lib/aerospike/command/exists_command.rb +21 -5
  29. data/lib/aerospike/command/field_type.rb +3 -1
  30. data/lib/aerospike/command/multi_command.rb +11 -4
  31. data/lib/aerospike/command/operate_command.rb +6 -1
  32. data/lib/aerospike/command/read_command.rb +29 -18
  33. data/lib/aerospike/command/read_header_command.rb +18 -6
  34. data/lib/aerospike/command/roles.rb +1 -1
  35. data/lib/aerospike/command/single_command.rb +9 -3
  36. data/lib/aerospike/command/touch_command.rb +14 -3
  37. data/lib/aerospike/command/unsupported_particle_type_validator.rb +1 -1
  38. data/lib/aerospike/command/write_command.rb +13 -4
  39. data/lib/aerospike/connection/create.rb +1 -1
  40. data/lib/aerospike/features.rb +1 -1
  41. data/lib/aerospike/geo_json.rb +70 -1
  42. data/lib/aerospike/host.rb +1 -1
  43. data/lib/aerospike/info.rb +1 -1
  44. data/lib/aerospike/key.rb +1 -1
  45. data/lib/aerospike/language.rb +1 -1
  46. data/lib/aerospike/node.rb +3 -6
  47. data/lib/aerospike/node/refresh/partitions.rb +6 -15
  48. data/lib/aerospike/node_validator.rb +45 -40
  49. data/lib/aerospike/operation.rb +6 -1
  50. data/lib/aerospike/policy/admin_policy.rb +1 -1
  51. data/lib/aerospike/policy/batch_policy.rb +1 -1
  52. data/lib/aerospike/policy/client_policy.rb +1 -1
  53. data/lib/aerospike/policy/commit_level.rb +1 -1
  54. data/lib/aerospike/policy/consistency_level.rb +1 -1
  55. data/lib/aerospike/policy/generation_policy.rb +1 -1
  56. data/lib/aerospike/policy/operate_policy.rb +1 -1
  57. data/lib/aerospike/policy/policy.rb +57 -3
  58. data/lib/aerospike/policy/priority.rb +1 -1
  59. data/lib/aerospike/policy/query_policy.rb +8 -1
  60. data/lib/aerospike/policy/record_bin_multiplicity.rb +1 -1
  61. data/lib/aerospike/policy/record_exists_action.rb +1 -1
  62. data/lib/aerospike/policy/replica.rb +38 -0
  63. data/lib/aerospike/policy/scan_policy.rb +8 -1
  64. data/lib/aerospike/policy/write_policy.rb +1 -1
  65. data/lib/aerospike/query/filter.rb +1 -1
  66. data/lib/aerospike/query/pred_exp.rb +192 -0
  67. data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
  68. data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
  69. data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
  70. data/lib/aerospike/query/pred_exp/op.rb +27 -0
  71. data/lib/aerospike/query/pred_exp/regex.rb +32 -0
  72. data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
  73. data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
  74. data/lib/aerospike/query/query_command.rb +27 -1
  75. data/lib/aerospike/query/recordset.rb +5 -5
  76. data/lib/aerospike/query/scan_command.rb +1 -1
  77. data/lib/aerospike/query/statement.rb +12 -3
  78. data/lib/aerospike/query/stream_command.rb +9 -10
  79. data/lib/aerospike/record.rb +1 -1
  80. data/lib/aerospike/result_code.rb +13 -20
  81. data/lib/aerospike/socket/base.rb +1 -1
  82. data/lib/aerospike/task/execute_task.rb +1 -1
  83. data/lib/aerospike/task/index_task.rb +1 -1
  84. data/lib/aerospike/task/task.rb +1 -1
  85. data/lib/aerospike/task/udf_register_task.rb +1 -1
  86. data/lib/aerospike/task/udf_remove_task.rb +1 -1
  87. data/lib/aerospike/ttl.rb +1 -1
  88. data/lib/aerospike/udf.rb +1 -1
  89. data/lib/aerospike/user_role.rb +1 -1
  90. data/lib/aerospike/utils/buffer.rb +1 -1
  91. data/lib/aerospike/utils/packer.rb +1 -1
  92. data/lib/aerospike/utils/pool.rb +1 -1
  93. data/lib/aerospike/utils/unpacker.rb +7 -2
  94. data/lib/aerospike/value/particle_type.rb +1 -1
  95. data/lib/aerospike/value/value.rb +59 -29
  96. data/lib/aerospike/version.rb +1 -1
  97. metadata +15 -8
  98. data/lib/aerospike/cluster/partition_tokenizer_new.rb +0 -130
  99. data/lib/aerospike/cluster/partition_tokenizer_old.rb +0 -135
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.master_node(@partition)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_delete(@policy, @key)
38
42
  end
@@ -43,13 +47,25 @@ module Aerospike
43
47
 
44
48
  result_code = @data_buffer.read(13).ord & 0xFF
45
49
 
46
- if (result_code != 0) && (result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
47
- raise Aerospike::Exceptions::Aerospike.new(result_code)
50
+ if result_code == 0
51
+ @existed = true
52
+ return
48
53
  end
49
54
 
50
- @existed = (result_code == 0)
55
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
56
+ @existed = false
57
+ return
58
+ end
59
+
60
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
61
+ if @policy.fail_on_filtered_out
62
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
63
+ end
64
+ @existed = true
65
+ return
66
+ end
51
67
 
52
- empty_socket
68
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
53
69
  end
54
70
 
55
71
  end # class
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.read_node(@partition, @policy.replica, @sequence)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_exists(@policy, @key)
38
42
  end
@@ -43,13 +47,25 @@ module Aerospike
43
47
 
44
48
  result_code = @data_buffer.read(13).ord & 0xFF
45
49
 
46
- if (result_code != 0) && (result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
47
- raise Aerospike::Exceptions::Aerospike.new(result_code)
50
+ if result_code == 0
51
+ @exists = true
52
+ return
48
53
  end
49
54
 
50
- @exists = (result_code == 0)
55
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
56
+ @exists = false
57
+ return
58
+ end
59
+
60
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
61
+ if @policy.fail_on_filtered_out
62
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
63
+ end
64
+ @exists = true
65
+ return
66
+ end
51
67
 
52
- empty_socket
68
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
53
69
  end
54
70
 
55
71
  end # class
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -31,6 +31,7 @@ module Aerospike
31
31
  TRAN_ID = 7 # user supplied transaction id, which is simply passed back
32
32
  SCAN_OPTIONS = 8
33
33
  SCAN_TIMEOUT = 9
34
+ RECORDS_PER_SECOND = 10
34
35
  INDEX_NAME = 21
35
36
  INDEX_RANGE = 22
36
37
  INDEX_FILTER = 23
@@ -43,6 +44,7 @@ module Aerospike
43
44
  UDF_OP = 33
44
45
  QUERY_BINLIST = 40
45
46
  BATCH_INDEX = 41
47
+ PREDEXP = 43
46
48
 
47
49
  end # module
48
50
 
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -32,6 +32,10 @@ module Aerospike
32
32
  self
33
33
  end
34
34
 
35
+ def get_node
36
+ @node
37
+ end
38
+
35
39
  def parse_result
36
40
  # Read socket into receive buffer one record at a time. Do not read entire receive size
37
41
  # because the receive buffer would be too big.
@@ -59,10 +63,13 @@ module Aerospike
59
63
  read_bytes(MSG_REMAINING_HEADER_SIZE)
60
64
  result_code = @data_buffer.read(5).ord & 0xFF
61
65
 
62
- # The only valid server return codes are "ok" and "not found".
66
+ # The only valid server return codes are "ok", "not found" and "filtered out".
63
67
  # If other return codes are received, then abort the batch.
64
- if result_code != 0 && result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
65
- raise Aerospike::Exceptions::Aerospike.new(result_code)
68
+ if result_code != 0
69
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR || result_code == Aerospike::ResultCode::FILTERED_OUT
70
+ else
71
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
72
+ end
66
73
  end
67
74
 
68
75
  # If cmd is the end marker of the response, do not proceed further
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -28,6 +28,11 @@ module Aerospike
28
28
  @operations = operations
29
29
  end
30
30
 
31
+ def get_node
32
+ @cluster.master_node(@partition)
33
+ end
34
+
35
+
31
36
  def write_bins
32
37
  @operations.select{|op| op.op_type == Aerospike::Operation::WRITE}.map(&:bin).compact
33
38
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2017 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -39,6 +39,10 @@ module Aerospike
39
39
  self
40
40
  end
41
41
 
42
+ def get_node
43
+ @cluster.read_node(@partition, @policy.replica, @sequence)
44
+ end
45
+
42
46
  def write_buffer
43
47
  set_read(@policy, @key, @bin_names)
44
48
  end
@@ -76,29 +80,36 @@ module Aerospike
76
80
 
77
81
  end
78
82
 
79
- if result_code != 0
80
- return nil if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
81
- return nil if result_code == Aerospike::ResultCode::LARGE_ITEM_NOT_FOUND
82
- if result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE
83
- begin
84
- @record = parse_record(op_count, field_count, generation, expiration)
85
- handle_udf_error(result_code)
86
- rescue => e
87
- Aerospike.logger.error("UDF execution error: #{e}")
88
- raise e
89
- end
90
-
83
+ if result_code == 0
84
+ if op_count == 0
85
+ @record = Record.new(@node, @key, nil, generation, expiration)
86
+ return
91
87
  end
92
-
93
- raise Aerospike::Exceptions::Aerospike.new(result_code)
88
+
89
+ @record = parse_record(op_count, field_count, generation, expiration)
90
+ return
94
91
  end
95
92
 
96
- if op_count == 0
97
- @record = Record.new(@node, @key, nil, generation, expiration)
93
+ return nil if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
94
+
95
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
96
+ if @policy.fail_on_filtered_out
97
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
98
+ end
98
99
  return
99
100
  end
100
101
 
101
- @record = parse_record(op_count, field_count, generation, expiration)
102
+ if result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE
103
+ begin
104
+ @record = parse_record(op_count, field_count, generation, expiration)
105
+ handle_udf_error(result_code)
106
+ rescue => e
107
+ Aerospike.logger.error("UDF execution error: #{e}")
108
+ raise e
109
+ end
110
+ end
111
+
112
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
102
113
  end
103
114
 
104
115
  def handle_udf_error(result_code)
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.read_node(@partition, @policy.replica, @sequence)
38
+ end
39
+
36
40
  def write_buffer
37
41
  set_read_header(@policy, @key)
38
42
  end
@@ -47,15 +51,23 @@ module Aerospike
47
51
  generation = @data_buffer.read_int32(14)
48
52
  expiration = @data_buffer.read_int32(18)
49
53
  @record = Record.new(@node, @key, nil, generation, expiration)
50
- else
51
- if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
52
- @record = nil
53
- else
54
+ return
55
+ end
56
+
57
+ if result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
58
+ @record = nil
59
+ return
60
+ end
61
+
62
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
63
+ @record = nil
64
+ if @policy.fail_on_filtered_out
54
65
  raise Aerospike::Exceptions::Aerospike.new(result_code)
55
66
  end
67
+ return
56
68
  end
57
69
 
58
- empty_socket
70
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
59
71
  end
60
72
 
61
73
  end # class
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -1,4 +1,4 @@
1
- # Copyright 2014-2018 Aerospike, Inc.
1
+ # Copyright 2014-2020 Aerospike, Inc.
2
2
  #
3
3
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
4
4
  # license agreements.
@@ -27,12 +27,18 @@ module Aerospike
27
27
  @cluster = cluster
28
28
  @key = key
29
29
 
30
- node = cluster.get_node_for_key(key)
31
- super(node)
30
+ @partition = Partition.new_by_key(key)
31
+
32
+ super()
32
33
  end
33
34
 
34
35
  protected
35
36
 
37
+ def get_node
38
+ # abstract method
39
+ raise Aerospike::Exceptions::InvalidNode
40
+ end
41
+
36
42
  def empty_socket
37
43
  # There should not be any more bytes.
38
44
  # Empty the socket to be safe.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -30,6 +30,10 @@ module Aerospike
30
30
  self
31
31
  end
32
32
 
33
+ def get_node
34
+ @cluster.master_node(@partition)
35
+ end
36
+
33
37
  def write_buffer
34
38
  set_touch(@policy, @key)
35
39
  end
@@ -40,9 +44,16 @@ module Aerospike
40
44
 
41
45
  result_code = @data_buffer.read(13).ord & 0xFF
42
46
 
43
- raise Aerospike::Exceptions::Aerospike.new(result_code) if result_code != 0
47
+ return if result_code == 0
48
+
49
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
50
+ if @policy.fail_on_filtered_out
51
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
52
+ end
53
+ return
54
+ end
44
55
 
45
- empty_socket
56
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
46
57
  end
47
58
 
48
59
  end # class
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2015-2017 Aerospike, Inc.
2
+ # Copyright 2015-2020 Aerospike, Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License")
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2014-2017 Aerospike, Inc.
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -33,6 +33,10 @@ module Aerospike
33
33
  self
34
34
  end
35
35
 
36
+ def get_node
37
+ @cluster.master_node(@partition)
38
+ end
39
+
36
40
  def write_bins
37
41
  @bins
38
42
  end
@@ -52,11 +56,16 @@ module Aerospike
52
56
 
53
57
  result_code = @data_buffer.read(13).ord & 0xFF
54
58
 
55
- if result_code != 0
56
- raise Aerospike::Exceptions::Aerospike.new(result_code)
59
+ return if result_code == 0
60
+
61
+ if result_code == Aerospike::ResultCode::FILTERED_OUT
62
+ if @policy.fail_on_filtered_out
63
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
64
+ end
65
+ return
57
66
  end
58
67
 
59
- empty_socket
68
+ raise Aerospike::Exceptions::Aerospike.new(result_code)
60
69
  end
61
70
 
62
71
  end # class
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2018 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2014-2017 Aerospike, Inc.
3
+ # Copyright 2014-2020 Aerospike, Inc.
4
4
  #
5
5
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
6
  # license agreements.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2015-2017 Aerospike, Inc.
2
+ # Copyright 2015-2020 Aerospike, Inc.
3
3
  #
4
4
  # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
5
  # license agreements.
@@ -52,6 +52,75 @@ module Aerospike
52
52
  other.to_json == self.to_json
53
53
  end
54
54
 
55
+ def lng
56
+ case type
57
+ when 'Point'
58
+ coordinates.first
59
+ when 'AeroCircle'
60
+ coordinates.first.first
61
+ end
62
+ end
63
+
64
+ def lat
65
+ case type
66
+ when 'Point'
67
+ coordinates.last
68
+ when 'AeroCircle'
69
+ coordinates.first.last
70
+ end
71
+ end
72
+
73
+ def radius
74
+ return nil unless circle?
75
+
76
+ coordinates.last
77
+ end
78
+
79
+ def coordinates
80
+ to_h['coordinates']
81
+ end
82
+
83
+ def type
84
+ to_h['type']
85
+ end
86
+
87
+ def point?
88
+ type == 'Point'
89
+ end
90
+
91
+ def circle?
92
+ type == 'AeroCircle'
93
+ end
94
+
95
+ def polygon?
96
+ type == 'Polygon'
97
+ end
98
+
99
+ def self.point(lng, lat)
100
+ new(type: 'Point', coordinates: [lng, lat])
101
+ end
102
+
103
+ def self.circle(lng, lat, radius)
104
+ new(type: 'AeroCircle', coordinates: [[lng, lat], radius])
105
+ end
106
+
107
+ def self.polygon(coordinates)
108
+ new(type: 'Polygon', coordinates: coordinates)
109
+ end
110
+
111
+ def to_circle(radius)
112
+ raise TypeError, 'Cannot create a Circle from a Polygon' if polygon?
113
+
114
+ self.class.circle(lng, lat, radius)
115
+ end
116
+
117
+ def to_point
118
+ return self if point?
119
+ raise TypeError, 'Cannot create a Point from a Polygon' if polygon?
120
+
121
+ self.class.point(lng, lat)
122
+ end
123
+
55
124
  protected
56
125
 
57
126
  attr_accessor :json_data