rocksdb-ruby 0.2.2 → 1.0.2

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"
@@ -1,8 +1,9 @@
1
1
  #include "rocksdb_batch_rb.h"
2
2
 
3
- extern "C" {
4
3
  #include <ruby.h>
5
4
 
5
+ extern "C" {
6
+
6
7
  VALUE batch_alloc(VALUE klass){
7
8
  rocksdb::WriteBatch *batch = ALLOC(rocksdb::WriteBatch);
8
9
  batch = new rocksdb::WriteBatch;
@@ -12,6 +13,7 @@ extern "C" {
12
13
  VALUE rocksdb_write_batch_init(){
13
14
  return Qtrue;
14
15
  }
16
+
15
17
  VALUE rocksdb_write_batch_put(VALUE self, VALUE v_key, VALUE v_value){
16
18
  Check_Type(v_key, T_STRING);
17
19
  Check_Type(v_value, T_STRING);
@@ -19,17 +21,18 @@ extern "C" {
19
21
  rocksdb::WriteBatch *batch;
20
22
  std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
21
23
  std::string value = std::string((char*)RSTRING_PTR(v_value), RSTRING_LEN(v_value));
22
-
24
+
23
25
  Data_Get_Struct(self, rocksdb::WriteBatch, batch);
24
26
  batch->Put(key, value);
25
27
  return Qnil;
26
28
  }
29
+
27
30
  VALUE rocksdb_write_batch_delete(VALUE self, VALUE v_key){
28
31
  Check_Type(v_key, T_STRING);
29
32
 
30
33
  rocksdb::WriteBatch *batch;
31
34
  std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
32
-
35
+
33
36
  Data_Get_Struct(self, rocksdb::WriteBatch, batch);
34
37
  batch->Delete(key);
35
38
 
@@ -1,10 +1,10 @@
1
1
  #include "rocksdb/db.h"
2
2
  #include "rocksdb/write_batch.h"
3
+ #include <ruby.h>
3
4
 
4
5
  extern "C" {
5
6
 
6
- #include <ruby.h>
7
-
7
+
8
8
  typedef VALUE (*METHOD)(...);
9
9
 
10
10
  VALUE rocksdb_write_batch_init();
@@ -2,39 +2,40 @@
2
2
  #include "rocksdb_db_rb.h"
3
3
  #include "ruby/encoding.h"
4
4
  #include <iostream>
5
+ #include <ruby.h>
5
6
 
6
7
  extern "C" {
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);
25
+
26
+ db_file_name = STRING_FROM_RB_VALUE(v_db_path);
27
+ db_string_options = STRING_FROM_RB_VALUE(v_db_options);
36
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,320 +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
+ }
121
+
122
+ VALUE rocksdb_db_property(VALUE self, VALUE v_key){
123
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
124
+
125
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
126
+ std::string value = std::string();
127
+
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;
143
+
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;
120
157
  }
121
158
 
122
159
  VALUE rocksdb_db_get(VALUE self, VALUE v_key){
123
- Check_Type(v_key, T_STRING);
160
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
124
161
 
125
- rocksdb_pointer* db_pointer;
126
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
127
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
162
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
128
163
  std::string value;
129
- if (db_pointer->db == NULL) {
130
- rb_raise(rb_eRuntimeError, "db not open");
131
- }
132
- rocksdb::Status status = db_pointer->db->Get(rocksdb::ReadOptions(), key, &value);
133
164
 
134
- 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);
135
166
 
136
- }
167
+ if(status.IsNotFound()) {
168
+ return Qnil;
169
+ } else if (!status.ok()) {
170
+ raise_status_error(&status);
171
+ return Qnil;
172
+ }
137
173
 
174
+ return SLICE_TO_RB_STRING(value);
175
+ }
138
176
 
139
177
  VALUE rocksdb_db_multi_get(VALUE self, VALUE v_array){
140
178
  Check_Type(v_array, T_ARRAY);
141
179
 
142
- rocksdb_pointer* db_pointer;
143
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
180
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
144
181
 
145
182
  long i;
146
183
  long length = RARRAY_LEN(v_array);
147
184
  std::vector<std::string> values(length);
148
185
  std::vector<rocksdb::Slice> keys(length);
149
- std::vector<rocksdb::Status> status;
186
+ std::vector<rocksdb::Status> statuses;
150
187
 
151
188
  for(i=0; i < length; i++){
152
- VALUE op = rb_ary_entry(v_array, i);
153
- 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);
154
191
  }
155
192
 
156
- if (db_pointer->db == NULL) {
157
- rb_raise(rb_eRuntimeError, "db not open");
158
- }
159
- status = db_pointer->db->MultiGet(rocksdb::ReadOptions(),keys,&values);
193
+ statuses = db_pointer->db->MultiGet(rocksdb::ReadOptions(), keys, &values);
194
+
160
195
  for(i=0; i < length; i++){
161
- 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
+ }
162
205
  }
206
+
163
207
  return v_array;
164
208
  }
165
-
209
+
166
210
  VALUE rocksdb_db_delete(VALUE self, VALUE v_key){
167
- Check_Type(v_key, T_STRING);
168
-
169
- rocksdb_pointer* db_pointer;
170
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
211
+ rocksdb_pointer* db_pointer = get_db_for_write(&self);
171
212
 
172
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
173
- if (db_pointer->db == NULL) {
174
- rb_raise(rb_eRuntimeError, "db not open");
175
- }
176
- if (db_pointer->readonly) {
177
- rb_raise(rb_eRuntimeError, "readonly");
178
- }
213
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
179
214
  rocksdb::Status status = db_pointer->db->Delete(rocksdb::WriteOptions(), key);
180
-
181
- 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
+ }
182
223
  }
183
224
 
184
225
  VALUE rocksdb_db_exists(VALUE self, VALUE v_key){
185
- Check_Type(v_key, T_STRING);
226
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
186
227
 
187
- rocksdb_pointer* db_pointer;
188
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
189
-
190
- std::string key = std::string((char*)RSTRING_PTR(v_key), RSTRING_LEN(v_key));
228
+ rocksdb::Slice key = SLICE_FROM_RB_VALUE(v_key);
191
229
  std::string value = std::string();
192
-
193
- if (db_pointer->db == NULL) {
194
- rb_raise(rb_eRuntimeError, "db not open");
195
- }
196
- return db_pointer->db->KeyMayExist(rocksdb::ReadOptions(), key, &value) ? Qtrue : Qfalse;
197
- }
198
230
 
199
- VALUE rocksdb_db_close(VALUE self){
200
- rocksdb_pointer* db_pointer;
201
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
202
-
203
- if(db_pointer->db != NULL){
204
- delete db_pointer->db;
205
- db_pointer->db = NULL;
206
- }
207
- return Qnil;
231
+ return db_pointer->db->KeyMayExist(rocksdb::ReadOptions(), key, &value) ? Qtrue : Qfalse;
208
232
  }
209
233
 
210
- void db_free(rocksdb_pointer* db_pointer){
211
- if(db_pointer->db != NULL){
212
- delete db_pointer->db;
213
- db_pointer->db = NULL;
214
- }
215
- delete db_pointer;
216
- }
217
234
 
218
- VALUE rocksdb_db_new_iterator(VALUE self){
219
- rocksdb_pointer* db_pointer;
235
+ VALUE rocksdb_db_to_iterator(VALUE self){
236
+ rocksdb_pointer* db_pointer = get_db_for_read(&self);
220
237
  rocksdb_iterator_pointer* rocksdb_it;
221
238
 
222
- VALUE klass;
223
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
224
-
225
- if (db_pointer->db == NULL) {
226
- rb_raise(rb_eRuntimeError, "db not open");
227
- }
228
239
  rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
229
240
 
241
+ VALUE klass;
230
242
  klass = rb_class_new_instance(0, NULL, cRocksdb_iterator);
231
243
 
232
244
  Data_Get_Struct(klass, rocksdb_iterator_pointer , rocksdb_it);
233
245
  rocksdb_it->it = it;
246
+ rocksdb_it->db_pointer = db_pointer;
247
+
234
248
  return klass;
235
249
  }
236
250
 
237
-
238
- VALUE rocksdb_db_each(VALUE self){
239
- if(!rb_block_given_p()){
240
- return rocksdb_db_new_iterator(self);
241
- }
242
-
243
- rocksdb_pointer* db_pointer;
244
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
245
- if (db_pointer->db == NULL) {
246
- rb_raise(rb_eRuntimeError, "db not open");
247
- }
248
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
249
-
250
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
251
- rb_yield(rb_enc_str_new(it->value().data(), it->value().size(), rb_utf8_encoding()));
252
- }
253
-
254
- delete it;
255
- return self;
251
+ VALUE rocksdb_db_debug(VALUE self){
252
+ return Qnil;
256
253
  }
257
254
 
258
- VALUE rocksdb_db_each_index(VALUE self){
259
- if(!rb_block_given_p()){
260
- return rocksdb_db_new_iterator(self);
261
- }
262
-
263
- rocksdb_pointer* db_pointer;
264
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
265
- if (db_pointer->db == NULL) {
266
- rb_raise(rb_eRuntimeError, "db not open");
267
- }
268
- 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);
269
257
 
270
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
271
- rb_yield(rb_enc_str_new(it->key().data(), it->key().size(), rb_utf8_encoding()));
272
- }
273
-
274
- delete it;
275
- return self;
258
+ return (db_pointer->readonly) ? Qfalse : Qtrue;
276
259
  }
