tablestore-ruby-sdk 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,217 @@
1
+ require 'consts'
2
+ require 'tablestore/plain_buffer_crc8'
3
+ require 'tablestore/error'
4
+
5
+ class PlainBufferCodedInputStream
6
+ def initialize(input_stream)
7
+ @input_stream = input_stream
8
+ end
9
+
10
+ def read_tag
11
+ @input_stream.read_tag
12
+ end
13
+
14
+ def check_last_tag_was(tag)
15
+ @input_stream.check_last_tag_was(tag)
16
+ end
17
+
18
+ def get_last_tag
19
+ @input_stream.get_last_tag
20
+ end
21
+
22
+ def read_header
23
+ @input_stream.read_int32
24
+ end
25
+
26
+ def read_primary_key_value(cell_check_sum)
27
+ raise TableStoreClientError.new("Expect TAG_CELL_VALUE but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL_VALUE)
28
+ @input_stream.read_raw_little_endian32
29
+ column_type = @input_stream.read_raw_byte.ord
30
+ if column_type == VT_INTEGER
31
+ int64_value = @input_stream.read_int64
32
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INTEGER)
33
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, int64_value)
34
+ read_tag
35
+ return int64_value, cell_check_sum
36
+ elsif column_type == VT_STRING
37
+ value_size = @input_stream.read_int32
38
+ string_value = @input_stream.read_utf_string(value_size)
39
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_STRING)
40
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value_size)
41
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, string_value)
42
+ read_tag
43
+ return string_value, cell_check_sum
44
+ elsif column_type == VT_BLOB
45
+ value_size = @input_stream.read_int32
46
+ binary_value = @input_stream.read_bytes(value_size)
47
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_BLOB)
48
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value_size)
49
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, binary_value)
50
+ read_tag
51
+ return [binary_value], cell_check_sum
52
+ else
53
+ raise TableStoreClientError.new("Unsupported primary key type:" + column_type.to_s)
54
+ end
55
+ end
56
+
57
+ def read_column_value(cell_check_sum)
58
+ raise TableStoreClientError.new("Expect TAG_CELL_VALUE but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL_VALUE)
59
+ @input_stream.read_raw_little_endian32
60
+ column_type = @input_stream.read_raw_byte.ord
61
+ if column_type == VT_INTEGER
62
+ int64_value = @input_stream.read_int64
63
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INTEGER)
64
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, int64_value)
65
+ read_tag
66
+ return int64_value, cell_check_sum
67
+ elsif column_type == VT_STRING
68
+ value_size = @input_stream.read_int32
69
+ string_value = @input_stream.read_utf_string(value_size)
70
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_STRING)
71
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value_size)
72
+ cell_check_sum =PlainBufferCrc8.crc_string(cell_check_sum, string_value)
73
+ read_tag
74
+ return string_value, cell_check_sum
75
+ elsif column_type == VT_BLOB
76
+ value_size = @input_stream.read_int32
77
+ binary_value = @input_stream.read_bytes(value_size)
78
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_BLOB)
79
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value_size)
80
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, binary_value)
81
+ read_tag
82
+ return binary_value, cell_check_sum
83
+ elsif column_type == VT_BOOLEAN
84
+ bool_value = @input_stream.read_boolean
85
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_BOOLEAN)
86
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, bool_value ? 1 : 0)
87
+ read_tag
88
+ return bool_value, cell_check_sum
89
+ elsif column_type == VT_DOUBLE
90
+ double_int = @input_stream.read_int64
91
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_DOUBLE)
92
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, double_int)
93
+ read_tag
94
+
95
+ if SYS_BITS == 64
96
+ double_value, = [double_int].pack('q').unpack('d')
97
+ else
98
+ double_value, = [double_int].pack('l').unpack('d')
99
+ end
100
+ return double_value, cell_check_sum
101
+ else
102
+ raise TableStoreClientError.new("Unsupported column type: " + column_type.str)
103
+ end
104
+ end
105
+
106
+ def read_primary_key_column(row_check_sum)
107
+ raise TableStoreClientError.new("Expect TAG_CELL but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL)
108
+ read_tag
109
+ raise TableStoreClientError.new("Expect TAG_CELL_NAME but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL_NAME)
110
+ cell_check_sum = 0
111
+ name_size = @input_stream.read_raw_little_endian32
112
+ column_name = @input_stream.read_utf_string(name_size)
113
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, column_name)
114
+ read_tag
115
+ raise TableStoreClientError.new("Expect TAG_CELL_VALUE but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL_VALUE)
116
+ primary_key_value, cell_check_sum = read_primary_key_value(cell_check_sum)
117
+ if @input_stream.get_last_tag == TAG_CELL_CHECKSUM
118
+ check_sum = @input_stream.read_raw_byte.ord
119
+ raise TableStoreClientError.new("Checksum mismatch. expected:" + check_sum.to_s + ",actual:" + cell_check_sum.to_s) if check_sum != cell_check_sum
120
+ read_tag
121
+ else
122
+ raise TableStoreClientError.new("Expect TAG_CELL_CHECKSUM but it was " + get_last_tag.to_s)
123
+ end
124
+ row_check_sum = PlainBufferCrc8.crc_int8(row_check_sum, cell_check_sum)
125
+ return column_name, primary_key_value, row_check_sum
126
+ end
127
+
128
+ def read_column(row_check_sum)
129
+ raise TableStoreClientError.new("Expect TAG_CELL but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL)
130
+ read_tag
131
+ raise TableStoreClientError.new("Expect TAG_CELL_NAME but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_CELL_NAME)
132
+
133
+ cell_check_sum = 0
134
+ column_value = nil
135
+ timestamp = nil
136
+ name_size = @input_stream.read_raw_little_endian32
137
+ column_name = @input_stream.read_utf_string(name_size)
138
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, column_name)
139
+ read_tag
140
+ if get_last_tag == TAG_CELL_VALUE
141
+ column_value, cell_check_sum = read_column_value(cell_check_sum)
142
+ end
143
+ # skip CELL_TYPE
144
+ if get_last_tag == TAG_CELL_TYPE
145
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, cell_type)
146
+ read_tag
147
+ end
148
+ if get_last_tag == TAG_CELL_TIMESTAMP
149
+ timestamp = @input_stream.read_int64
150
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, timestamp)
151
+ read_tag
152
+ end
153
+ if get_last_tag == TAG_CELL_CHECKSUM
154
+ check_sum = @input_stream.read_raw_byte.ord
155
+ raise TableStoreClientError.new("Checksum mismatch. expected:" + check_sum.to_s + ",actual:" + cell_check_sum.to_s) if check_sum != cell_check_sum
156
+ read_tag
157
+ else
158
+ raise TableStoreClientError.new("Expect TAG_CELL_CHECKSUM but it was " + get_last_tag.to_s)
159
+ end
160
+ row_check_sum = PlainBufferCrc8.crc_int8(row_check_sum, cell_check_sum)
161
+ return column_name, column_value, timestamp, row_check_sum
162
+ end
163
+
164
+ def read_row_without_header
165
+ row_check_sum = 0
166
+ primary_key = {}
167
+ attributes = {}
168
+
169
+ raise TableStoreClientError.new("Expect TAG_ROW_PK but it was " + get_last_tag.to_s) unless check_last_tag_was(TAG_ROW_PK)
170
+
171
+ read_tag
172
+ while check_last_tag_was(TAG_CELL)
173
+ name, value, row_check_sum = read_primary_key_column(row_check_sum)
174
+ primary_key[name] = value
175
+ end
176
+ if check_last_tag_was(TAG_ROW_DATA)
177
+ read_tag
178
+ while check_last_tag_was(TAG_CELL)
179
+ column_name, column_value, timestamp, row_check_sum = read_column(row_check_sum)
180
+ attributes[column_name] = column_value
181
+ end
182
+ end
183
+ if check_last_tag_was(TAG_DELETE_ROW_MARKER)
184
+ read_tag
185
+ row_check_sum = PlainBufferCrc8.crc_int8(row_check_sum, 1)
186
+ else
187
+ row_check_sum = PlainBufferCrc8.crc_int8(row_check_sum, 0)
188
+ end
189
+
190
+ if check_last_tag_was(TAG_ROW_CHECKSUM)
191
+ check_sum = @input_stream.read_raw_byte.ord
192
+ raise TableStoreClientError.new("Checksum is mismatch.") if check_sum != row_check_sum
193
+ read_tag
194
+ else
195
+ raise TableStoreClientError.new("Expect TAG_ROW_CHECKSUM but it was " + get_last_tag.to_s)
196
+ end
197
+ return primary_key, attributes
198
+ end
199
+
200
+ def read_row
201
+ raise TableStoreClientError.new("Invalid header from plain buffer.") if read_header != HEADER
202
+ read_tag
203
+ read_row_without_header
204
+ end
205
+
206
+ def read_rows
207
+ raise TableStoreClientError("Invalid header from plain buffer.") if read_header != HEADER
208
+ read_tag
209
+ row_list = []
210
+ while !@input_stream.is_at_end?
211
+ pk, attr = read_row_without_header
212
+ row_list << {pk:pk, attr: attr}
213
+ end
214
+ row_list
215
+ end
216
+
217
+ end
@@ -0,0 +1,252 @@
1
+ require 'consts'
2
+ require 'tablestore/plain_buffer_crc8'
3
+ require 'tablestore/error'
4
+
5
+ class PlainBufferCodedOutputStream
6
+
7
+ def initialize(output_stream)
8
+ @output_stream = output_stream
9
+ end
10
+
11
+ def write_header
12
+ @output_stream.write_raw_little_endian32(HEADER)
13
+ end
14
+
15
+ def write_tag(tag)
16
+ @output_stream.write_raw_byte(tag)
17
+ end
18
+
19
+ def write_cell_name(name, cell_check_sum)
20
+ write_tag(TAG_CELL_NAME)
21
+ @output_stream.write_raw_little_endian32(name.length)
22
+ @output_stream.write_bytes(name)
23
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, name)
24
+ cell_check_sum
25
+ end
26
+
27
+ def write_primary_key_value(value, cell_check_sum)
28
+ write_tag(TAG_CELL_VALUE)
29
+ value = value.to_s.split("::").last if [Metadata::INF_MAX, Metadata::INF_MIN, Metadata::PK_AUTO_INCR].include?value
30
+ if value == "INF_MIN"
31
+ @output_stream.write_raw_little_endian32(1)
32
+ @output_stream.write_raw_byte(VT_INF_MIN)
33
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INF_MIN)
34
+ elsif value == "INF_MAX"
35
+ @output_stream.write_raw_little_endian32(1)
36
+ @output_stream.write_raw_byte(VT_INF_MAX)
37
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INF_MAX)
38
+ elsif value == "PK_AUTO_INCR"
39
+ @output_stream.write_raw_little_endian32(1)
40
+ @output_stream.write_raw_byte(VT_AUTO_INCREMENT)
41
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_AUTO_INCREMENT)
42
+ elsif value.is_a?(Fixnum)
43
+ @output_stream.write_raw_little_endian32(1 + LITTLE_ENDIAN_64_SIZE)
44
+ @output_stream.write_raw_byte(VT_INTEGER)
45
+ @output_stream.write_raw_little_endian64(value)
46
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INTEGER)
47
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, value)
48
+ elsif value.is_a?(String)
49
+ prefix_length = LITTLE_ENDIAN_32_SIZE + 1
50
+ @output_stream.write_raw_little_endian32(prefix_length + value.length)
51
+ @output_stream.write_raw_byte(VT_STRING)
52
+ @output_stream.write_raw_little_endian32(value.length)
53
+ @output_stream.write_bytes(value)
54
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_STRING)
55
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value.length)
56
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, value)
57
+ # elsif value.is_a?()
58
+ else
59
+ raise TableStoreClientError.new("Unsupported primary key type: " + value.class)
60
+ end
61
+ cell_check_sum
62
+ end
63
+
64
+ def write_column_value_with_checksum(value, cell_check_sum)
65
+ write_tag(TAG_CELL_VALUE)
66
+ if value.is_a?(TrueClass) || value.is_a?(FalseClass)
67
+ @output_stream.write_raw_little_endian32(2)
68
+ @output_stream.write_raw_byte(VT_BOOLEAN)
69
+ @output_stream.write_boolean(value)
70
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_BOOLEAN)
71
+ if value
72
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, 1)
73
+ else
74
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, 0)
75
+ end
76
+ elsif value.is_a?(Fixnum)
77
+ @output_stream.write_raw_little_endian32(1 + LITTLE_ENDIAN_64_SIZE)
78
+ @output_stream.write_raw_byte(VT_INTEGER)
79
+ @output_stream.write_raw_little_endian64(value)
80
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_INTEGER)
81
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, value)
82
+ elsif value.is_a?(String)
83
+ prefix_length = LITTLE_ENDIAN_32_SIZE + 1
84
+ @output_stream.write_raw_little_endian32(prefix_length + value.length)
85
+ @output_stream.write_raw_byte(VT_STRING)
86
+ @output_stream.write_raw_little_endian32(value.length)
87
+ @output_stream.write_bytes(value)
88
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_STRING)
89
+ cell_check_sum = PlainBufferCrc8.crc_int32(cell_check_sum, value.length)
90
+ cell_check_sum = PlainBufferCrc8.crc_string(cell_check_sum, value)
91
+ elsif value.is_a?(Float)
92
+ if SYS_BITS == 64
93
+ double_in_long, = [value].pack("d").unpack("q")
94
+ else
95
+ double_in_long, = [value].pack("d").unpack("l")
96
+ end
97
+ @output_stream.write_raw_little_endian32(1 + LITTLE_ENDIAN_64_SIZE)
98
+ @output_stream.write_raw_byte(VT_DOUBLE)
99
+ @output_stream.write_double(value)
100
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, VT_DOUBLE)
101
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, double_in_long)
102
+ else
103
+ raise TableStoreClientError.new("Unsupported column type: " + value.class)
104
+ end
105
+ cell_check_sum
106
+ end
107
+
108
+ def write_column_value(value)
109
+ if value.is_a?(TrueClass) || value.is_a?(FalseClass)
110
+ @output_stream.write_raw_byte(VT_BOOLEAN)
111
+ elsif value.is_a?(Fixnum)
112
+ @output_stream.write_raw_byte(VT_INTEGER)
113
+ @output_stream.write_raw_little_endian64(value)
114
+ elsif value.is_a?(String)
115
+ @output_stream.write_raw_byte(VT_STRING)
116
+ @output_stream.write_raw_little_endian32(value.length)
117
+ @output_stream.write_bytes(value)
118
+ elsif value.is_a?(Float)
119
+ @output_stream.write_raw_byte(VT_DOUBLE)
120
+ @output_stream.write_double(value)
121
+ else
122
+ raise TableStoreClientError.new("Unsupported column type: " + value.class)
123
+ end
124
+ end
125
+
126
+ def write_primary_key_column(pk_name, pk_value, row_check_sum)
127
+ cell_check_sum = 0
128
+ write_tag(TAG_CELL)
129
+ cell_check_sum = write_cell_name(pk_name, cell_check_sum)
130
+ cell_check_sum = write_primary_key_value(pk_value, cell_check_sum)
131
+ write_tag(TAG_CELL_CHECKSUM)
132
+ @output_stream.write_raw_byte(cell_check_sum)
133
+ row_check_sum = PlainBufferCrc8.crc_int8(row_check_sum, cell_check_sum)
134
+ row_check_sum
135
+ end
136
+
137
+ def write_column(column_name, column_value, timestamp, row_check_sum)
138
+ cell_check_sum = 0
139
+ write_tag(TAG_CELL)
140
+ cell_check_sum = write_cell_name(column_name, cell_check_sum)
141
+ cell_check_sum = write_column_value_with_checksum(column_value, cell_check_sum)
142
+
143
+ unless timestamp.nil?
144
+ write_tag(TAG_CELL_TIMESTAMP)
145
+ @output_stream.write_raw_little_endian64(timestamp)
146
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, timestamp)
147
+ end
148
+ write_tag(TAG_CELL_CHECKSUM)
149
+ @output_stream.write_raw_byte(cell_check_sum)
150
+ PlainBufferCrc8.crc_int8(row_check_sum, cell_check_sum)
151
+ end
152
+
153
+ def write_update_column(update_type, column_name, column_value, row_check_sum)
154
+ update_type = update_type.upcase
155
+ cell_check_sum = 0
156
+ write_tag(TAG_CELL)
157
+ cell_check_sum = write_cell_name(column_name, cell_check_sum)
158
+ timestamp = nil
159
+ if column_value.present?
160
+ if column_value.is_a?(Array)
161
+ if column_value[0].present?
162
+ cell_check_sum = write_column_value_with_checksum(column_value[0], cell_check_sum)
163
+ end
164
+ if column_value[1].present?
165
+ timestamp = column_value[1]
166
+ end
167
+ else
168
+ cell_check_sum = write_column_value_with_checksum(column_value, cell_check_sum)
169
+ end
170
+ end
171
+ if update_type == UpdateType.DELETE
172
+ write_tag(TAG_CELL_TYPE)
173
+ @output_stream.write_raw_byte(const.DELETE_ONE_VERSION)
174
+ elsif update_type == UpdateType.DELETE_ALL
175
+ write_tag(TAG_CELL_TYPE)
176
+ @output_stream.write_raw_byte(const.DELETE_ALL_VERSION)
177
+ end
178
+ if timestamp.present?
179
+ write_tag(TAG_CELL_TIMESTAMP)
180
+ @output_stream.write_raw_little_endian64(timestamp)
181
+ end
182
+ if timestamp.present?
183
+ cell_check_sum = PlainBufferCrc8.crc_int64(cell_check_sum, timestamp)
184
+ end
185
+ if update_type == UpdateType.DELETE
186
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, const.DELETE_ONE_VERSION)
187
+ end
188
+ if update_type == UpdateType.DELETE_ALL
189
+ cell_check_sum = PlainBufferCrc8.crc_int8(cell_check_sum, const.DELETE_ALL_VERSION)
190
+ end
191
+ write_tag(TAG_CELL_CHECKSUM)
192
+ @output_stream.write_raw_byte(cell_check_sum)
193
+ PlainBufferCrc8.crc_int8(row_check_sum, cell_check_sum)
194
+ end
195
+
196
+ def write_primary_key(primary_key, row_check_sum)
197
+ write_tag(TAG_ROW_PK)
198
+ primary_key.each do |pk|
199
+ row_check_sum = write_primary_key_column(pk[0], pk[1], row_check_sum)
200
+ end
201
+ row_check_sum
202
+ end
203
+
204
+ def write_columns(columns, row_check_sum)
205
+ if columns.present? and columns.length != 0
206
+ write_tag(TAG_ROW_DATA)
207
+ columns.each do |column|
208
+ if column.length == 2
209
+ row_check_sum = write_column(column[0], column[1], nil, row_check_sum)
210
+ elsif column.length == 3
211
+ row_check_sum = write_column(column[0], column[1], column[2], row_check_sum)
212
+ end
213
+ end
214
+ row_check_sum
215
+ end
216
+ end
217
+
218
+ def write_update_columns( attribute_columns, row_check_sum)
219
+ if attribute_columns.length != 0
220
+ write_tag(TAG_ROW_DATA)
221
+ attribute_columns.keys.each do |update_type|
222
+ columns = attribute_columns[update_type]
223
+ columns.each do |column|
224
+ if column.is_a?(String)
225
+ row_check_sum = write_update_column(update_type, column, nil, row_check_sum)
226
+ elsif column.length == 2
227
+ row_check_sum = write_update_column(update_type, column[0], [column[1], nil], row_check_sum)
228
+ elsif column.length == 3
229
+ row_check_sum = write_update_column(update_type, column[0], [column[1], column[2]], row_check_sum)
230
+ else
231
+ raise TableStoreClientError.new("Unsupported column format: " + column.to_s)
232
+ end
233
+ end
234
+ end
235
+ end
236
+ row_check_sum
237
+ end
238
+
239
+ def write_delete_marker(row_checksum)
240
+ write_tag(TAG_DELETE_ROW_MARKER)
241
+ PlainBufferCrc8.crc_int8(row_checksum, 1)
242
+ end
243
+
244
+ def write_row_checksum(row_checksum)
245
+ write_tag(TAG_ROW_CHECKSUM)
246
+ @output_stream.write_raw_byte(row_checksum)
247
+ end
248
+
249
+ def crc_int8(row_checksum, data)
250
+ PlainBufferCrc8.crc_int8(row_checksum, data)
251
+ end
252
+ end