rocksdb-ruby 0.2.3 → 1.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.
@@ -3,8 +3,15 @@ require "mkmf"
3
3
  dir_config('rocksdb')
4
4
  RbConfig::CONFIG["CPP"] = "g++ -E -std=gnu++11"
5
5
 
6
- if have_header('rocksdb/db.h') and have_library('rocksdb')
6
+ DEBUG_BUILD = have_library('rocksdb_debug') || ENV["DEBUG_LEVEL"]
7
+
8
+ if have_header('rocksdb/db.h') and (have_library('rocksdb') or have_library('rocksdb_debug'))
7
9
  $CPPFLAGS << " -std=gnu++11"
10
+
11
+ if DEBUG_BUILD
12
+ CONFIG["optflags"] = "-O0"
13
+ end
14
+
8
15
  create_makefile("RocksDB/RocksDB")
9
16
  else
10
17
  abort "can't find header or library of rocksdb"
@@ -12,6 +12,7 @@ extern "C" {
12
12
  VALUE rocksdb_write_batch_init(){
13
13
  return Qtrue;
14
14
  }
15
+
15
16
  VALUE rocksdb_write_batch_put(VALUE self, VALUE v_key, VALUE v_value){
16
17
  Check_Type(v_key, T_STRING);
17
18
  Check_Type(v_value, T_STRING);
@@ -19,17 +20,18 @@ extern "C" {
19
20
  rocksdb::WriteBatch *batch;
20
21
  std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
21
22
  std::string value = std::string((char*)RSTRING_PTR(v_value), RSTRING_LEN(v_value));
22
-
23
+
23
24
  Data_Get_Struct(self, rocksdb::WriteBatch, batch);
24
25
  batch->Put(key, value);
25
26
  return Qnil;
26
27
  }
28
+
27
29
  VALUE rocksdb_write_batch_delete(VALUE self, VALUE v_key){
28
30
  Check_Type(v_key, T_STRING);
29
31
 
30
32
  rocksdb::WriteBatch *batch;
31
33
  std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
32
-
34
+
33
35
  Data_Get_Struct(self, rocksdb::WriteBatch, batch);
34
36
  batch->Delete(key);
35
37
 
@@ -4,7 +4,7 @@
4
4
  extern "C" {
5
5
 
6
6
  #include <ruby.h>
7
-
7
+
8
8
  typedef VALUE (*METHOD)(...);
9
9
 
10
10
  VALUE rocksdb_write_batch_init();
@@ -6,35 +6,36 @@
6
6
  extern "C" {
7
7
  #include <ruby.h>
8
8
 
9
- VALUE rocksdb_db_init(int argc, VALUE* argv, VALUE self) {
10
- VALUE v_db_file_name;
11
- VALUE v_options;
9
+ VALUE rocksdb_db_init(VALUE self, VALUE v_db_path, VALUE v_readonly, VALUE v_db_options) {
12
10
  rocksdb_pointer* db_pointer;
13
11
  rocksdb::DB* db;
14
12
  rocksdb::Options options;
15
13
  rocksdb::Status status;
14
+
16
15
  std::string db_file_name;
17
- bool readonly;
18
-
16
+ std::string db_string_options;
17
+
19
18
  Data_Get_Struct(self, rocksdb_pointer, db_pointer);
20
- rb_scan_args(argc, argv, "11", &v_db_file_name, &v_options);
21
19
 
22
- Check_Type(v_db_file_name, T_STRING);
23
- db_file_name = std::string((char*)RSTRING_PTR(v_db_file_name));
20
+ // Initialize db_pointer
21
+ db_pointer->db = nullptr;
22
+ db_pointer->readonly = false;
24
23
 
25
- readonly = false;
26
- if (TYPE(v_options) == T_HASH) {
27
- VALUE v = rb_hash_aref(v_options, ID2SYM(rb_intern("readonly")));
28
- if(v == Qtrue){
29
- readonly = true;
30
- }
31
- set_opt(&options, &v_options);
32
- }
33
- //std::cout << options.max_bytes_for_level_base << "\n";
34
- //std::cout << options.max_grandparent_overlap_factor << "\n";
35
- //std::cout << options.delete_obsolete_files_period_micros << "\n";
24
+ bool readonly = RTEST(v_readonly);
36
25
 
26
+ db_file_name = STRING_FROM_RB_VALUE(v_db_path);
27
+ db_string_options = STRING_FROM_RB_VALUE(v_db_options);
28
+
29
+ // Set option before parsing string, so create_if_missing could be
30
+ // overwriten in option string
37
31
  options.create_if_missing = true;
32
+ status = GetOptionsFromString(options, db_string_options, &options);
33
+
34
+ if(!status.ok()) {
35
+ raise_status_error(&status);
36
+ return Qnil;
37
+ }
38
+
38
39
  if(readonly){
39
40
  status = rocksdb::DB::OpenForReadOnly(options, db_file_name, &db);
40
41
  }else{
@@ -43,337 +44,287 @@ extern "C" {
43
44
 
44
45
  db_pointer->db = db;
45
46
  db_pointer->readonly = readonly;
46
-
47
- return status.ok() ? Qtrue : Qfalse;
48
- }
49
- VALUE rocksdb_db_init2(int argc, VALUE* argv, VALUE self) {
50
- rocksdb_pointer* db_pointer;
51
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
52
- db_pointer->db = NULL;
53
- db_pointer->readonly = true;
54
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
47
+
48
+ if(!status.ok()) {
49
+ raise_status_error(&status);
50
+ return Qnil;
51
+ }
55
52
 
56
53
  return Qtrue;
57
54
  }
58
55
 
59
- void set_opt_unit_val(uint64_t* opt, char* name, VALUE *v_options){
56
+ VALUE db_alloc(VALUE klass){
57
+ rocksdb_pointer* db_pointer = ALLOC(rocksdb_pointer);
58
+ return Data_Wrap_Struct(klass, 0, db_free, db_pointer);
59
+ }
60
60
 
61
- VALUE v2 = rb_hash_aref(*v_options, ID2SYM(rb_intern(name)));
62
- if(RB_TYPE_P(v2, T_FIXNUM)){
63
- *opt = NUM2INT(v2);
61
+ void db_free(rocksdb_pointer* db_pointer){
62
+ if(db_pointer == nullptr) {
63
+ return;
64
64
  }
65
- }
66
- void set_opt_int_val(int* opt, char* name, VALUE *v_options){
67
- VALUE v2 = rb_hash_aref(*v_options, ID2SYM(rb_intern(name)));
68
- if(RB_TYPE_P(v2, T_FIXNUM)){
69
- *opt = NUM2INT(v2);
65
+
66
+ if(db_pointer->db != nullptr){
67
+ delete db_pointer->db;
68
+ db_pointer->db = nullptr;
70
69
  }
71
- }
72
70
 
73
- void set_opt(rocksdb::Options* options, VALUE *v_options){
74
- set_opt_unit_val(&options->max_bytes_for_level_base, (char *) "max_bytes_for_level_base", v_options);
75
- set_opt_unit_val(&options->delete_obsolete_files_period_micros, (char *) "delete_obsolete_files_period_micros", v_options);
76
- set_opt_int_val(&options->max_open_files, (char *) "max_open_files", v_options);
71
+ delete db_pointer;
72
+ db_pointer = nullptr;
77
73
  }
78
74
 
79
- VALUE db_alloc(VALUE klass){
80
- rocksdb_pointer* db_pointer = ALLOC(rocksdb_pointer);
81
- return Data_Wrap_Struct(klass, 0, db_free, db_pointer);
75
+ VALUE rocksdb_db_close(VALUE self){
76
+ rocksdb_pointer* db_pointer = get_db(&self);
77
+
78
+ if(db_pointer == nullptr) {
79
+ return Qfalse;
80
+ }
81
+
82
+ if(db_pointer->db != nullptr){
83
+ delete db_pointer->db;
84
+ db_pointer->db = nullptr;
85
+ }
86
+
87
+ return Qtrue;
82
88
  }
83
89
 
84
90
  VALUE rocksdb_db_put(VALUE self, VALUE v_key, VALUE v_value) {
85
- Check_Type(v_key, T_STRING);
86
- Check_Type(v_value, T_STRING);
91
+ rocksdb_pointer* db_pointer = get_db_for_write(&self);
87
92
 
88
- rocksdb_pointer* db_pointer;
89
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
90
-
91
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
92
- std::string value = std::string((char*)RSTRING_PTR(v_value), RSTRING_LEN(v_value));
93
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
94
+ std::string value = STRING_FROM_RB_VALUE(v_value);
93
95
 
94
- if (db_pointer->db == NULL) {
95
- rb_raise(rb_eRuntimeError, "db not open");
96
- }
97
- if (db_pointer->readonly) {
98
- rb_raise(rb_eRuntimeError, "readonly");
99
- }
100
96
  rocksdb::Status status = db_pointer->db->Put(rocksdb::WriteOptions(), key, value);
101
-
102
- return status.ok() ? Qtrue : Qfalse;
97
+
98
+ if(!status.ok()) {
99
+ raise_status_error(&status);
100
+ return Qnil;
101
+ }
102
+
103
+ return Qtrue;
103
104
  }
104
105
 
105
106
  VALUE rocksdb_db_write(VALUE self, VALUE v_write){
106
- rocksdb_pointer* db_pointer;
107
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
107
+ rocksdb_pointer* db_pointer = get_db_for_write(&self);
108
108
 
109
109
  rocksdb::WriteBatch *batch;
110
110
  Data_Get_Struct(v_write, rocksdb::WriteBatch, batch);
111
111
 
112
- if (db_pointer->db == NULL) {
113
- rb_raise(rb_eRuntimeError, "db not open");
114
- }
115
- if (db_pointer->readonly) {
116
- rb_raise(rb_eRuntimeError, "readonly");
117
- }
118
112
  rocksdb::Status status = db_pointer->db->Write(rocksdb::WriteOptions(), batch);
119
- return status.ok() ? Qtrue : Qfalse;
113
+
114
+ if(!status.ok()) {
115
+ raise_status_error(&status);
116
+ return Qnil;
117
+ }
118
+
119
+ return Qtrue;
120
120
  }
121
121
 
122
122
  VALUE rocksdb_db_property(VALUE self, VALUE v_key){
123
- Check_Type(v_key, T_STRING);
123
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
124
124
 
125
- rocksdb_pointer* db_pointer;
126
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
125
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
126
+ std::string value = std::string();
127
127
 
128
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
129
- std::string value;
130
- if (db_pointer->db == NULL) {
131
- rb_raise(rb_eRuntimeError, "db not open");
132
- }
128
+ bool result_ok = db_pointer->db->GetProperty(key, &value);
129
+
130
+ if(!result_ok) return Qnil;
131
+ return SLICE_TO_RB_STRING(value);
132
+ }
133
+
134
+ VALUE rocksdb_db_options(VALUE self){
135
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
136
+
137
+ VALUE v_result = rb_hash_new();
138
+ VALUE v_key = Qnil;
139
+ VALUE v_value = Qnil;
140
+
141
+ std::string options_str;
142
+ std::unordered_map<std::string, std::string> options_map;
133
143
 
134
- bool status = db_pointer->db->GetProperty(key, &value);
135
- if(!status) return Qnil;
136
- return rb_enc_str_new(value.data(), value.size(), rb_utf8_encoding());
144
+ GetStringFromDBOptions(&options_str, db_pointer->db->GetOptions());
145
+
146
+ v_key = rb_str_new_cstr("DBOptions");
147
+ v_value = rb_str_new_cstr(options_str.c_str());
148
+ rb_hash_aset(v_result, v_key, v_value);
149
+
150
+ GetStringFromColumnFamilyOptions(&options_str, db_pointer->db->GetOptions());
151
+
152
+ v_key = rb_str_new_cstr("CFOptions");
153
+ v_value = rb_str_new_cstr(options_str.c_str());
154
+ rb_hash_aset(v_result, v_key, v_value);
155
+
156
+ return v_result;
137
157
  }
138
158
 
139
159
  VALUE rocksdb_db_get(VALUE self, VALUE v_key){
140
- Check_Type(v_key, T_STRING);
160
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
141
161
 
142
- rocksdb_pointer* db_pointer;
143
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
144
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
162
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
145
163
  std::string value;
146
- if (db_pointer->db == NULL) {
147
- rb_raise(rb_eRuntimeError, "db not open");
148
- }
149
- rocksdb::Status status = db_pointer->db->Get(rocksdb::ReadOptions(), key, &value);
150
164
 
151
- return (status.IsNotFound()) ? Qnil : rb_enc_str_new(value.data(), value.size(), rb_utf8_encoding());
165
+ rocksdb::Status status = db_pointer->db->Get(rocksdb::ReadOptions(), key, &value);
152
166
 
153
- }
167
+ if(status.IsNotFound()) {
168
+ return Qnil;
169
+ } else if (!status.ok()) {
170
+ raise_status_error(&status);
171
+ return Qnil;
172
+ }
154
173
 
174
+ return SLICE_TO_RB_STRING(value);
175
+ }
155
176
 
156
177
  VALUE rocksdb_db_multi_get(VALUE self, VALUE v_array){
157
178
  Check_Type(v_array, T_ARRAY);
158
179
 
159
- rocksdb_pointer* db_pointer;
160
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
180
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
161
181
 
162
182
  long i;
163
183
  long length = RARRAY_LEN(v_array);
164
184
  std::vector<std::string> values(length);
165
185
  std::vector<rocksdb::Slice> keys(length);
166
- std::vector<rocksdb::Status> status;
186
+ std::vector<rocksdb::Status> statuses;
167
187
 
168
188
  for(i=0; i < length; i++){
169
- VALUE op = rb_ary_entry(v_array, i);
170
- keys[i] = rocksdb::Slice((char*)RSTRING_PTR(op), RSTRING_LEN(op));
189
+ VALUE v_element = rb_ary_entry(v_array, i);
190
+ keys[i] = SLICE_FROM_RB_VALUE(v_element);
171
191
  }
172
192
 
173
- if (db_pointer->db == NULL) {
174
- rb_raise(rb_eRuntimeError, "db not open");
175
- }
176
- status = db_pointer->db->MultiGet(rocksdb::ReadOptions(),keys,&values);
193
+ statuses = db_pointer->db->MultiGet(rocksdb::ReadOptions(), keys, &values);
194
+
177
195
  for(i=0; i < length; i++){
178
- rb_ary_store(v_array, i, rb_enc_str_new(values[i].data(), values[i].size(), rb_utf8_encoding()));
196
+ rocksdb::Status status = statuses[i];
197
+
198
+ if(status.IsNotFound()) {
199
+ rb_ary_store(v_array, i, Qnil);
200
+ } else if(status.ok()) {
201
+ rb_ary_store(v_array, i, SLICE_TO_RB_STRING(values[i]));
202
+ } else {
203
+ rb_ary_store(v_array, i, Qfalse);
204
+ }
179
205
  }
206
+
180
207
  return v_array;
181
208
  }
182
-
209
+
183
210
  VALUE rocksdb_db_delete(VALUE self, VALUE v_key){
184
- Check_Type(v_key, T_STRING);
185
-
186
- rocksdb_pointer* db_pointer;
187
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
211
+ rocksdb_pointer* db_pointer = get_db_for_write(&self);
188
212
 
189
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
190
- if (db_pointer->db == NULL) {
191
- rb_raise(rb_eRuntimeError, "db not open");
192
- }
193
- if (db_pointer->readonly) {
194
- rb_raise(rb_eRuntimeError, "readonly");
195
- }
213
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
196
214
  rocksdb::Status status = db_pointer->db->Delete(rocksdb::WriteOptions(), key);
197
-
198
- return status.ok() ? Qtrue : Qfalse;
215
+
216
+ // https://github.com/facebook/rocksdb/issues/4975
217
+ if (status.ok()) {
218
+ return Qtrue;
219
+ } else {
220
+ raise_status_error(&status);
221
+ return Qfalse;
222
+ }
199
223
  }
200
224
 
201
225
  VALUE rocksdb_db_exists(VALUE self, VALUE v_key){
202
- Check_Type(v_key, T_STRING);
203
-
204
- rocksdb_pointer* db_pointer;
205
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
226
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
206
227
 
207
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
228
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
208
229
  std::string value = std::string();
209
-
210
- if (db_pointer->db == NULL) {
211
- rb_raise(rb_eRuntimeError, "db not open");
212
- }
213
- return db_pointer->db->KeyMayExist(rocksdb::ReadOptions(), key, &value) ? Qtrue : Qfalse;
214
- }
215
230
 
216
- VALUE rocksdb_db_close(VALUE self){
217
- rocksdb_pointer* db_pointer;
218
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
219
-
220
- if(db_pointer->db != NULL){
221
- delete db_pointer->db;
222
- db_pointer->db = NULL;
223
- }
224
- return Qnil;
231
+ return db_pointer->db->KeyMayExist(rocksdb::ReadOptions(), key, &value) ? Qtrue : Qfalse;
225
232
  }
226
233
 
227
- void db_free(rocksdb_pointer* db_pointer){
228
- if(db_pointer->db != NULL){
229
- delete db_pointer->db;
230
- db_pointer->db = NULL;
231
- }
232
- delete db_pointer;
233
- }
234
234
 
235
- VALUE rocksdb_db_new_iterator(VALUE self){
236
- rocksdb_pointer* db_pointer;
235
+ VALUE rocksdb_db_to_iterator(VALUE self){
236
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
237
237
  rocksdb_iterator_pointer* rocksdb_it;
238
238
 
239
- VALUE klass;
240
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
241
-
242
- if (db_pointer->db == NULL) {
243
- rb_raise(rb_eRuntimeError, "db not open");
244
- }
245
239
  rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
246
240
 
241
+ VALUE klass;
247
242
  klass = rb_class_new_instance(0, NULL, cRocksdb_iterator);
248
243
 
249
244
  Data_Get_Struct(klass, rocksdb_iterator_pointer , rocksdb_it);
250
245
  rocksdb_it->it = it;
246
+ rocksdb_it->db_pointer = db_pointer;
247
+
251
248
  return klass;
252
249
  }
253
250
 
254
-
255
- VALUE rocksdb_db_each(VALUE self){
256
- if(!rb_block_given_p()){
257
- return rocksdb_db_new_iterator(self);
258
- }
259
-
260
- rocksdb_pointer* db_pointer;
261
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
262
- if (db_pointer->db == NULL) {
263
- rb_raise(rb_eRuntimeError, "db not open");
264
- }
265
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
266
-
267
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
268
- rb_yield(rb_enc_str_new(it->value().data(), it->value().size(), rb_utf8_encoding()));
269
- }
270
-
271
- delete it;
272
- return self;
251
+ VALUE rocksdb_db_debug(VALUE self){
252
+ return Qnil;
273
253
  }
274
254
 
275
- VALUE rocksdb_db_each_index(VALUE self){
276
- if(!rb_block_given_p()){
277
- return rocksdb_db_new_iterator(self);
278
- }
279
-
280
- rocksdb_pointer* db_pointer;
281
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
282
- if (db_pointer->db == NULL) {
283
- rb_raise(rb_eRuntimeError, "db not open");
284
- }
285
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
255
+ VALUE rocksdb_db_is_writable(VALUE self){
256
+ rocksdb_pointer* db_pointer = get_db(&self);
286
257
 
287
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
288
- rb_yield(rb_enc_str_new(it->key().data(), it->key().size(), rb_utf8_encoding()));
289
- }
290
-
291
- delete it;
292
- return self;
258
+ return (db_pointer->readonly) ? Qfalse : Qtrue;
293
259
  }
294
260
 
295
- VALUE rocksdb_db_each_with_index(VALUE self){
296
- if(!rb_block_given_p()){
297
- return rocksdb_db_new_iterator(self);
298
- }
299
-
300
- rocksdb_pointer* db_pointer;
301
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
302
- if (db_pointer->db == NULL) {
303
- rb_raise(rb_eRuntimeError, "db not open");
304
- }
305
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
261
+ VALUE rocksdb_db_is_open(VALUE self){
262
+ rocksdb_pointer* db_pointer = get_db(&self);
306
263
 
307
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
308
- VALUE a = rb_enc_str_new(it->key().data(), it->key().size(), rb_utf8_encoding());
309
- VALUE b = rb_enc_str_new(it->value().data(), it->value().size(), rb_utf8_encoding());
310
- rb_yield_values(2, a, b);
311
- }
312
-
313
- delete it;
314
- return self;
264
+ return (db_pointer->db == NULL) ? Qfalse : Qtrue;
315
265
  }
316
266
 
317
-
267
+ VALUE rocksdb_db_compact(int argc, VALUE* argv, VALUE self) {
268
+ VALUE v_from, v_to;
269
+ rocksdb::Slice from, to;
318
270
 
319
- VALUE rocksdb_db_reverse_each(VALUE self){
320
- rocksdb_pointer* db_pointer;
321
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
322
- if (db_pointer->db == NULL) {
323
- rb_raise(rb_eRuntimeError, "db not open");
271
+ rb_scan_args(argc, argv, "02", &v_from, &v_to);
272
+
273
+ if(!NIL_P(v_from)) {
274
+ from = SLICE_FROM_RB_VALUE(v_from);
324
275
  }
325
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
326
276
 
327
- for (it->SeekToLast(); it->Valid(); it->Prev()) {
328
- rb_yield(rb_enc_str_new(it->value().data(), it->value().size(), rb_utf8_encoding()));
277
+ if(!NIL_P(v_to)) {
278
+ to = SLICE_FROM_RB_VALUE(v_to);
329
279
  }
330
-
331
- delete it;
332
- return self;
280
+
281
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
282
+ rocksdb::Status status = db_pointer->db->CompactRange(rocksdb::CompactRangeOptions(), &from, &to);
283
+
284
+ return status.ok() ? Qtrue : Qfalse;
333
285
  }
334
286
 
335
- VALUE rocksdb_db_debug(VALUE self){
287
+ VALUE raise_status_error(rocksdb::Status *status) {
288
+ char const *error_text = status->ToString().c_str();
289
+ rb_raise(cRocksdb_status_error, "%s", error_text);
290
+
336
291
  return Qnil;
337
292
  }
338
- VALUE rocksdb_db_is_readonly(VALUE self){
339
- rocksdb_pointer* db_pointer;
340
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
341
- if (db_pointer->readonly) {
342
- return Qtrue;
343
- }
344
- if (!db_pointer->readonly) {
345
- return Qfalse;
346
- }
347
- return Qnil;
293
+
294
+ rocksdb_pointer* get_db(VALUE *self) {
295
+ rocksdb_pointer *db_pointer;
296
+ Data_Get_Struct(*self, rocksdb_pointer, db_pointer);
297
+
298
+ return db_pointer;
348
299
  }
349
- VALUE rocksdb_db_is_open(VALUE self){
350
- rocksdb_pointer* db_pointer;
351
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
352
- return (db_pointer->db == NULL) ? Qfalse : Qtrue;
300
+
301
+ rocksdb_pointer* get_db_for_read(VALUE *self) {
302
+ rocksdb_pointer *db_pointer = get_db(self);
303
+
304
+ check_is_db_ready(db_pointer);
305
+
306
+ return db_pointer;
353
307
  }
354
-
355
- VALUE rocksdb_db_compact(int argc, VALUE* argv, VALUE self) {
356
- VALUE v_from, v_to;
357
- rocksdb::Slice from, to;
358
308
 
359
- rb_scan_args(argc, argv, "02", &v_from, &v_to);
309
+ rocksdb_pointer* get_db_for_write(VALUE *self) {
310
+ rocksdb_pointer *db_pointer = get_db(self);
360
311
 
361
- if(!NIL_P(v_from)) {
362
- Check_Type(v_from, T_STRING);
363
- from = rocksdb::Slice((char*)RSTRING_PTR(v_from), RSTRING_LEN(v_from));
312
+ check_is_db_ready(db_pointer);
313
+
314
+ if (db_pointer->readonly) {
315
+ rb_raise(cRocksdb_readonly, "database is read-only");
364
316
  }
365
317
 
366
- if(!NIL_P(v_to)) {
367
- Check_Type(v_to, T_STRING);
368
- to = rocksdb::Slice((char*)RSTRING_PTR(v_to), RSTRING_LEN(v_to));
318
+ return db_pointer;
319
+ }
320
+
321
+ void check_is_db_ready(rocksdb_pointer *db_pointer) {
322
+ if (db_pointer == NULL) {
323
+ rb_raise(cRocksdb_database_closed, "database is not initialized");
369
324
  }
370
325
 
371
- rocksdb_pointer* db_pointer;
372
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
373
326
  if (db_pointer->db == NULL) {
374
- rb_raise(rb_eRuntimeError, "db not open");
327
+ rb_raise(cRocksdb_database_closed, "database is not opened");
375
328
  }
376
- rocksdb::Status status = db_pointer->db->CompactRange(rocksdb::CompactRangeOptions(), &from, &to);
377
- return status.ok() ? Qtrue : Qfalse;
378
329
  }
379
330
  }