cassandra-driver 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +13 -5
  2. data/README.md +18 -9
  3. data/ext/cassandra_murmur3/cassandra_murmur3.c +1 -1
  4. data/lib/cassandra.rb +5 -1
  5. data/lib/cassandra/address_resolution.rb +1 -1
  6. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
  7. data/lib/cassandra/address_resolution/policies/none.rb +1 -1
  8. data/lib/cassandra/auth.rb +1 -1
  9. data/lib/cassandra/auth/providers.rb +1 -1
  10. data/lib/cassandra/auth/providers/password.rb +1 -1
  11. data/lib/cassandra/cluster.rb +1 -1
  12. data/lib/cassandra/cluster/client.rb +33 -13
  13. data/lib/cassandra/cluster/connection_pool.rb +1 -1
  14. data/lib/cassandra/cluster/connector.rb +1 -36
  15. data/lib/cassandra/cluster/control_connection.rb +85 -9
  16. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  17. data/lib/cassandra/cluster/metadata.rb +1 -1
  18. data/lib/cassandra/cluster/options.rb +15 -4
  19. data/lib/cassandra/cluster/registry.rb +1 -1
  20. data/lib/cassandra/cluster/schema.rb +76 -16
  21. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  22. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +1 -1
  23. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
  24. data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
  25. data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
  26. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +1 -1
  27. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
  28. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
  29. data/lib/cassandra/cluster/schema/type_parser.rb +35 -8
  30. data/lib/cassandra/column.rb +10 -14
  31. data/lib/cassandra/compression.rb +1 -1
  32. data/lib/cassandra/compression/compressors/lz4.rb +1 -1
  33. data/lib/cassandra/compression/compressors/snappy.rb +1 -1
  34. data/lib/cassandra/driver.rb +2 -2
  35. data/lib/cassandra/errors.rb +1 -1
  36. data/lib/cassandra/execution/info.rb +1 -1
  37. data/lib/cassandra/execution/options.rb +3 -2
  38. data/lib/cassandra/execution/trace.rb +1 -1
  39. data/lib/cassandra/executors.rb +1 -1
  40. data/lib/cassandra/future.rb +1 -1
  41. data/lib/cassandra/host.rb +1 -1
  42. data/lib/cassandra/keyspace.rb +55 -5
  43. data/lib/cassandra/listener.rb +1 -1
  44. data/lib/cassandra/load_balancing.rb +1 -1
  45. data/lib/cassandra/load_balancing/policies.rb +1 -1
  46. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +1 -1
  47. data/lib/cassandra/load_balancing/policies/round_robin.rb +1 -1
  48. data/lib/cassandra/load_balancing/policies/token_aware.rb +1 -1
  49. data/lib/cassandra/load_balancing/policies/white_list.rb +1 -1
  50. data/lib/cassandra/null_logger.rb +1 -1
  51. data/lib/cassandra/protocol.rb +6 -1
  52. data/lib/cassandra/protocol/coder.rb +319 -84
  53. data/lib/cassandra/protocol/cql_byte_buffer.rb +1 -1
  54. data/lib/cassandra/protocol/cql_protocol_handler.rb +24 -10
  55. data/lib/cassandra/protocol/request.rb +1 -1
  56. data/lib/cassandra/protocol/requests/auth_response_request.rb +1 -1
  57. data/lib/cassandra/protocol/requests/batch_request.rb +1 -1
  58. data/lib/cassandra/protocol/requests/credentials_request.rb +1 -1
  59. data/lib/cassandra/protocol/requests/execute_request.rb +1 -1
  60. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  61. data/lib/cassandra/protocol/requests/prepare_request.rb +1 -1
  62. data/lib/cassandra/protocol/requests/query_request.rb +5 -3
  63. data/lib/cassandra/protocol/requests/register_request.rb +1 -1
  64. data/lib/cassandra/protocol/requests/startup_request.rb +1 -1
  65. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  66. data/lib/cassandra/protocol/response.rb +1 -1
  67. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +1 -1
  68. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +1 -1
  69. data/lib/cassandra/protocol/responses/auth_success_response.rb +1 -1
  70. data/lib/cassandra/protocol/responses/authenticate_response.rb +1 -1
  71. data/lib/cassandra/protocol/responses/error_response.rb +1 -1
  72. data/lib/cassandra/protocol/responses/event_response.rb +1 -1
  73. data/lib/cassandra/protocol/responses/prepared_result_response.rb +1 -1
  74. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +9 -2
  75. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +1 -1
  76. data/lib/cassandra/protocol/responses/ready_response.rb +1 -1
  77. data/lib/cassandra/protocol/responses/result_response.rb +1 -1
  78. data/lib/cassandra/protocol/responses/rows_result_response.rb +1 -1
  79. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +21 -6
  80. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +18 -8
  81. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +1 -1
  82. data/lib/cassandra/protocol/responses/status_change_event_response.rb +1 -1
  83. data/lib/cassandra/protocol/responses/supported_response.rb +1 -1
  84. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +1 -1
  85. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +1 -1
  86. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +1 -1
  87. data/lib/cassandra/protocol/responses/void_result_response.rb +1 -1
  88. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +1 -1
  89. data/lib/cassandra/protocol/v1.rb +4 -2
  90. data/lib/cassandra/protocol/v3.rb +280 -0
  91. data/lib/cassandra/reconnection.rb +1 -1
  92. data/lib/cassandra/reconnection/policies.rb +1 -1
  93. data/lib/cassandra/reconnection/policies/constant.rb +1 -1
  94. data/lib/cassandra/reconnection/policies/exponential.rb +1 -1
  95. data/lib/cassandra/result.rb +1 -1
  96. data/lib/cassandra/retry.rb +1 -1
  97. data/lib/cassandra/retry/policies.rb +1 -1
  98. data/lib/cassandra/retry/policies/default.rb +1 -1
  99. data/lib/cassandra/retry/policies/downgrading_consistency.rb +1 -1
  100. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  101. data/lib/cassandra/session.rb +14 -80
  102. data/lib/cassandra/statement.rb +1 -1
  103. data/lib/cassandra/statements.rb +1 -1
  104. data/lib/cassandra/statements/batch.rb +10 -25
  105. data/lib/cassandra/statements/bound.rb +1 -1
  106. data/lib/cassandra/statements/prepared.rb +24 -31
  107. data/lib/cassandra/statements/simple.rb +22 -66
  108. data/lib/cassandra/statements/void.rb +1 -1
  109. data/lib/cassandra/table.rb +36 -5
  110. data/lib/cassandra/time_uuid.rb +1 -1
  111. data/lib/cassandra/tuple.rb +124 -0
  112. data/lib/cassandra/types.rb +1406 -0
  113. data/lib/cassandra/udt.rb +420 -0
  114. data/lib/cassandra/util.rb +42 -64
  115. data/lib/cassandra/uuid.rb +1 -1
  116. data/lib/cassandra/uuid/generator.rb +1 -1
  117. data/lib/cassandra/version.rb +2 -2
  118. metadata +19 -15
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@ module Cassandra
139
139
  attr_reader :options
140
140
 
141
141
  # @private
142
- def initialize(keyspace, name, partition_key, clustering_columns, columns, options, clustering_order)
142
+ def initialize(keyspace, name, partition_key, clustering_columns, columns, options, clustering_order, release_version)
143
143
  @keyspace = keyspace
144
144
  @name = name
145
145
  @partition_key = partition_key
@@ -147,6 +147,7 @@ module Cassandra
147
147
  @columns = columns
148
148
  @options = options
149
149
  @clustering_order = clustering_order
150
+ @release_version = release_version
150
151
  end
151
152
 
152
153
  # @param name [String] column name
@@ -187,7 +188,7 @@ module Cassandra
187
188
  else
188
189
  cql << ",\n" unless first