277
260
 
278
- VALUE rocksdb_db_each_with_index(VALUE self){
279
- if(!rb_block_given_p()){
280
- return rocksdb_db_new_iterator(self);
281
- }
282
-
283
- rocksdb_pointer* db_pointer;
284
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
285
- if (db_pointer->db == NULL) {
286
- rb_raise(rb_eRuntimeError, "db not open");
287
- }
288
- 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);
289
263
 
290
- for (it->SeekToFirst(); it->Valid(); it->Next()) {
291
- VALUE a = rb_enc_str_new(it->key().data(), it->key().size(), rb_utf8_encoding());
292
- VALUE b = rb_enc_str_new(it->value().data(), it->value().size(), rb_utf8_encoding());
293
- rb_yield_values(2, a, b);
294
- }
295
-
296
- delete it;
297
- return self;
264
+ return (db_pointer->db == NULL) ? Qfalse : Qtrue;
298
265
  }
299
266
 
300
-
267
+ VALUE rocksdb_db_compact(int argc, VALUE* argv, VALUE self) {
268
+ VALUE v_from, v_to;
269
+ rocksdb::Slice from, to;
301
270
 
302
- VALUE rocksdb_db_reverse_each(VALUE self){
303
- rocksdb_pointer* db_pointer;
304
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
305
- if (db_pointer->db == NULL) {
306
- 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);
307
275
  }
308
- rocksdb::Iterator* it = db_pointer->db->NewIterator(rocksdb::ReadOptions());
309
276
 
310
- for (it->SeekToLast(); it->Valid(); it->Prev()) {
311
- 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);
312
279
  }
