tablestore-ruby-sdk 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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