189
190
  end
190
- cql << " #{column.to_cql}"
191
+ cql << " #{column.name} #{type_to_cql(column.type, column.frozen?)}"
191
192
  end
192
193
  cql << ",\n PRIMARY KEY ("
193
194
  if @partition_key.one?
@@ -261,7 +262,12 @@ module Cassandra
261
262
 
262
263
  buffer = Protocol::CqlByteBuffer.new
263
264
 
264
- Protocol::Coder.write_value_v1(buffer, values[column_name], column.type)
265
+ if @release_version > '2.1'
266
+ Protocol::Coder.write_value_v3(buffer, values[column_name], column.type)
267
+ else
268
+ Protocol::Coder.write_value_v1(buffer, values[column_name], column.type)
269
+ end
270
+
265
271
  buffer.discard(4)
266
272
  else
267
273
  buf = nil
@@ -274,7 +280,12 @@ module Cassandra
274
280
  buf ||= Protocol::CqlByteBuffer.new
275
281
  buffer ||= Protocol::CqlByteBuffer.new
276
282
 
277
- Protocol::Coder.write_value_v1(buf, values[column_name], column.type)
283
+ if @protocol_version > 2
284
+ Protocol::Coder.write_value_v3(buf, values[column_name], column.type)
285
+ else
286
+ Protocol::Coder.write_value_v1(buf, values[column_name], column.type)
287
+ end
288
+
278
289
  buf.discard(4) # discard size
279
290
 
280
291
  size = buf.length
@@ -288,6 +299,26 @@ module Cassandra
288
299
 
289
300
  private
290
301
 
302
+ # @private
303
+ def type_to_cql(type, is_frozen)
304
+ case type.kind
305
+ when :tuple
306
+ "frozen <#{type}>"
307
+ when :udt
308
+ if @keyspace == type.keyspace
309
+ "frozen <#{Util.escape_name(type.name)}>"
310
+ else
311
+ "frozen <#{Util.escape_name(type.keyspace)}.#{Util.escape_name(type.name)}>"
312
+ end
313
+ else
314
+ if is_frozen
315
+ "frozen <#{type}>"
316
+ else
317
+ "#{type}"
318
+ end
319
+ end
320
+ end
321
+
291
322
  NULL_BYTE = "\x00".freeze
292
323
 