313
-
314
- delete it;
315
- 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;
316
285
  }
317
286
 
318
- 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
+
319
291
  return Qnil;
320
292
  }
321
- VALUE rocksdb_db_is_readonly(VALUE self){
322
- rocksdb_pointer* db_pointer;
323
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
324
- if (db_pointer->readonly) {
325
- return Qtrue;
326
- }
327
- if (!db_pointer->readonly) {
328
- return Qfalse;
329
- }
330
- 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;
331
299
  }
332
- VALUE rocksdb_db_is_open(VALUE self){
333
- rocksdb_pointer* db_pointer;
334
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
335
- 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;
336
307
  }
337
-
338
- VALUE rocksdb_db_compact(int argc, VALUE* argv, VALUE self) {
339
- VALUE v_from, v_to;
340
- rocksdb::Slice from, to;
341
308
 
342
- 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);
343
311
 
344
- if(!NIL_P(v_from)) {
345
- Check_Type(v_from, T_STRING);
346
- 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");
347
316
  }
348
317
 
349
- if(!NIL_P(v_to)) {
350
- Check_Type(v_to, T_STRING);
351
- 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");
352
324
  }
353
325
 
354
- rocksdb_pointer* db_pointer;
355
- Data_Get_Struct(self, rocksdb_pointer, db_pointer);
356
326
  if (db_pointer->db == NULL) {
357
- rb_raise(rb_eRuntimeError, "db not open");
327
+ rb_raise(cRocksdb_database_closed, "database is not opened");
358
328
  }
359
- rocksdb::Status status = db_pointer->db->CompactRange(rocksdb::CompactRangeOptions(), &from, &to);
360
- return status.ok() ? Qtrue : Qfalse;
361
329
  }
362
330
  }