yugabyte-ycql-driver 3.2.3.1

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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +13 -0
  3. data/README.md +242 -0
  4. data/ext/cassandra_murmur3/cassandra_murmur3.c +178 -0
  5. data/ext/cassandra_murmur3/extconf.rb +2 -0
  6. data/lib/cassandra/address_resolution.rb +36 -0
  7. data/lib/cassandra/address_resolution/policies.rb +2 -0
  8. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +56 -0
  9. data/lib/cassandra/address_resolution/policies/none.rb +35 -0
  10. data/lib/cassandra/aggregate.rb +123 -0
  11. data/lib/cassandra/argument.rb +51 -0
  12. data/lib/cassandra/attr_boolean.rb +33 -0
  13. data/lib/cassandra/auth.rb +100 -0
  14. data/lib/cassandra/auth/providers.rb +17 -0
  15. data/lib/cassandra/auth/providers/password.rb +65 -0
  16. data/lib/cassandra/cassandra_logger.rb +80 -0
  17. data/lib/cassandra/cluster.rb +331 -0
  18. data/lib/cassandra/cluster/client.rb +1612 -0
  19. data/lib/cassandra/cluster/connection_pool.rb +78 -0
  20. data/lib/cassandra/cluster/connector.rb +372 -0
  21. data/lib/cassandra/cluster/control_connection.rb +962 -0
  22. data/lib/cassandra/cluster/failed_connection.rb +35 -0
  23. data/lib/cassandra/cluster/metadata.rb +142 -0
  24. data/lib/cassandra/cluster/options.rb +145 -0
  25. data/lib/cassandra/cluster/registry.rb +284 -0
  26. data/lib/cassandra/cluster/schema.rb +405 -0
  27. data/lib/cassandra/cluster/schema/cql_type_parser.rb +112 -0
  28. data/lib/cassandra/cluster/schema/fetchers.rb +1627 -0
  29. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +175 -0
  30. data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
  31. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +45 -0
  32. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
  33. data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
  34. data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
  35. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +102 -0
  36. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
  37. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
  38. data/lib/cassandra/column.rb +66 -0
  39. data/lib/cassandra/column_container.rb +326 -0
  40. data/lib/cassandra/compression.rb +69 -0
  41. data/lib/cassandra/compression/compressors/lz4.rb +73 -0
  42. data/lib/cassandra/compression/compressors/snappy.rb +69 -0
  43. data/lib/cassandra/custom_data.rb +53 -0
  44. data/lib/cassandra/driver.rb +260 -0
  45. data/lib/cassandra/errors.rb +784 -0
  46. data/lib/cassandra/execution/info.rb +69 -0
  47. data/lib/cassandra/execution/options.rb +267 -0
  48. data/lib/cassandra/execution/profile.rb +153 -0
  49. data/lib/cassandra/execution/profile_manager.rb +71 -0
  50. data/lib/cassandra/execution/trace.rb +192 -0
  51. data/lib/cassandra/executors.rb +113 -0
  52. data/lib/cassandra/function.rb +156 -0
  53. data/lib/cassandra/function_collection.rb +85 -0
  54. data/lib/cassandra/future.rb +794 -0
  55. data/lib/cassandra/host.rb +102 -0
  56. data/lib/cassandra/index.rb +118 -0
  57. data/lib/cassandra/keyspace.rb +473 -0
  58. data/lib/cassandra/listener.rb +87 -0
  59. data/lib/cassandra/load_balancing.rb +121 -0
  60. data/lib/cassandra/load_balancing/policies.rb +20 -0
  61. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +172 -0
  62. data/lib/cassandra/load_balancing/policies/round_robin.rb +141 -0
  63. data/lib/cassandra/load_balancing/policies/token_aware.rb +149 -0
  64. data/lib/cassandra/load_balancing/policies/white_list.rb +100 -0
  65. data/lib/cassandra/materialized_view.rb +92 -0
  66. data/lib/cassandra/null_logger.rb +56 -0
  67. data/lib/cassandra/protocol.rb +102 -0
  68. data/lib/cassandra/protocol/coder.rb +1085 -0
  69. data/lib/cassandra/protocol/cql_byte_buffer.rb +418 -0
  70. data/lib/cassandra/protocol/cql_protocol_handler.rb +448 -0
  71. data/lib/cassandra/protocol/request.rb +41 -0
  72. data/lib/cassandra/protocol/requests/auth_response_request.rb +51 -0
  73. data/lib/cassandra/protocol/requests/batch_request.rb +117 -0
  74. data/lib/cassandra/protocol/requests/credentials_request.rb +51 -0
  75. data/lib/cassandra/protocol/requests/execute_request.rb +122 -0
  76. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  77. data/lib/cassandra/protocol/requests/prepare_request.rb +59 -0
  78. data/lib/cassandra/protocol/requests/query_request.rb +112 -0
  79. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  80. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  81. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  82. data/lib/cassandra/protocol/response.rb +28 -0
  83. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +50 -0
  84. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +36 -0
  85. data/lib/cassandra/protocol/responses/auth_success_response.rb +36 -0
  86. data/lib/cassandra/protocol/responses/authenticate_response.rb +36 -0
  87. data/lib/cassandra/protocol/responses/error_response.rb +142 -0
  88. data/lib/cassandra/protocol/responses/event_response.rb +30 -0
  89. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +52 -0
  90. data/lib/cassandra/protocol/responses/prepared_result_response.rb +62 -0
  91. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +59 -0
  92. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +71 -0
  93. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +61 -0
  94. data/lib/cassandra/protocol/responses/ready_response.rb +43 -0
  95. data/lib/cassandra/protocol/responses/result_response.rb +42 -0
  96. data/lib/cassandra/protocol/responses/rows_result_response.rb +39 -0
  97. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +73 -0
  98. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +70 -0
  99. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +37 -0
  100. data/lib/cassandra/protocol/responses/status_change_event_response.rb +39 -0
  101. data/lib/cassandra/protocol/responses/supported_response.rb +36 -0
  102. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +33 -0
  103. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +58 -0
  104. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +48 -0
  105. data/lib/cassandra/protocol/responses/void_result_response.rb +34 -0
  106. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +73 -0
  107. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +63 -0
  108. data/lib/cassandra/protocol/v1.rb +326 -0
  109. data/lib/cassandra/protocol/v3.rb +358 -0
  110. data/lib/cassandra/protocol/v4.rb +478 -0
  111. data/lib/cassandra/reconnection.rb +49 -0
  112. data/lib/cassandra/reconnection/policies.rb +20 -0
  113. data/lib/cassandra/reconnection/policies/constant.rb +46 -0
  114. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  115. data/lib/cassandra/result.rb +276 -0
  116. data/lib/cassandra/retry.rb +154 -0
  117. data/lib/cassandra/retry/policies.rb +21 -0
  118. data/lib/cassandra/retry/policies/default.rb +53 -0
  119. data/lib/cassandra/retry/policies/downgrading_consistency.rb +73 -0
  120. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  121. data/lib/cassandra/session.rb +270 -0
  122. data/lib/cassandra/statement.rb +32 -0
  123. data/lib/cassandra/statements.rb +23 -0
  124. data/lib/cassandra/statements/batch.rb +146 -0
  125. data/lib/cassandra/statements/bound.rb +65 -0
  126. data/lib/cassandra/statements/prepared.rb +235 -0
  127. data/lib/cassandra/statements/simple.rb +118 -0
  128. data/lib/cassandra/statements/void.rb +38 -0
  129. data/lib/cassandra/table.rb +240 -0
  130. data/lib/cassandra/time.rb +103 -0
  131. data/lib/cassandra/time_uuid.rb +78 -0
  132. data/lib/cassandra/timestamp_generator.rb +37 -0
  133. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  134. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  135. data/lib/cassandra/trigger.rb +67 -0
  136. data/lib/cassandra/tuple.rb +131 -0
  137. data/lib/cassandra/types.rb +1704 -0
  138. data/lib/cassandra/udt.rb +443 -0
  139. data/lib/cassandra/util.rb +464 -0
  140. data/lib/cassandra/uuid.rb +110 -0
  141. data/lib/cassandra/uuid/generator.rb +212 -0
  142. data/lib/cassandra/version.rb +21 -0
  143. data/lib/datastax/cassandra.rb +47 -0
  144. data/lib/ycql.rb +842 -0
  145. metadata +243 -0
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ module Statements
21
+ class Simple
22
+ include Statement
23
+
24
+ # @return [String] original cql used to prepare this statement
25
+ attr_reader :cql
26
+ # @return [Array<Object>] a list of positional parameters for the cql
27
+ attr_reader :params
28
+
29
+ # @private
30
+ attr_reader :params_types
31
+
32
+ # @private
33
+ attr_reader :params_names
34
+
35
+ # @param cql [String] a cql statement
36
+ # @param params [Array, Hash] (nil) positional or named arguments
37
+ # for the query
38
+ # @param type_hints [Array, Hash] (nil) positional or named types
39
+ # to override type guessing for the query
40
+ # @param idempotent [Boolean] (false) whether this statement can be
41
+ # safely retries on timeouts
42
+ #
43
+ # @note Positional arguments for simple statements are only supported
44
+ # starting with Apache Cassandra 2.0 and above.
45
+ #
46
+ # @note Named arguments for simple statements are only supported
47
+ # starting with Apache Cassandra 2.1 and above.
48
+ #
49
+ # @raise [ArgumentError] if cql statement given is not a String
50
+ def initialize(cql, params = nil, type_hints = nil, idempotent = false)
51
+ Util.assert_instance_of(::String, cql) do
52
+ "cql must be a string, #{cql.inspect} given"
53
+ end
54
+
55
+ params ||= EMPTY_LIST
56
+
57
+ if params.is_a?(::Hash)
58
+ params_names = []
59
+ params = params.each_with_object([]) do |(name, value), collector|
60
+ params_names << name
61
+ collector << value
62
+ end
63
+ if type_hints && !type_hints.empty?
64
+ Util.assert_instance_of(::Hash, type_hints) do
65
+ 'type_hints must be a Hash when using named params'
66
+ end
67
+ end
68
+ else
69
+ Util.assert_instance_of(::Array, params) do
70
+ "params must be an Array or a Hash, #{params.inspect} given"
71
+ end
72
+ params_names = EMPTY_LIST
73
+ end
74
+
75
+ type_hints ||= EMPTY_LIST
76
+
77
+ if type_hints.is_a?(::Hash)
78
+ type_hints = params_names.map {|name| type_hints[name] }
79
+ else
80
+ Util.assert_instance_of(::Array, type_hints) do
81
+ "type_hints must be an Array or a Hash, #{type_hints.inspect} given"
82
+ end
83
+ end
84
+
85
+ @cql = cql
86
+ @params = params
87
+ @params_types = params.each_with_index.map do |value, index|
88
+ (!type_hints.empty? && type_hints[index] && type_hints[index].is_a?(Type)) ?
89
+ type_hints[index] :
90
+ Util.guess_type(value)
91
+ end
92
+ @params_names = params_names
93
+ @idempotent = idempotent
94
+ end
95
+
96
+ # @private
97
+ def accept(client, options)
98
+ client.query(self, options)
99
+ end
100
+
101
+ # @return [String] a CLI-friendly simple statement representation
102
+ def inspect
103
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} @cql=#{@cql.inspect} " \
104
+ "@params=#{@params.inspect}>"
105
+ end
106
+
107
+ # @param other [Object, Cassandra::Statements::Simple] object to compare
108
+ # @return [Boolean] whether the statements are equal
109
+ def eql?(other)
110
+ other.is_a?(Simple) &&
111
+ @cql == other.cql &&
112
+ @params == other.params
113
+ end
114
+
115
+ alias == eql?
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ module Statements
21
+ # This statement is passed to {Cassandra::LoadBalancing::Policy#plan} when
22
+ # establishing connections and preparing statements
23
+ class Void
24
+ include Statement
25
+
26
+ # @private
27
+ def accept(client, options)
28
+ nil
29
+ end
30
+
31
+ # Returns nothing
32
+ # @return [nil] there is no cql for the void statement
33
+ def cql
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,240 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ # Represents a cassandra table
21
+ # @see Cassandra::Keyspace#each_table
22
+ # @see Cassandra::Keyspace#table
23
+ class Table < ColumnContainer
24
+ # @return [Array<Symbol>] an array of order values (`:asc` or `:desc`) that apply to the
25
+ # `clustering_columns` array.
26
+ attr_reader :clustering_order
27
+
28
+ # @private
29
+ def initialize(keyspace,
30
+ name,
31
+ partition_key,
32
+ clustering_columns,
33
+ other_columns,
34
+ options,
35
+ clustering_order,
36
+ id)
37
+ super(keyspace, name, partition_key, clustering_columns, other_columns, options, id)
38
+ @clustering_order = clustering_order.freeze
39
+ @indexes = []
40
+ @indexes_hash = {}
41
+ @materialized_views = []
42
+ @materialized_views_hash = {}
43
+ @triggers = []
44
+ @triggers_hash = {}
45
+ end
46
+
47
+ # @param name [String] index name
48
+ # @return [Boolean] whether this table has a given index
49
+ def has_index?(name)
50
+ @indexes_hash.key?(name)
51
+ end
52
+
53
+ # @param name [String] index name
54
+ # @return [Cassandra::Index, nil] an index or nil
55
+ def index(name)
56
+ @indexes_hash[name]
57
+ end
58
+
59
+ # Yield or enumerate each index bound to this table
60
+ # @overload each_index
61
+ # @yieldparam index [Cassandra::Index] current index
62
+ # @return [Cassandra::Table] self
63
+ # @overload each_index
64
+ # @return [Array<Cassandra::Index>] a list of indexes
65
+ def each_index(&block)
66
+ if block_given?
67
+ @indexes.each(&block)
68
+ self
69
+ else
70
+ @indexes.freeze
71
+ end
72
+ end
73
+ alias indexes each_index
74
+
75
+ # @param name [String] trigger name
76
+ # @return [Boolean] whether this table has a given trigger
77
+ def has_trigger?(name)
78
+ @triggers_hash.key?(name)
79
+ end
80
+
81
+ # @param name [String] trigger name
82
+ # @return [Cassandra::Trigger, nil] a trigger or nil
83
+ def trigger(name)
84
+ @triggers_hash[name]
85
+ end
86
+
87
+ # Yield or enumerate each trigger bound to this table
88
+ # @overload each_trigger
89
+ # @yieldparam trigger [Cassandra::Index] current trigger
90
+ # @return [Cassandra::Table] self
91
+ # @overload each_trigger
92
+ # @return [Array<Cassandra::Trigger>] a list of triggers
93
+ def each_trigger(&block)
94
+ if block_given?
95
+ @triggers.each(&block)
96
+ self
97
+ else
98
+ @triggers.freeze
99
+ end
100
+ end
101
+ alias triggers each_trigger
102
+
103
+ # @param name [String] materialized view name
104
+ # @return [Boolean] whether this table has a given materialized view
105
+ def has_materialized_view?(name)
106
+ @materialized_views_hash.key?(name)
107
+ end
108
+
109
+ # @param name [String] materialized view name
110
+ # @return [Cassandra::MaterializedView, nil] a materialized view or nil
111
+ def materialized_view(name)
112
+ @materialized_views_hash[name]
113
+ end
114
+
115
+ # Yield or enumerate each materialized view bound to this table
116
+ # @overload each_materialized_view
117
+ # @yieldparam materialized_view [Cassandra::MaterializedView] current materialized view
118
+ # @return [Cassandra::Table] self
119
+ # @overload each_materialized_view
120
+ # @return [Array<Cassandra::MaterializedView>] a list of materialized views
121
+ def each_materialized_view(&block)
122
+ if block_given?
123
+ @materialized_views.each(&block)
124
+ self
125
+ else
126
+ @materialized_views.freeze
127
+ end
128
+ end
129
+ alias materialized_views each_materialized_view
130
+
131
+ # @return [String] a cql representation of this table
132
+ def to_cql
133
+ cql = "CREATE TABLE #{Util.escape_name(@keyspace.name)}.#{Util.escape_name(@name)} (\n"
134
+ primary_key = @partition_key.first.name if @partition_key.one? && @clustering_columns.empty?
135
+
136
+ first = true
137
+ @columns.each do |column|
138
+ if first
139
+ first = false
140
+ else
141
+ cql << ",\n"
142
+ end
143
+ cql << " #{Util.escape_name(column.name)} #{type_to_cql(column.type, column.frozen?)}"
144
+ cql << ' PRIMARY KEY' if primary_key && column.name == primary_key
145
+ end
146
+
147
+ unless primary_key
148
+ cql << ",\n PRIMARY KEY ("
149
+ if @partition_key.one?
150
+ cql << Util.escape_name(@partition_key.first.name)
151
+ else
152
+ cql << '('
153
+ first = true
154
+ @partition_key.each do |column|
155
+ if first
156
+ first = false
157
+ else
158
+ cql << ', '
159
+ end
160
+ cql << Util.escape_name(column.name)
161
+ end
162
+ cql << ')'
163
+ end
164
+ @clustering_columns.each do |column|
165
+ cql << ", #{Util.escape_name(column.name)}"
166
+ end
167
+ cql << ')'
168
+ end
169
+
170
+ cql << "\n)\nWITH "
171
+
172
+ if !@clustering_order.empty? && !@clustering_columns.empty?
173
+ cql << 'CLUSTERING ORDER BY ('
174
+ first = true
175
+ @clustering_columns.zip(@clustering_order) do |column, order|
176
+ if first
177
+ first = false
178
+ else
179
+ cql << ', '
180
+ end
181
+ cql << "#{Util.escape_name(column.name)} #{order.to_s.upcase}"
182
+ end
183
+ cql << ")\n AND "
184
+ end
185
+
186
+ cql << @options.to_cql.split("\n").join("\n ")
187
+
188
+ cql << ';'
189
+ end
190
+
191
+ # @private
192
+ def add_index(index)
193
+ @indexes << index
194
+ @indexes_hash[index.name] = index
195
+ end
196
+
197
+ # @private
198
+ def add_view(view)
199
+ @materialized_views << view
200
+ @materialized_views_hash[view.name] = view
201
+ end
202
+
203
+ # @private
204
+ def add_trigger(trigger)
205
+ @triggers << trigger
206
+ @triggers_hash[trigger.name] = trigger
207
+ end
208
+
209
+ # @private
210
+ def eql?(other)
211
+ other.is_a?(Table) &&
212
+ super.eql?(other) &&
213
+ @clustering_order == other.clustering_order &&
214
+ @indexes == other.indexes
215
+ end
216
+ alias == eql?
217
+
218
+ private
219
+
220
+ # @private
221
+ def type_to_cql(type, is_frozen)
222
+ case type.kind
223
+ when :tuple
224
+ "frozen <#{type}>"
225
+ when :udt
226
+ if @keyspace.name == type.keyspace
227
+ "frozen <#{Util.escape_name(type.name)}>"
228
+ else
229
+ "frozen <#{Util.escape_name(type.keyspace)}.#{Util.escape_name(type.name)}>"
230
+ end
231
+ else
232
+ if is_frozen
233
+ "frozen <#{type}>"
234
+ else
235
+ type.to_s
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 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
+ # Represents a Cassandra time type.
21
+ class Time
22
+ # @private
23
+ NANOSECONDS_IN_MILISECOND = 1_000_000
24
+ # @private
25
+ NANOSECONDS_IN_SECOND = NANOSECONDS_IN_MILISECOND * 1000
26
+ # @private
27
+ NANOSECONDS_IN_MINUTE = NANOSECONDS_IN_SECOND * 60
28
+ # @private
29
+ NANOSECONDS_IN_HOUR = NANOSECONDS_IN_MINUTE * 60
30
+ # @private
31
+ NANOSECONDS_IN_DAY = NANOSECONDS_IN_HOUR * 24
32
+
33
+ include ::Comparable
34
+
35
+ # @private
36
+ def initialize(nanoseconds = 0)
37
+ if nanoseconds < 0 && nanoseconds > NANOSECONDS_IN_DAY - 1
38
+ raise ::ArgumentError, 'value must be between 0 and ' \
39
+ "#{NANOSECONDS_IN_DAY}, #{value.inspect} given"
40
+ end
41
+
42
+ @nanoseconds = nanoseconds
43
+ end
44
+
45
+ # @return [Integer] an integer between 0 and 24, the number of full hours
46
+ # since midnight that this time represents
47
+ def hours
48
+ @nanoseconds / NANOSECONDS_IN_HOUR
49
+ end
50
+
51
+ # @return [Integer] an integer between 0 and 60, the number of full minutes
52
+ # since the last full hour that this time represents
53
+ def minutes
54
+ (@nanoseconds - (hours * NANOSECONDS_IN_HOUR)) / NANOSECONDS_IN_MINUTE
55
+ end
56
+
57
+ # @return [Integer] an integer between 0 and 60, the number of full seconds
58
+ # since the last full minutes that this time represents
59
+ def seconds
60
+ (@nanoseconds -
61
+ (hours * NANOSECONDS_IN_HOUR) -
62
+ (minutes * NANOSECONDS_IN_MINUTE)) / NANOSECONDS_IN_SECOND
63
+ end
64
+
65
+ # @return [Integer] an integer between 0 and 60, the number of full
66
+ # miliseconds since the last full second that this time represents
67
+ def miliseconds
68
+ (@nanoseconds -
69
+ (hours * NANOSECONDS_IN_HOUR) -
70
+ (minutes * NANOSECONDS_IN_MINUTE) -
71
+ (seconds * NANOSECONDS_IN_SECOND)) / NANOSECONDS_IN_MILISECOND
72
+ end
73
+
74
+ # @return [String] a "%H:%M%S.%3N" formatted time string
75
+ def to_s
76
+ format('%.2d:%.2d:%.2d.%.3d', hours, minutes, seconds, miliseconds)
77
+ end
78
+
79
+ # @return [Integer] an integer between 0 and 86400000000000, the number of
80
+ # nanoseconds since midnight that this time represents
81
+ def to_nanoseconds
82
+ @nanoseconds
83
+ end
84
+
85
+ # @private
86
+ def eql?(other)
87
+ other.is_a?(Time) && other.to_nanoseconds == @nanoseconds
88
+ end
89
+ alias == eql?
90
+
91
+ # @private
92
+ def <=>(other)
93
+ other <=> nanoseconds
94
+ end
95
+
96
+ # @private
97
+ def hash
98
+ # Modeled after http://developer.android.com/reference/java/lang/Object.html#writing_hashCode, but
99
+ # simplified since only one field participates in the hash.
100
+ @hash ||= 31 * 17 + @nanoseconds.hash
101
+ end
102
+ end
103
+ end