293
324
  attr_reader :partition_key, :clustering_columns, :clustering_order
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,124 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2015 DataStax, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module Cassandra
20
+ class Tuple
21
+ # @private
22
+ class Strict < Tuple
23
+ attr_reader :types
24
+
25
+ def initialize(types, values)
26
+ @types = types
27
+ @values = values
28
+ end
29
+
30
+ def each(&block)
31
+ @types.size.times do |i|
32
+ yield(@values[i])
33
+ end
34
+ self
35
+ end
36
+
37
+ def [](i)
38
+ @values[Integer(i)]
39
+ end
40
+
41
+ def fetch(i)
42
+ i = Integer(i)
43
+ raise ::IndexError, "index #{i} is outside of tuple, size: #{@types.size}" if i < 0 || i >= @types.size
44
+ @values[i]
45
+ end
46
+
47
+ def []=(i, value)
48
+ raise ::IndexError, "index #{i} is outside of tuple, size: #{@types.size}" if i < 0 || i >= @types.size
49
+ Util.assert_type(@types[i], value)
50
+ @values[i] = value
51
+ end
52
+
53
+ def size
54
+ @types.size
55
+ end
56
+
57
+ def inspect
58
+ "#<Cassandra::Tuple:0x#{self.object_id.to_s(16)} #{to_s}>"
59
+ end
60
+ end
61
+
62
+ include Enumerable
63
+
64
+ # Constructs a tuple with given values
65
+ def initialize(*values)
66
+ @values = values
67
+ end
68
+
69
+ # Iterates over all values of the tuple
70
+ # @yieldparam value [Object] current value
71
+ def each(&block)
72
+ @values.each(&block)
73
+ self
74
+ end
75
+
76
+ # @param i [Integer] numeric index of the value inside the tuple, must
77
+ # be `0 < i < tuple.size`
78
+ # @return [Object] value of the tuple at position `i`
79
+ def [](i)
80
+ @values[Integer(i)]
81
+ end
82
+
83
+ # @param i [Integer] numeric index of the value inside the tuple, must
84
+ # be `0 < i < tuple.size`
85
+ # @raise [IndexError] when index is outside of tuple bounds
86
+ # @return [Object] value of the tuple at position `i`
87
+ def fetch(i)
88
+ i = Integer(i)
89
+ raise ::IndexError, "index #{i} is outside of tuple, size: #{@values.size}" if i < 0 || i >= @values.size
90
+ @values[i]
91
+ end
92
+
93
+ # @param i [Integer] numeric index of the value inside the tuple, must
94
+ # be `0 < i < tuple.size`
95
+ # @param value [Object] a value to assign at position `i`
96
+ # @raise [IndexError] when index is outside of tuple bounds
97
+ # @return [Object] value of the tuple at position `i`
98
+ def []=(i, value)
99
+ i = Integer(i)
100
+ raise ::IndexError, "index #{i} is outside of tuple, size: #{@values.size}" if i < 0 || i >= @values.size
101
+ @values[i] = value
102
+ end
103
+
104
+ # Returns tuple size
105
+ # @return [Integer] tuple size
106
+ def size
107
+ @values.size
108
+ end
109
+
110
+ # String representation of the tuple
111
+ def to_s
112
+ "(#{@values.map(&:to_s).join(', ')})"
113
+ end
114
+
115
+ def inspect
116
+ "#<Cassandra::Tuple:0x#{self.object_id.to_s(16)} #{to_s}>"
117
+ end
118
+
119
+ def eql?(other)
120
+ other == @values
121
+ end
122
+ alias :== :eql?
123
+ end
124
+ end
@@ -0,0 +1,1406 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2015 DataStax, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module Cassandra
20
+ # Base class for all cassandra types.
21
+ # @abstract This class exists for documentation purposes only
22
+ class Type
23
+ # @return [Symbol] shorthand type name
24
+ def kind
25
+ end
26
+
27
+ # Coerces a given value to this type
28
+ #
29
+ # @param values [*Object] value to be coerced
30
+ # @return [Object] a value of this type
31
+ def new(*values)
32
+ end
33
+
34
+ # Asserts that a given value is of this type
35
+ # @param value [Object] value to be validated
36
+ # @param message [String] error message to use when assertion fails
37
+ # @yieldreturn [String] error message to use when assertion fails
38
+ # @raise [ArgumentError] if the value is invalid
39
+ # @return [void]
40
+ def assert(value, message = nil, &block)
41
+ end
42
+
43
+ # @return [String] a cassandra representation of this type
44
+ def to_s
45
+ end
46
+ end
47
+
48
+ module Types; extend self
49
+ # @private
50
+ class Simple < Type
51
+ attr_reader :kind
52
+
53
+ def initialize(kind)
54
+ @kind = kind
55
+ end
56
+
57
+ def new(value)
58
+ __send__(:"new_#{@kind}", value)
59
+ end
60
+
61
+ def assert(value, message = nil, &block)
62
+ __send__(:"assert_#{@kind}", value, message, &block)
63
+ nil
64
+ end
65
+
66
+ def to_s
67
+ @kind.to_s
68
+ end
69
+
70
+ def eql?(other)
71
+ other.is_a?(Simple) && @kind == other.kind
72
+ end
73
+ alias :== :eql?
74
+
75
+ private
76
+
77
+ def new_varchar(value)
78
+ String(value)
79
+ end
80
+
81
+ def assert_varchar(value, message, &block)
82
+ Util.assert_instance_of(::String, value, message, &block)
83
+ end
84
+
85
+ def new_text(value)
86
+ String(value)
87
+ end
88
+
89
+ def assert_text(valuee, message, &block)
90
+ Util.assert_instance_of(::String, valuee, message, &block)
91
+ end
92
+
93
+ def new_blob(value)
94
+ String(value)
95
+ end
96
+
97
+ def assert_blob(valuee, message, &block)
98
+ Util.assert_instance_of(::String, valuee, message, &block)
99
+ end
100
+
101
+ def new_ascii(value)
102
+ String(value)
103
+ end
104
+
105
+ def assert_ascii(valuee, message, &block)
106
+ Util.assert_instance_of(::String, valuee, message, &block)
107
+ end
108
+
109
+ def new_bigint(value)
110
+ Integer(value)
111
+ end
112
+
113
+ def assert_bigint(valuee, message, &block)
114
+ Util.assert_instance_of(::Integer, valuee, message, &block)
115
+ end
116
+
117
+ def new_counter(value)
118
+ Integer(value)
119
+ end
120
+
121
+ def assert_counter(valuee, message, &block)
122
+ Util.assert_instance_of(::Integer, valuee, message, &block)
123
+ end
124
+
125
+ def new_int(value)
126
+ Integer(value)
127
+ end
128
+
129
+ def assert_int(valuee, message, &block)
130
+ Util.assert_instance_of(::Integer, valuee, message, &block)
131
+ end
132
+
133
+ def new_varint(value)
134
+ Integer(value)
135
+ end
136
+
137
+ def assert_varint(valuee, message, &block)
138
+ Util.assert_instance_of(::Integer, valuee, message, &block)
139
+ end
140
+
141
+ def new_boolean(value)
142
+ !!value
143
+ end
144
+
145
+ def assert_boolean(valuee, message, &block)
146
+ Util.assert_instance_of_one_of([::TrueClass, ::FalseClass], valuee, message, &block)
147
+ end
148
+
149
+ def new_decimal(value)
150
+ ::BigDecimal.new(value)
151
+ end
152
+
153
+ def assert_decimal(valuee, message, &block)
154
+ Util.assert_instance_of(::BigDecimal, valuee, message, &block)
155
+ end
156
+
157
+ def new_double(value)
158
+ Float(value)
159
+ end
160
+
161
+ def assert_double(valuee, message, &block)
162
+ Util.assert_instance_of(::Float, valuee, message, &block)
163
+ end
164
+
165
+ def new_float(value)
166
+ Float(value)
167
+ end
168
+
169
+ def assert_float(valuee, message, &block)
170
+ Util.assert_instance_of(::Float, valuee, message, &block)
171
+ end
172
+
173
+ def new_inet(value)
174
+ ::IPAddr.new(value)
175
+ end
176
+
177
+ def assert_inet(valuee, message, &block)
178
+ Util.assert_instance_of(::IPAddr, valuee, message, &block)
179
+ end
180
+
181
+ def new_timestamp(value)
182
+ case value
183
+ when ::Time
184
+ value
185
+ else
186
+ return value.to_time if value.respond_to?(:to_time)
187
+ raise ::ArgumentError, "cannot convert #{value.inspect} to timestamp"
188
+ end
189
+ end
190
+
191
+ def assert_timestamp(valuee, message, &block)
192
+ Util.assert_instance_of(::Time, valuee, message, &block)
193
+ end
194
+
195
+ def new_uuid(valuee, message, &block)
196
+ Cassandra::Uuid.new(value)
197
+ end
198
+
199
+ def assert_uuid(valuee, message, &block)
200
+ Util.assert_instance_of(Cassandra::Uuid, valuee, message, &block)
201
+ end
202
+
203
+ def new_timeuuid(value)
204
+ Cassandra::TimeUuid.new(value)
205
+ end
206
+
207
+ def assert_timeuuid(valuee, message, &block)
208
+ Util.assert_instance_of(Cassandra::TimeUuid, valuee, message, &block)
209
+ end
210
+ end
211
+
212
+ # @!parse
213
+ # class Varchar < Type
214
+ # # @return [Symbol] `:varchar`
215
+ # # @see Cassandra::Type#kind
216
+ # def kind
217
+ # end
218
+ #
219
+ # # Coerces the value to String
220
+ # # @param value [Object] original value
221
+ # # @return [String] value
222
+ # # @see Cassandra::Type#new
223
+ # def new(value)
224
+ # end
225
+ #
226
+ # # Asserts that a given value is a String
227
+ # # @param value [Object] value to be validated
228
+ # # @param message [String] error message to use when assertion
229
+ # # fails
230
+ # # @yieldreturn [String] error message to use when assertion fails
231
+ # # @raise [ArgumentError] if the value is not a String
232
+ # # @return [void]
233
+ # # @see Cassandra::Type#assert
234
+ # def assert(value, message = nil, &block)
235
+ # end
236
+ #
237
+ # # @return [String] `"varchar"`
238
+ # # @see Cassandra::Type#to_s
239
+ # def to_s
240
+ # end
241
+ # end
242
+ const_set('Varchar', Simple.new(:varchar))
243
+
244
+ # @!parse
245
+ # class Text < Type
246
+ # # @return [Symbol] `:text`
247
+ # # @see Cassandra::Type#kind
248
+ # def kind
249
+ # end
250
+ #
251
+ # # Coerces the value to String
252
+ # # @param value [Object] original value
253
+ # # @return [String] value
254
+ # # @see Cassandra::Type#new
255
+ # def new(value)
256
+ # end
257
+ #
258
+ # # Asserts that a given value is a String
259
+ # # @param value [Object] value to be validated
260
+ # # @param message [String] error message to use when assertion
261
+ # # fails
262
+ # # @yieldreturn [String] error message to use when assertion fails
263
+ # # @raise [ArgumentError] if the value is not a String
264
+ # # @return [void]
265
+ # # @see Cassandra::Type#assert
266
+ # def assert(value, message = nil, &block)
267
+ # end
268
+ #
269
+ # # @return [String] `"text"`
270
+ # # @see Cassandra::Type#to_s
271
+ # def to_s
272
+ # end
273
+ # end
274
+ const_set('Text', Simple.new(:text))
275
+
276
+ # @!parse
277
+ # class Blob < Type
278
+ # # @return [Symbol] `:blob`
279
+ # # @see Cassandra::Type#kind
280
+ # def kind
281
+ # end
282
+ #
283
+ # # Coerces the value to String
284
+ # # @param value [Object] original value
285
+ # # @return [String] value
286
+ # # @see Cassandra::Type#new
287
+ # def new(value)
288
+ # end
289
+ #
290
+ # # Asserts that a given value is a String
291
+ # # @param value [Object] value to be validated
292
+ # # @param message [String] error message to use when assertion
293
+ # # fails
294
+ # # @yieldreturn [String] error message to use when assertion fails
295
+ # # @raise [ArgumentError] if the value is not a String
296
+ # # @return [void]
297
+ # # @see Cassandra::Type#assert
298
+ # def assert(value, message = nil, &block)
299
+ # end
300
+ #
301
+ # # @return [String] `"blob"`
302
+ # # @see Cassandra::Type#to_s
303
+ # def to_s
304
+ # end
305
+ # end
306
+ const_set('Blob', Simple.new(:blob))
307
+
308
+ # @!parse
309
+ # class Ascii < Type
310
+ # # @return [Symbol] `:ascii`
311
+ # # @see Cassandra::Type#kind
312
+ # def kind
313
+ # end
314
+ #
315
+ # # Coerces the value to String
316
+ # # @param value [Object] original value
317
+ # # @return [String] value
318
+ # # @see Cassandra::Type#new
319
+ # def new(value)
320
+ # end
321
+ #
322
+ # # Asserts that a given value is a String
323
+ # # @param value [Object] value to be validated
324
+ # # @param message [String] error message to use when assertion
325
+ # # fails
326
+ # # @yieldreturn [String] error message to use when assertion fails
327
+ # # @raise [ArgumentError] if the value is not a String
328
+ # # @return [void]
329
+ # # @see Cassandra::Type#assert
330
+ # def assert(value, message = nil, &block)
331
+ # end
332
+ #
333
+ # # @return [String] `"ascii"`
334
+ # # @see Cassandra::Type#to_s
335
+ # def to_s
336
+ # end
337
+ # end
338
+ const_set('Ascii', Simple.new(:ascii))
339
+
340
+ # @!parse
341
+ # class Bigint < Type
342
+ # # @return [Symbol] `:bigint`
343
+ # # @see Cassandra::Type#kind
344
+ # def kind
345
+ # end
346
+ #
347
+ # # Coerces the value to Integer
348
+ # # @param value [Object] original value
349
+ # # @return [Integer] value
350
+ # # @see Cassandra::Type#new
351
+ # def new(value)
352
+ # end
353
+ #
354
+ # # Asserts that a given value is an Integer
355
+ # # @param value [Object] value to be validated
356
+ # # @param message [String] error message to use when assertion
357
+ # # fails
358
+ # # @yieldreturn [String] error message to use when assertion fails
359
+ # # @raise [ArgumentError] if the value is not an Integer
360
+ # # @return [void]
361
+ # # @see Cassandra::Type#assert
362
+ # def assert(value, message = nil, &block)
363
+ # end
364
+ #
365
+ # # @return [String] `"bigint"`
366
+ # # @see Cassandra::Type#to_s
367
+ # def to_s
368
+ # end
369
+ # end
370
+ const_set('Bigint', Simple.new(:bigint))
371
+
372
+ # @!parse
373
+ # class Counter < Type
374
+ # # @return [Symbol] `:counter`
375
+ # # @see Cassandra::Type#kind
376
+ # def kind
377
+ # end
378
+ #
379
+ # # Coerces the value to Integer
380
+ # # @param value [Object] original value
381
+ # # @return [Integer] value
382
+ # # @see Cassandra::Type#new
383
+ # def new(value)
384
+ # end
385
+ #
386
+ # # Asserts that a given value is an Integer
387
+ # # @param value [Object] value to be validated
388
+ # # @param message [String] error message to use when assertion
389
+ # # fails
390
+ # # @yieldreturn [String] error message to use when assertion fails
391
+ # # @raise [ArgumentError] if the value is not an Integer
392
+ # # @return [void]
393
+ # # @see Cassandra::Type#assert
394
+ # def assert(value, message = nil, &block)
395
+ # end
396
+ #
397
+ # # @return [String] `"counter"`
398
+ # # @see Cassandra::Type#to_s
399
+ # def to_s
400
+ # end
401
+ # end
402
+ const_set('Counter', Simple.new(:counter))
403
+
404
+ # @!parse
405
+ # class Int < Type
406
+ # # @return [Symbol] `:int`
407
+ # # @see Cassandra::Type#kind
408
+ # def kind
409
+ # end
410
+ #
411
+ # # Coerces the value to Integer
412
+ # # @param value [Object] original value
413
+ # # @return [Integer] value
414
+ # # @see Cassandra::Type#new
415
+ # def new(value)
416
+ # end
417
+ #
418
+ # # Asserts that a given value is an Integer
419
+ # # @param value [Object] value to be validated
420
+ # # @param message [String] error message to use when assertion
421
+ # # fails
422
+ # # @yieldreturn [String] error message to use when assertion fails
423
+ # # @raise [ArgumentError] if the value is not an Integer
424
+ # # @return [void]
425
+ # # @see Cassandra::Type#assert
426
+ # def assert(value, message = nil, &block)
427
+ # end
428
+ #
429
+ # # @return [String] `"int"`
430
+ # # @see Cassandra::Type#to_s
431
+ # def to_s
432
+ # end
433
+ # end
434
+ const_set('Int', Simple.new(:int))
435
+
436
+ # @!parse
437
+ # class Varint < Type
438
+ # # @return [Symbol] `:varint`
439
+ # # @see Cassandra::Type#kind
440
+ # def kind
441
+ # end
442
+ #
443
+ # # Coerces the value to Integer
444
+ # # @param value [Object] original value
445
+ # # @return [Integer] value
446
+ # # @see Cassandra::Type#new
447
+ # def new(value)
448
+ # end
449
+ #
450
+ # # Asserts that a given value is an Integer
451
+ # # @param value [Object] value to be validated
452
+ # # @param message [String] error message to use when assertion
453
+ # # fails
454
+ # # @yieldreturn [String] error message to use when assertion fails
455
+ # # @raise [ArgumentError] if the value is not an Integer
456
+ # # @return [void]
457
+ # # @see Cassandra::Type#assert
458
+ # def assert(value, message = nil, &block)
459
+ # end
460
+ #
461
+ # # @return [String] `"varint"`
462
+ # # @see Cassandra::Type#to_s
463
+ # def to_s
464
+ # end
465
+ # end
466
+ const_set('Varint', Simple.new(:varint))
467
+
468
+ # @!parse
469
+ # class Boolean < Type
470
+ # # @return [Symbol] `:boolean`
471
+ # # @see Cassandra::Type#kind
472
+ # def kind
473
+ # end
474
+ #
475
+ # # Coerces the value to `true` or `false`
476
+ # # @param value [Object] original value
477
+ # # @return [Boolean] value
478
+ # # @see Cassandra::Type#new
479
+ # def new(value)
480
+ # end
481
+ #
482
+ # # Asserts that a given value is a `true` or `false`
483
+ # # @param value [Object] value to be validated
484
+ # # @param message [String] error message to use when assertion
485
+ # # fails
486
+ # # @yieldreturn [String] error message to use when assertion fails
487
+ # # @raise [ArgumentError] if the value is not `true` or `false`
488
+ # # @return [void]
489
+ # # @see Cassandra::Type#assert
490
+ # def assert(value, message = nil, &block)
491
+ # end
492
+ #
493
+ # # @return [String] `"boolean"`
494
+ # # @see Cassandra::Type#to_s
495
+ # def to_s
496
+ # end
497
+ # end
498
+ const_set('Boolean', Simple.new(:boolean))
499
+
500
+ # @!parse
501
+ # class Decimal < Type
502
+ # # @return [Symbol] `:decimal`
503
+ # # @see Cassandra::Type#kind
504
+ # def kind
505
+ # end
506
+ #
507
+ # # Coerces the value to BigDecimal
508
+ # # @param value [Object] original value
509
+ # # @return [BigDecimal] value
510
+ # # @see Cassandra::Type#new
511
+ # def new(value)
512
+ # end
513
+ #
514
+ # # Asserts that a given value is a BigDecimal
515
+ # # @param value [Object] value to be validated
516
+ # # @param message [String] error message to use when assertion
517
+ # # fails
518
+ # # @yieldreturn [String] error message to use when assertion fails
519
+ # # @raise [ArgumentError] if the value is not a BigDecimal
520
+ # # @return [void]
521
+ # # @see Cassandra::Type#assert
522
+ # def assert(value, message = nil, &block)
523
+ # end
524
+ #
525
+ # # @return [String] `"decimal"`
526
+ # # @see Cassandra::Type#to_s
527
+ # def to_s
528
+ # end
529
+ # end
530
+ const_set('Decimal', Simple.new(:decimal))
531
+
532
+ # @!parse
533
+ # class Double < Type
534
+ # # @return [Symbol] `:double`
535
+ # # @see Cassandra::Type#kind
536
+ # def kind
537
+ # end
538
+ #
539
+ # # Coerces the value to Float
540
+ # # @param value [Object] original value
541
+ # # @return [Float] value
542
+ # # @see Cassandra::Type#new
543
+ # def new(value)
544
+ # end
545
+ #
546
+ # # Asserts that a given value is a Float
547
+ # # @param value [Object] value to be validated
548
+ # # @param message [String] error message to use when assertion
549
+ # # fails
550
+ # # @yieldreturn [String] error message to use when assertion fails
551
+ # # @raise [ArgumentError] if the value is not a Float
552
+ # # @return [void]
553
+ # # @see Cassandra::Type#assert
554
+ # def assert(value, message = nil, &block)
555
+ # end
556
+ #
557
+ # # @return [String] `"double"`
558
+ # # @see Cassandra::Type#to_s
559
+ # def to_s
560
+ # end
561
+ # end
562
+ const_set('Double', Simple.new(:double))
563
+
564
+ # @!parse
565
+ # class Float < Type
566
+ # # @return [Symbol] `:float`
567
+ # # @see Cassandra::Type#kind
568
+ # def kind
569
+ # end
570
+ #
571
+ # # Coerces the value to Float
572
+ # # @param value [Object] original value
573
+ # # @return [Float] value
574
+ # # @see Cassandra::Type#new
575
+ # def new(value)
576
+ # end
577
+ #
578
+ # # Asserts that a given value is a Float
579
+ # # @param value [Object] value to be validated
580
+ # # @param message [String] error message to use when assertion
581
+ # # fails
582
+ # # @yieldreturn [String] error message to use when assertion fails
583
+ # # @raise [ArgumentError] if the value is not a Float
584
+ # # @return [void]
585
+ # # @see Cassandra::Type#assert
586
+ # def assert(value, message = nil, &block)
587
+ # end
588
+ #
589
+ # # @return [String] `"float"`
590
+ # # @see Cassandra::Type#to_s
591
+ # def to_s
592
+ # end
593
+ # end
594
+ const_set('Float', Simple.new(:float))
595
+
596
+ # @!parse
597
+ # class Inet < Type
598
+ # # @return [Symbol] `:inet`
599
+ # # @see Cassandra::Type#kind
600
+ # def kind
601
+ # end
602
+ #
603
+ # # Coerces the value to IPAddr
604
+ # # @param value [Object] original value
605
+ # # @return [IPAddr] value
606
+ # # @see Cassandra::Type#new
607
+ # def new(value)
608
+ # end
609
+ #
610
+ # # Asserts that a given value is an IPAddr
611
+ # # @param value [Object] value to be validated
612
+ # # @param message [String] error message to use when assertion
613
+ # # fails
614
+ # # @yieldreturn [String] error message to use when assertion fails
615
+ # # @raise [ArgumentError] if the value is not an IPAddr
616
+ # # @return [void]
617
+ # # @see Cassandra::Type#assert
618
+ # def assert(value, message = nil, &block)
619
+ # end
620
+ #
621
+ # # @return [String] `"inet"`
622
+ # # @see Cassandra::Type#to_s
623
+ # def to_s
624
+ # end
625
+ # end
626
+ const_set('Inet', Simple.new(:inet))
627
+
628
+ # @!parse
629
+ # class Timestamp < Type
630
+ # # @return [Symbol] `:timestamp`
631
+ # # @see Cassandra::Type#kind
632
+ # def kind
633
+ # end
634
+ #
635
+ # # Coerces the value to Time
636
+ # # @param value [Object] original value
637
+ # # @return [Time] value
638
+ # # @see Cassandra::Type#new
639
+ # def new(value)
640
+ # end
641
+ #
642
+ # # Asserts that a given value is a Time
643
+ # # @param value [Object] value to be validated
644
+ # # @param message [String] error message to use when assertion
645
+ # # fails
646
+ # # @yieldreturn [String] error message to use when assertion fails
647
+ # # @raise [ArgumentError] if the value is not a Time
648
+ # # @return [void]
649
+ # # @see Cassandra::Type#assert
650
+ # def assert(value, message = nil, &block)
651
+ # end
652
+ #
653
+ # # @return [String] `"timestamp"`
654
+ # # @see Cassandra::Type#to_s
655
+ # def to_s
656
+ # end
657
+ # end
658
+ const_set('Timestamp', Simple.new(:timestamp))
659
+
660
+ # @!parse
661
+ # class Uuid < Type
662
+ # # @return [Symbol] `:uuid`
663
+ # # @see Cassandra::Type#kind
664
+ # def kind
665
+ # end
666
+ #
667
+ # # Coerces the value to Cassandra::Uuid
668
+ # # @param value [Object] original value
669
+ # # @return [Cassandra::Uuid] value
670
+ # # @see Cassandra::Type#new
671
+ # def new(value)
672
+ # end
673
+ #
674
+ # # Asserts that a given value is a Cassandra::Uuid
675
+ # # @param value [Object] value to be validated
676
+ # # @param message [String] error message to use when assertion
677
+ # # fails
678
+ # # @yieldreturn [String] error message to use when assertion fails
679
+ # # @raise [ArgumentError] if the value is not a Cassandra::Uuid
680
+ # # @return [void]
681
+ # # @see Cassandra::Type#assert
682
+ # def assert(value, message = nil, &block)
683
+ # end
684
+ #
685
+ # # @return [String] `"uuid"`
686
+ # # @see Cassandra::Type#to_s
687
+ # def to_s
688
+ # end
689
+ # end
690
+ const_set('Uuid', Simple.new(:uuid))
691
+
692
+ # @!parse
693
+ # class Timeuuid < Type
694
+ # # @return [Symbol] `:timeuuid`
695
+ # # @see Cassandra::Type#kind
696
+ # def kind
697
+ # end
698
+ #
699
+ # # Coerces the value to Cassandra::Timeuuid
700
+ # # @param value [Object] original value
701
+ # # @return [Cassandra::Timeuuid] value
702
+ # # @see Cassandra::Type#new
703
+ # def new(value)
704
+ # end
705
+ #
706
+ # # Asserts that a given value is a Cassandra::Timeuuid
707
+ # # @param value [Object] value to be validated
708
+ # # @param message [String] error message to use when assertion
709
+ # # fails
710
+ # # @yieldreturn [String] error message to use when assertion fails
711
+ # # @raise [ArgumentError] if the value is not a Cassandra::Timeuuid
712
+ # # @return [void]
713
+ # # @see Cassandra::Type#assert
714
+ # def assert(value, message = nil, &block)
715
+ # end
716
+ #
717
+ # # @return [String] `"timeuuid"`
718
+ # # @see Cassandra::Type#to_s
719
+ # def to_s
720
+ # end
721
+ # end
722
+ const_set('Timeuuid', Simple.new(:timeuuid))
723
+
724
+ class List < Type
725
+ # @private
726
+ attr_reader :value_type
727
+
728
+ # @private
729
+ def initialize(value_type)
730
+ @value_type = value_type
731
+ end
732
+
733
+ # @return [Symbol] `:list`
734
+ # @see Cassandra::Type#kind
735
+ def kind
736
+ :list
737
+ end
738
+
739
+ # Coerces the value to Array
740
+ # @param value [Object] original value
741
+ # @return [Array] value
742
+ # @see Cassandra::Type#new
743
+ def new(*value)
744
+ value = Array(value.first) if value.one?
745
+
746
+ value.each do |v|
747
+ Util.assert_type(@value_type, v)
748
+ end
749
+ value
750
+ end
751
+
752
+ # Asserts that a given value is an Array
753
+ # @param value [Object] value to be validated
754
+ # @param message [String] error message to use when assertion fails
755
+ # @yieldreturn [String] error message to use when assertion fails
756
+ # @raise [ArgumentError] if the value is not an Array
757
+ # @return [void]
758
+ # @see Cassandra::Type#assert
759
+ def assert(value, message = nil, &block)
760
+ Util.assert_instance_of(::Array, value, message, &block)
761
+ value.each do |v|
762
+ Util.assert_type(@value_type, v, message, &block)
763
+ end
764
+ nil
765
+ end
766
+
767
+ # @return [String] `"list<type>"`
768
+ # @see Cassandra::Type#to_s
769
+ def to_s
770
+ "list<#{@value_type.to_s}>"
771
+ end
772
+
773
+ def eql?(other)
774
+ other.is_a?(List) && @value_type == other.value_type
775
+ end
776
+ alias :== :eql?
777
+ end
778
+
779
+ class Map < Type
780
+ # @private
781
+ attr_reader :key_type, :value_type
782
+
783
+ # @private
784
+ def initialize(key_type, value_type)
785
+ @key_type = key_type
786
+ @value_type = value_type
787
+ end
788
+
789
+ # @return [Symbol] `:map`
790
+ # @see Cassandra::Type#kind
791
+ def kind
792
+ :map
793
+ end
794
+
795
+ # Coerces the value to Hash
796
+ # @param value [Object] original value
797
+ # @return [Hash] value
798
+ # @see Cassandra::Type#new
799
+ def new(*value)
800
+ value = value.first if value.one?
801
+
802
+ case value
803
+ when ::Hash
804
+ value.each do |k, v|
805
+ Util.assert_type(@key_type, k)
806
+ Util.assert_type(@value_type, v)
807
+ end
808
+ value
809
+ when ::Array
810
+ result = ::Hash.new
811
+ value.each_slice(2) do |(k, v)|
812
+ Util.assert_type(@key_type, k)
813
+ Util.assert_type(@value_type, v)
814
+ result[k] = v
815
+ end
816
+ result
817
+ else
818
+ raise ::ArgumentError, "cannot convert #{value.inspect} to #{to_s}"
819
+ end
820
+ end
821
+
822
+ # Asserts that a given value is a Hash
823
+ # @param value [Object] value to be validated
824
+ # @param message [String] error message to use when assertion fails
825
+ # @yieldreturn [String] error message to use when assertion fails
826
+ # @raise [ArgumentError] if the value is not a Hash
827
+ # @return [void]
828
+ # @see Cassandra::Type#assert
829
+ def assert(value, message = nil, &block)
830
+ Util.assert_instance_of(::Hash, value, message, &block)
831
+ value.each do |k, v|
832
+ Util.assert_type(@key_type, k, message, &block)
833
+ Util.assert_type(@value_type, v, message, &block)
834
+ end
835
+ nil
836
+ end
837
+
838
+ # @return [String] `"map<type, type>"`
839
+ # @see Cassandra::Type#to_s
840
+ def to_s
841
+ "map<#{@key_type.to_s}, #{@value_type.to_s}>"
842
+ end
843
+
844
+ def eql?(other)
845
+ other.is_a?(Map) &&
846
+ @key_type == other.key_type &&
847
+ @value_type == other.value_type
848
+ end
849
+ alias :== :eql?
850
+ end
851
+
852
+ class Set < Type
853
+ # @private
854
+ attr_reader :value_type
855
+
856
+ # @private
857
+ def initialize(value_type)
858
+ @value_type = value_type
859
+ end
860
+
861
+ # @return [Symbol] `:set`
862
+ # @see Cassandra::Type#kind
863
+ def kind
864
+ :set
865
+ end
866
+
867
+ # Coerces the value to Set
868
+ # @param value [Object] original value
869
+ # @return [Set] value
870
+ # @see Cassandra::Type#new
871
+ # @example Creating a set using splat arguments
872
+ # include Cassandra::Types
873
+ #
874
+ # set(varchar).new('Jane', 'Alice', 'Loren') => #<Set: {"Jane", "Alice", "Loren"}>
875
+ #
876
+ # @example Coercing an existing set
877
+ # include Cassandra::Types
878
+ #
879
+ # set(varchar).new(Set['Jane', 'Alice', 'Loren']) => #<Set: {"Jane", "Alice", "Loren"}>
880
+ #
881
+ # @example Coercing an array
882
+ # include Cassandra::Types
883
+ #
884
+ # set(varchar).new(['Jane', 'Alice', 'Loren']) => #<Set: {"Jane", "Alice", "Loren"}>
885
+ def new(*value)
886
+ value = value.first if value.one?
887
+
888
+ case value
889
+ when ::Array
890
+ result = ::Set.new
891
+ value.each do |v|
892
+ Util.assert_type(@value_type, v)
893
+ result << v
894
+ end
895
+ result
896
+ when ::Set
897
+ value.each do |v|
898
+ Util.assert_type(@value_type, v)
899
+ end
900
+ value
901
+ else
902
+ Util.assert_type(@value_type, value)
903
+ ::Set[value]
904
+ end
905
+ end
906
+
907
+ # Asserts that a given value is an Set
908
+ # @param value [Object] value to be validated
909
+ # @param message [String] error message to use when assertion fails
910
+ # @yieldreturn [String] error message to use when assertion fails
911
+ # @raise [ArgumentError] if the value is not an Set
912
+ # @return [void]
913
+ # @see Cassandra::Type#assert
914
+ def assert(value, message = nil, &block)
915
+ Util.assert_instance_of(::Set, value, message, &block)
916
+ value.each do |v|
917
+ Util.assert_type(@value_type, v, message, &block)
918
+ end
919
+ nil
920
+ end
921
+
922
+ # @return [String] `"set<type>"`
923
+ # @see Cassandra::Type#to_s
924
+ def to_s
925
+ "set<#{@value_type.to_s}>"
926
+ end
927
+
928
+ def eql?(other)
929
+ other.is_a?(Set) && @value_type == other.value_type
930
+ end
931
+ alias :== :eql?
932
+ end
933
+
934
+ class Tuple < Type
935
+ # @private
936
+ attr_reader :members
937
+
938
+ # @private
939
+ def initialize(*members)
940
+ @members = members
941
+ end
942
+
943
+ # @return [Symbol] `:tuple`
944
+ # @see Cassandra::Type#kind
945
+ def kind
946
+ :tuple
947
+ end
948
+
949
+ # Coerces the value to Cassandra::Tuple
950
+ # @param values [*Object] tuple values
951
+ # @return [Cassandra::Tuple] value
952
+ # @see Cassandra::Type#new
953
+ # @example Creating a tuple
954
+ # include Cassandra::Types
955
+ #
956
+ # tuple(varchar, varchar, int).new('Jane', 'Smith', 38) # => (Jane, Smith, 38)
957
+ def new(*values)
958
+ Util.assert(values.size <= @members.size) { "too many values: #{values.size} out of max #{@members.size}" }
959
+ values.each_with_index do |v, i|
960
+ Util.assert_type(@members[i], v)
961
+ end
962
+ Cassandra::Tuple::Strict.new(@members, values)
963
+ end
964
+
965
+ # Asserts that a given value is an Cassandra::Tuple
966
+ # @param value [Object] value to be validated
967
+ # @param message [String] error message to use when assertion fails
968
+ # @yieldreturn [String] error message to use when assertion fails
969
+ # @raise [ArgumentError] if the value is not an Cassandra::Tuple
970
+ # @return [void]
971
+ # @see Cassandra::Type#assert
972
+ def assert(value, message = nil, &block)
973
+ Util.assert_instance_of(Cassandra::Tuple, value, message, &block)
974
+ Util.assert(value.size <= @members.size, message, &block)
975
+ @members.each_with_index do |type, i|
976
+ Util.assert_type(type, value[i], message, &block)
977
+ end
978
+ nil
979
+ end
980
+
981
+ # @return [String] `"tuple<type, type, type...>"`
982
+ # @see Cassandra::Type#to_s
983
+ def to_s
984
+ "tuple<#{@members.map(&:to_s).join(', ')}>"
985
+ end
986
+
987
+ def eql?(other)
988
+ other.is_a?(Tuple) && @members == other.members
989
+ end
990
+ alias :== :eql?
991
+ end
992
+
993
+ class UserDefined < Type
994
+ class Field
995
+ # @return [String] name of this field
996
+ attr_reader :name
997
+ # @return [Cassandra::Type] type of this field
998
+ attr_reader :type
999
+
1000
+ # @private
1001
+ def initialize(name, type)
1002
+ @name = name
1003
+ @type = type
1004
+ end
1005
+
1006
+ # String representation of the field
1007
+ # @return [String] String representation of the field
1008
+ def to_s
1009
+ "#{@name} #{@type}"
1010
+ end
1011
+
1012
+ def eql?(other)
1013
+ other.is_a?(Field) &&
1014
+ @name == other.name &&
1015
+ @type == other.type
1016
+ end
1017
+ alias :== :eql?
1018
+ end
1019
+
1020
+ # @return [String] keyspace where this type is defined
1021
+ attr_reader :keyspace
1022
+
1023
+ # @return [String] name of this type
1024
+ attr_reader :name
1025
+
1026
+ # @private
1027
+ attr_reader :fields
1028
+
1029
+ # @private
1030
+ def initialize(keyspace, name, fields)
1031
+ @keyspace = keyspace
1032
+ @name = name
1033
+ @fields = fields
1034
+ end
1035
+
1036
+ # @param name [String] field name
1037
+ # @return [Boolean] whether this type has a given field
1038
+ def has_field?(name)
1039
+ @fields.any? {|f| f.name == name}
1040
+ end
1041
+
1042
+ # Yield or enumerate each field defined in this type
1043
+ # @overload each_field
1044
+ # @yieldparam field [Cassandra::UserDefined::Field] field
1045
+ # @return [Cassandra::Types::UserDefined] self
1046
+ # @overload each_field
1047
+ # @return [Array<Array<String, Cassandra::Type>>] a list of fields
1048
+ def each_field(&block)
1049
+ if block_given?
1050
+ @fields.each(&block)
1051
+ self
1052
+ else
1053
+ @fields.dup
1054
+ end
1055
+ end
1056
+ alias :fields :each_field
1057
+
1058
+ # @param name [String] field name
1059
+ # @return [Cassandra::UserDefined::Field, nil] a field with this name or
1060
+ # nil
1061
+ def field(name)
1062
+ @fields.find {|f| f.name == name}
1063
+ end
1064
+
1065
+ # @return [Symbol] `:udt`
1066
+ # @see Cassandra::Type#kind
1067
+ def kind
1068
+ :udt
1069
+ end
1070
+
1071
+ # Coerces the value to Cassandra::UDT
1072
+ # @param value [Object] original value
1073
+ # @return [Cassandra::UDT] value
1074
+ # @see Cassandra::Type#new
1075
+ def new(*value)
1076
+ value = value.first if value.one?
1077
+ value = Array(value) unless value.is_a?(::Hash)
1078
+
1079
+ Util.assert(value.size <= @fields.size) { "too many values: #{value.size} out of #{@fields.size}" }
1080
+
1081
+ case value
1082
+ when ::Array
1083
+ result = ::Hash.new
1084
+ value.each_with_index do |v, i|
1085
+ f = @fields[i]
1086
+ Util.assert_type(f.type, v)
1087
+ result[f.name] = v
1088
+ end
1089
+ when ::Hash
1090
+ result = ::Hash.new
1091
+ @fields.each do |f|
1092
+ n = f.name
1093
+ v = value[n]
1094
+ Util.assert_type(f.type, v)
1095
+ result[n] = v
1096
+ end
1097
+ end
1098
+
1099
+ Cassandra::UDT::Strict.new(@keyspace, @name, @fields, result)
1100
+ end
1101
+
1102
+ # Asserts that a given value is an Cassandra::UDT
1103
+ # @param value [Object] value to be validated
1104
+ # @param message [String] error message to use when assertion fails
1105
+ # @yieldreturn [String] error message to use when assertion fails
1106
+ # @raise [ArgumentError] if the value is not an Cassandra::UDT
1107
+ # @return [void]
1108
+ # @see Cassandra::Type#assert
1109
+ def assert(value, message = nil, &block)
1110
+ Util.assert_instance_of(Cassandra::UDT, value, message, &block)
1111
+ Util.assert(value.size <= @fields.size, message, &block)
1112
+ @fields.each do |field|
1113
+ Util.assert_type(field.type, value[field.name], message, &block)
1114
+ end
1115
+ nil
1116
+ end
1117
+
1118
+ # @return [String] `"keyspace.name"`
1119
+ # @see Cassandra::Type#to_s
1120
+ def to_s
1121
+ "#{Util.escape_name(@keyspace)}.#{Util.escape_name(@name)} {#{@fields.join(', ')}}"
1122
+ end
1123
+
1124
+ def eql?(other)
1125
+ other.is_a?(UserDefined) &&
1126
+ @keyspace == other.keyspace &&
1127
+ @name == other.name &&
1128
+ @fields == other.fields
1129
+ end
1130
+ alias :== :eql?
1131
+
1132
+ # Output this type in CQL
1133
+ def to_cql
1134
+ cql = "CREATE TYPE #{Util.escape_name(@keyspace)}.#{Util.escape_name(@name)} (\n"
1135
+ first = true
1136
+
1137
+ @fields.each do |field|
1138
+ if first
1139
+ first = false
1140
+ else
1141
+ cql << ",\n" unless first
1142
+ end
1143
+ cql << " #{field.name} #{type_to_cql(field.type)}"
1144
+ end
1145
+
1146
+ cql << "\n);"
1147
+
1148
+ cql
1149
+ end
1150
+
1151
+ private
1152
+
1153
+ # @private
1154
+ def type_to_cql(type)
1155
+ case type.kind
1156
+ when :tuple
1157
+ "frozen <#{type}>"
1158
+ when :udt
1159
+ if @keyspace == type.keyspace
1160
+ "frozen <#{Util.escape_name(type.name)}>"
1161
+ else
1162
+ "frozen <#{Util.escape_name(type.keyspace)}.#{Util.escape_name(type.name)}>"
1163
+ end
1164
+ else
1165
+ "#{type}"
1166
+ end
1167
+ end
1168
+ end
1169
+
1170
+ class Custom < Type
1171
+ attr_reader :name
1172
+
1173
+ def initialize(name)
1174
+ @name = name
1175
+ end
1176
+
1177
+ # @return [Symbol] shorthand type name
1178
+ def kind
1179
+ :custom
1180
+ end
1181
+
1182
+ # Coerces a given value to this type
1183
+ #
1184
+ # @param value [*Object] value to be coerced
1185
+ # @return [Object] a value of this type
1186
+ def new(*value)
1187
+ raise ::NotImplementedError, "unable to create a value for custom type: #{@name.inspect}"
1188
+ end
1189
+
1190
+ # Asserts that a given value is of this type
1191
+ # @param value [Object] value to be validated
1192
+ # @param message [String] error message to use when assertion fails
1193
+ # @yieldreturn [String] error message to use when assertion fails
1194
+ # @raise [ArgumentError] if the value is invalid
1195
+ # @return [void]
1196
+ def assert(value, message = nil, &block)
1197
+ raise ::NotImplementedError, "unable to assert a value for custom type: #{@name.inspect}"
1198
+ end
1199
+
1200
+ # @return [String] a cassandra representation of this type
1201
+ def to_s
1202
+ "custom: #{@name}"
1203
+ end
1204
+ end
1205
+
1206
+ # @return [Cassandra::Types::Varchar] varchar type
1207
+ def varchar
1208
+ Varchar
1209
+ end
1210
+
1211
+ # @return [Cassandra::Types::Text] text type
1212
+ def text
1213
+ Text
1214
+ end
1215
+
1216
+ # @return [Cassandra::Types::Blob] blob type
1217
+ def blob
1218
+ Blob
1219
+ end
1220
+
1221
+ # @return [Cassandra::Types::Ascii] ascii type
1222
+ def ascii
1223
+ Ascii
1224
+ end
1225
+
1226
+ # @return [Cassandra::Types::Bigint] bigint type
1227
+ def bigint
1228
+ Bigint
1229
+ end
1230
+
1231
+ # @return [Cassandra::Types::Counter] counter type
1232
+ def counter
1233
+ Counter
1234
+ end
1235
+
1236
+ # @return [Cassandra::Types::Int] int type
1237
+ def int
1238
+ Int
1239
+ end
1240
+
1241
+ # @return [Cassandra::Types::Varint] varint type
1242
+ def varint
1243
+ Varint
1244
+ end
1245
+
1246
+ # @return [Cassandra::Types::Boolean] boolean type
1247
+ def boolean
1248
+ Boolean
1249
+ end
1250
+
1251
+ # @return [Cassandra::Types::Decimal] decimal type
1252
+ def decimal
1253
+ Decimal
1254
+ end
1255
+
1256
+ # @return [Cassandra::Types::Double] double type
1257
+ def double
1258
+ Double
1259
+ end
1260
+
1261
+ # @return [Cassandra::Types::Float] float type
1262
+ def float
1263
+ Float
1264
+ end
1265
+
1266
+ # @return [Cassandra::Types::Inet] inet type
1267
+ def inet
1268
+ Inet
1269
+ end
1270
+
1271
+ # @return [Cassandra::Types::Timestamp] timestamp type
1272
+ def timestamp
1273
+ Timestamp
1274
+ end
1275
+
1276
+ # @return [Cassandra::Types::Uuid] uuid type
1277
+ def uuid
1278
+ Uuid
1279
+ end
1280
+
1281
+ # @return [Cassandra::Types::Timeuuid] timeuuid type
1282
+ def timeuuid
1283
+ Timeuuid
1284
+ end
1285
+
1286
+ # @param value_type [Cassandra::Type] the type of elements in this list
1287
+ # @return [Cassandra::Types::Map] map type
1288
+ def list(value_type)
1289
+ Util.assert_instance_of(Cassandra::Type, value_type,
1290
+ "list type must be a Cassandra::Type, #{value_type.inspect} given"
1291
+ )
1292
+
1293
+ List.new(value_type)
1294
+ end
1295
+
1296
+ # @param key_type [Cassandra::Type] the type of keys in this map
1297
+ # @param value_type [Cassandra::Type] the type of values in this map
1298
+ # @return [Cassandra::Types::Varchar] varchar type
1299
+ def map(key_type, value_type)
1300
+ Util.assert_instance_of(Cassandra::Type, key_type,
1301
+ "map key type must be a Cassandra::Type, #{key_type.inspect} given"
1302
+ )
1303
+ Util.assert_instance_of(Cassandra::Type, value_type,
1304
+ "map value type must be a Cassandra::Type, #{value_type.inspect} given"
1305
+ )
1306
+
1307
+ Map.new(key_type, value_type)
1308
+ end
1309
+
1310
+ # @param value_type [Cassandra::Type] the type of elements in this set
1311
+ # @return [Cassandra::Types::Set] set type
1312
+ def set(value_type)
1313
+ Util.assert_instance_of(Cassandra::Type, value_type,
1314
+ "set type must be a Cassandra::Type, #{value_type.inspect} given"
1315
+ )
1316
+
1317
+ Set.new(value_type)
1318
+ end
1319
+
1320
+ # @param members [*Cassandra::Type] types of members of this tuple
1321
+ # @return [Cassandra::Types::Tuple] tuple type
1322
+ def tuple(*members)
1323
+ Util.assert_not_empty(members, "tuple must contain at least one member")
1324
+ members.each do |member|
1325
+ Util.assert_instance_of(Cassandra::Type, member,
1326
+ "each tuple member must be a Cassandra::Type, " \
1327
+ "#{member.inspect} given"
1328
+ )
1329
+ end
1330
+
1331
+ Tuple.new(*members)
1332
+ end
1333
+
1334
+ # Creates a User Defined Type instance
1335
+ # @example Various ways of defining the same UDT
1336
+ # include Cassandra::Types
1337
+ #
1338
+ # udt('simplex', 'address', {'street' => varchar, 'city' => varchar, 'state' => varchar, 'zip' => varchar}) #=> simplex.address
1339
+ #
1340
+ # udt('simplex', 'address', [['street', varchar], ['city', varchar], ['state', varchar], ['zip', varchar]]) #=> simplex.address
1341
+ #
1342
+ # udt('simplex', 'address', ['street', varchar], ['city', varchar], ['state', varchar], ['zip', varchar]) #=> simplex.address
1343
+ #
1344
+ # udt('simplex', 'address', 'street', varchar, 'city', varchar, 'state', varchar, 'zip', varchar) #=> simplex.address
1345
+ # @param keyspace [String] name of the keyspace that this UDT is defined in
1346
+ # @param name [String] name of this UDT
1347
+ # @param fields [Hash<String, Cassandra::Type>,
1348
+ # Array<Array<String, Cassandra::Type>>,
1349
+ # *(String, Cassandra::Type),
1350
+ # *Array<String, Cassandra::Type>] UDT field types
1351
+ # @return [Cassandra::Types::UserDefined] user defined type
1352
+ def udt(keyspace, name, *fields)
1353
+ keyspace = String(keyspace)
1354
+ name = String(name)
1355
+ fields = Array(fields.first) if fields.one?
1356
+
1357
+ Util.assert_not_empty(fields,
1358
+ "user-defined type must contain at least one field"
1359
+ )
1360
+
1361
+ if fields.first.is_a?(::Array)
1362
+ fields = fields.map do |pair|
1363
+ Util.assert(pair.size == 2,
1364
+ "fields of a user-defined type must be an Array of name and " \
1365
+ "value pairs, #{pair.inspect} given"
1366
+ )
1367
+ Util.assert_instance_of(::String, pair[0],
1368
+ "each field name for a user-defined type must be a String, " \
1369
+ "#{pair[0].inspect} given"
1370
+ )
1371
+ Util.assert_instance_of(Cassandra::Type, pair[1],
1372
+ "each field type for a user-defined type must be a " \
1373
+ "Cassandra::Type, #{pair[1].inspect} given"
1374
+ )
1375
+
1376
+ UserDefined::Field.new(*pair)
1377
+ end
1378
+ else
1379
+ Util.assert((fields.size % 2) == 0,
1380
+ "fields of a user-defined type must be an Array of alternating " \
1381
+ "names and values pairs, #{fields.inspect} given"
1382
+ )
1383
+ fields = fields.each_slice(2).map do |field_name, field_type|
1384
+ Util.assert_instance_of(::String, field_name,
1385
+ "each field name for a user-defined type must be a String, " \
1386
+ "#{field_name.inspect} given"
1387
+ )
1388
+ Util.assert_instance_of(Cassandra::Type, field_type,
1389
+ "each field type for a user-defined type must be a " \
1390
+ "Cassandra::Type, #{field_type.inspect} given"
1391
+ )
1392
+
1393
+ UserDefined::Field.new(field_name, field_type)
1394
+ end
1395
+ end
1396
+
1397
+ UserDefined.new(keyspace, name, fields)
1398
+ end
1399
+
1400
+ # @param name [String] name of the custom type
1401
+ # @return [Cassandra::Types::Custom] custom type
1402
+ def custom(name)
1403
+ Custom.new(name)
1404
+ end
1405
+ end
1406
+ end