@nxtedition/rocksdb 7.0.0-alpha.2 → 7.0.0-alpha.3
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.
- package/binding.cc +86 -124
- package/index.js +35 -91
- package/package.json +1 -1
package/binding.cc
CHANGED
|
@@ -31,7 +31,6 @@ class NullLogger : public rocksdb::Logger {
|
|
|
31
31
|
struct Database;
|
|
32
32
|
struct Iterator;
|
|
33
33
|
struct Updates;
|
|
34
|
-
struct Column;
|
|
35
34
|
|
|
36
35
|
#define NAPI_STATUS_RETURN(call) \
|
|
37
36
|
{ \
|
|
@@ -365,16 +364,6 @@ struct Database {
|
|
|
365
364
|
DecrementPriorityWork(env);
|
|
366
365
|
}
|
|
367
366
|
|
|
368
|
-
void AttachColumn(napi_env env, Column* column) {
|
|
369
|
-
columns_.insert(column);
|
|
370
|
-
IncrementPriorityWork(env);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
void DetachColumn(napi_env env, Column* column) {
|
|
374
|
-
columns_.erase(column);
|
|
375
|
-
DecrementPriorityWork(env);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
367
|
void IncrementPriorityWork(napi_env env) { napi_reference_ref(env, priorityRef_, &priorityWork_); }
|
|
379
368
|
|
|
380
369
|
void DecrementPriorityWork(napi_env env) {
|
|
@@ -392,7 +381,7 @@ struct Database {
|
|
|
392
381
|
Worker* pendingCloseWorker_;
|
|
393
382
|
std::set<Iterator*> iterators_;
|
|
394
383
|
std::set<Updates*> updates_;
|
|
395
|
-
std::
|
|
384
|
+
std::vector<rocksdb::ColumnFamilyHandle*> columns_;
|
|
396
385
|
napi_ref priorityRef_;
|
|
397
386
|
|
|
398
387
|
private:
|
|
@@ -597,39 +586,9 @@ struct Updates {
|
|
|
597
586
|
napi_ref ref_ = nullptr;
|
|
598
587
|
};
|
|
599
588
|
|
|
600
|
-
struct Column {
|
|
601
|
-
Column(Database* database, rocksdb::ColumnFamilyHandle* handle)
|
|
602
|
-
: database_(database), handle_(handle) {}
|
|
603
|
-
|
|
604
|
-
void Close() {
|
|
605
|
-
if (handle_) {
|
|
606
|
-
database_->db_->DestroyColumnFamilyHandle(handle_); // TODO (fix): Handle error?
|
|
607
|
-
handle_ = nullptr;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
void Attach(napi_env env, napi_value context) {
|
|
612
|
-
napi_create_reference(env, context, 1, &ref_);
|
|
613
|
-
database_->AttachColumn(env, this);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
void Detach(napi_env env) {
|
|
617
|
-
database_->DetachColumn(env, this);
|
|
618
|
-
if (ref_) {
|
|
619
|
-
napi_delete_reference(env, ref_);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
Database* database_;
|
|
624
|
-
rocksdb::ColumnFamilyHandle* handle_;
|
|
625
|
-
|
|
626
|
-
private:
|
|
627
|
-
napi_ref ref_ = nullptr;
|
|
628
|
-
};
|
|
629
|
-
|
|
630
589
|
static rocksdb::ColumnFamilyHandle* GetColumnFamily(Database* database, napi_env env, napi_value options) {
|
|
631
|
-
auto column_opt = ExternalValueProperty<
|
|
632
|
-
return column_opt ?
|
|
590
|
+
auto column_opt = ExternalValueProperty<rocksdb::ColumnFamilyHandle>(env, options, "column");
|
|
591
|
+
return column_opt ? *column_opt : database->db_->DefaultColumnFamily();
|
|
633
592
|
}
|
|
634
593
|
|
|
635
594
|
/**
|
|
@@ -659,8 +618,7 @@ static void env_cleanup_hook(void* arg) {
|
|
|
659
618
|
}
|
|
660
619
|
|
|
661
620
|
for (auto it : database->columns_) {
|
|
662
|
-
|
|
663
|
-
it->Close();
|
|
621
|
+
database->db_->DestroyColumnFamilyHandle(it);
|
|
664
622
|
}
|
|
665
623
|
|
|
666
624
|
// Having closed the iterators (and released snapshots) we can safely close.
|
|
@@ -695,24 +653,42 @@ struct OpenWorker final : public Worker {
|
|
|
695
653
|
Database* database,
|
|
696
654
|
napi_value callback,
|
|
697
655
|
const std::string& location,
|
|
698
|
-
rocksdb::Options options,
|
|
699
|
-
|
|
656
|
+
const rocksdb::Options& options,
|
|
657
|
+
std::vector<rocksdb::ColumnFamilyDescriptor> column_families)
|
|
700
658
|
: Worker(env, database, callback, "leveldown.db.open"),
|
|
701
659
|
options_(options),
|
|
702
|
-
|
|
703
|
-
|
|
660
|
+
location_(location),
|
|
661
|
+
column_families_(std::move(column_families)) {}
|
|
704
662
|
|
|
705
663
|
rocksdb::Status Execute(Database& database) override {
|
|
706
664
|
rocksdb::DB* db = nullptr;
|
|
707
|
-
const auto status =
|
|
708
|
-
|
|
665
|
+
const auto status = column_families_.empty()
|
|
666
|
+
? rocksdb::DB::Open(options_, location_, &db)
|
|
667
|
+
: rocksdb::DB::Open(options_, location_, column_families_, &database.columns_, &db);
|
|
709
668
|
database.db_.reset(db);
|
|
710
669
|
return status;
|
|
711
670
|
}
|
|
712
671
|
|
|
672
|
+
napi_status OnOk(napi_env env, napi_value callback) override {
|
|
673
|
+
const auto size = database_->columns_.size();
|
|
674
|
+
napi_value result;
|
|
675
|
+
NAPI_STATUS_RETURN(napi_create_object(env, &result));
|
|
676
|
+
|
|
677
|
+
for (size_t n = 0; n < size; ++n) {
|
|
678
|
+
napi_value column;
|
|
679
|
+
NAPI_STATUS_RETURN(napi_create_external(env, database_->columns_[n], nullptr, nullptr, &column));
|
|
680
|
+
NAPI_STATUS_RETURN(napi_set_named_property(env, result, column_families_[n].name.c_str(), column));
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
napi_value argv[2];
|
|
684
|
+
NAPI_STATUS_RETURN(napi_get_null(env, &argv[0]));
|
|
685
|
+
argv[1] = result;
|
|
686
|
+
return CallFunction(env, callback, 2, argv);
|
|
687
|
+
}
|
|
688
|
+
|
|
713
689
|
rocksdb::Options options_;
|
|
714
|
-
const bool readOnly_;
|
|
715
690
|
const std::string location_;
|
|
691
|
+
std::vector<rocksdb::ColumnFamilyDescriptor> column_families_;
|
|
716
692
|
};
|
|
717
693
|
|
|
718
694
|
napi_status InitOptions(napi_env env, auto& options, auto options2) {
|
|
@@ -805,26 +781,26 @@ NAPI_METHOD(db_open) {
|
|
|
805
781
|
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&database));
|
|
806
782
|
|
|
807
783
|
const auto location = ToString(env, argv[1]);
|
|
784
|
+
const auto options = argv[2];
|
|
785
|
+
const auto callback = argv[3];
|
|
808
786
|
|
|
809
|
-
rocksdb::Options
|
|
810
|
-
|
|
811
|
-
options.IncreaseParallelism(
|
|
812
|
-
Uint32Property(env, argv[2], "parallelism").value_or(std::thread::hardware_concurrency() / 2));
|
|
787
|
+
rocksdb::Options dbOptions;
|
|
813
788
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
options.avoid_unnecessary_blocking_io = true;
|
|
817
|
-
options.use_adaptive_mutex = BooleanProperty(env, argv[2], "useAdaptiveMutex").value_or(true);
|
|
818
|
-
options.enable_pipelined_write = BooleanProperty(env, argv[2], "enablePipelinedWrite").value_or(true);
|
|
819
|
-
options.max_background_jobs =
|
|
820
|
-
Uint32Property(env, argv[2], "maxBackgroundJobs").value_or(std::thread::hardware_concurrency() / 4);
|
|
821
|
-
options.WAL_ttl_seconds = Uint32Property(env, argv[2], "walTTL").value_or(0) / 1e3;
|
|
822
|
-
options.WAL_size_limit_MB = Uint32Property(env, argv[2], "walSizeLimit").value_or(0) / 1e6;
|
|
789
|
+
dbOptions.IncreaseParallelism(
|
|
790
|
+
Uint32Property(env, options, "parallelism").value_or(std::thread::hardware_concurrency() / 2));
|
|
823
791
|
|
|
824
|
-
|
|
825
|
-
|
|
792
|
+
dbOptions.create_if_missing = BooleanProperty(env, options, "createIfMissing").value_or(true);
|
|
793
|
+
dbOptions.error_if_exists = BooleanProperty(env, options, "errorIfExists").value_or(false);
|
|
794
|
+
dbOptions.avoid_unnecessary_blocking_io = true;
|
|
795
|
+
dbOptions.use_adaptive_mutex = BooleanProperty(env, options, "useAdaptiveMutex").value_or(true);
|
|
796
|
+
dbOptions.enable_pipelined_write = BooleanProperty(env, options, "enablePipelinedWrite").value_or(true);
|
|
797
|
+
dbOptions.max_background_jobs =
|
|
798
|
+
Uint32Property(env, options, "maxBackgroundJobs").value_or(std::thread::hardware_concurrency() / 4);
|
|
799
|
+
dbOptions.WAL_ttl_seconds = Uint32Property(env, options, "walTTL").value_or(0) / 1e3;
|
|
800
|
+
dbOptions.WAL_size_limit_MB = Uint32Property(env, options, "walSizeLimit").value_or(0) / 1e6;
|
|
801
|
+
dbOptions.create_missing_column_families = true;
|
|
826
802
|
|
|
827
|
-
const auto infoLogLevel = StringProperty(env,
|
|
803
|
+
const auto infoLogLevel = StringProperty(env, options, "infoLogLevel").value_or("");
|
|
828
804
|
if (infoLogLevel.size() > 0) {
|
|
829
805
|
rocksdb::InfoLogLevel lvl = {};
|
|
830
806
|
|
|
@@ -843,21 +819,43 @@ NAPI_METHOD(db_open) {
|
|
|
843
819
|
else
|
|
844
820
|
napi_throw_error(env, nullptr, "invalid log level");
|
|
845
821
|
|
|
846
|
-
|
|
822
|
+
dbOptions.info_log_level = lvl;
|
|
847
823
|
} else {
|
|
848
824
|
// In some places RocksDB checks this option to see if it should prepare
|
|
849
825
|
// debug information (ahead of logging), so set it to the highest level.
|
|
850
|
-
|
|
851
|
-
|
|
826
|
+
dbOptions.info_log_level = rocksdb::InfoLogLevel::HEADER_LEVEL;
|
|
827
|
+
dbOptions.info_log.reset(new NullLogger());
|
|
852
828
|
}
|
|
853
829
|
|
|
854
|
-
|
|
830
|
+
NAPI_STATUS_THROWS(InitOptions(env, dbOptions, options));
|
|
855
831
|
|
|
856
|
-
|
|
832
|
+
std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
|
|
833
|
+
|
|
834
|
+
if (HasProperty(env, options, "columns")) {
|
|
835
|
+
napi_value columns;
|
|
836
|
+
NAPI_STATUS_THROWS(napi_get_named_property(env, options, "columns", &columns));
|
|
857
837
|
|
|
858
|
-
|
|
838
|
+
napi_value keys;
|
|
839
|
+
NAPI_STATUS_THROWS(napi_get_property_names(env, columns, &keys));
|
|
840
|
+
|
|
841
|
+
uint32_t len;
|
|
842
|
+
NAPI_STATUS_THROWS(napi_get_array_length(env, keys, &len));
|
|
843
|
+
|
|
844
|
+
for (uint32_t n = 0; n < len; ++n) {
|
|
845
|
+
napi_value key;
|
|
846
|
+
NAPI_STATUS_THROWS(napi_get_element(env, keys, n, &key));
|
|
847
|
+
|
|
848
|
+
napi_value column;
|
|
849
|
+
NAPI_STATUS_THROWS(napi_get_property(env, columns, key, &column));
|
|
850
|
+
|
|
851
|
+
rocksdb::ColumnFamilyOptions columnOptions;
|
|
852
|
+
NAPI_STATUS_THROWS(InitOptions(env, columnOptions, column));
|
|
853
|
+
|
|
854
|
+
column_families.emplace_back(ToString(env, key), columnOptions);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
859
857
|
|
|
860
|
-
auto worker = new OpenWorker(env, database, callback, location,
|
|
858
|
+
auto worker = new OpenWorker(env, database, callback, location, dbOptions, column_families);
|
|
861
859
|
worker->Queue(env);
|
|
862
860
|
|
|
863
861
|
return 0;
|
|
@@ -867,7 +865,13 @@ struct CloseWorker final : public Worker {
|
|
|
867
865
|
CloseWorker(napi_env env, Database* database, napi_value callback)
|
|
868
866
|
: Worker(env, database, callback, "leveldown.db.close") {}
|
|
869
867
|
|
|
870
|
-
rocksdb::Status Execute(Database& database) override {
|
|
868
|
+
rocksdb::Status Execute(Database& database) override {
|
|
869
|
+
for (auto it : database.columns_) {
|
|
870
|
+
database.db_->DestroyColumnFamilyHandle(it);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
return database.db_->Close();
|
|
874
|
+
}
|
|
871
875
|
};
|
|
872
876
|
|
|
873
877
|
napi_value noop_callback(napi_env env, napi_callback_info info) {
|
|
@@ -1491,15 +1495,15 @@ struct NextWorker final : public Worker {
|
|
|
1491
1495
|
napi_value result;
|
|
1492
1496
|
NAPI_STATUS_RETURN(napi_create_array_with_length(env, size, &result));
|
|
1493
1497
|
|
|
1494
|
-
for (size_t
|
|
1498
|
+
for (size_t n = 0; n < size; n += 2) {
|
|
1495
1499
|
napi_value key;
|
|
1496
1500
|
napi_value val;
|
|
1497
1501
|
|
|
1498
|
-
NAPI_STATUS_RETURN(Convert(env, std::move(cache_[
|
|
1499
|
-
NAPI_STATUS_RETURN(Convert(env, std::move(cache_[
|
|
1502
|
+
NAPI_STATUS_RETURN(Convert(env, std::move(cache_[n + 0]), iterator_->keyAsBuffer_, key));
|
|
1503
|
+
NAPI_STATUS_RETURN(Convert(env, std::move(cache_[n + 1]), iterator_->valueAsBuffer_, val));
|
|
1500
1504
|
|
|
1501
|
-
NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(
|
|
1502
|
-
NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(
|
|
1505
|
+
NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(n + 0), key));
|
|
1506
|
+
NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(n + 1), val));
|
|
1503
1507
|
}
|
|
1504
1508
|
|
|
1505
1509
|
cache_.clear();
|
|
@@ -1655,45 +1659,6 @@ NAPI_METHOD(batch_write) {
|
|
|
1655
1659
|
return ToError(env, database->db_->Write(writeOptions, batch));
|
|
1656
1660
|
}
|
|
1657
1661
|
|
|
1658
|
-
NAPI_METHOD(column_init) {
|
|
1659
|
-
NAPI_ARGV(3);
|
|
1660
|
-
|
|
1661
|
-
Database* database;
|
|
1662
|
-
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&database));
|
|
1663
|
-
|
|
1664
|
-
NapiSlice name;
|
|
1665
|
-
NAPI_STATUS_THROWS(ToNapiSlice(env, argv[1], name));
|
|
1666
|
-
|
|
1667
|
-
rocksdb::ColumnFamilyOptions options;
|
|
1668
|
-
NAPI_STATUS_THROWS(InitOptions(env, options, argv[2]));
|
|
1669
|
-
|
|
1670
|
-
rocksdb::ColumnFamilyHandle* handle;
|
|
1671
|
-
ROCKS_STATUS_THROWS(database->db_->CreateColumnFamily(options, name.ToString(), &handle));
|
|
1672
|
-
|
|
1673
|
-
auto column = std::make_unique<Column>(database, handle);
|
|
1674
|
-
|
|
1675
|
-
napi_value result;
|
|
1676
|
-
NAPI_STATUS_THROWS(napi_create_external(env, column.get(), Finalize<Column>, column.get(), &result));
|
|
1677
|
-
|
|
1678
|
-
// Prevent GC of JS object before the iterator is closed (explicitly or on
|
|
1679
|
-
// db close) and keep track of non-closed iterators to end them on db close.
|
|
1680
|
-
column.release()->Attach(env, result);
|
|
1681
|
-
|
|
1682
|
-
return result;
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
NAPI_METHOD(column_close) {
|
|
1686
|
-
NAPI_ARGV(1);
|
|
1687
|
-
|
|
1688
|
-
Column* column;
|
|
1689
|
-
NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&column));
|
|
1690
|
-
|
|
1691
|
-
column->Detach(env);
|
|
1692
|
-
column->Close();
|
|
1693
|
-
|
|
1694
|
-
return 0;
|
|
1695
|
-
}
|
|
1696
|
-
|
|
1697
1662
|
NAPI_INIT() {
|
|
1698
1663
|
NAPI_EXPORT_FUNCTION(db_init);
|
|
1699
1664
|
NAPI_EXPORT_FUNCTION(db_open);
|
|
@@ -1705,9 +1670,6 @@ NAPI_INIT() {
|
|
|
1705
1670
|
NAPI_EXPORT_FUNCTION(db_clear);
|
|
1706
1671
|
NAPI_EXPORT_FUNCTION(db_get_property);
|
|
1707
1672
|
|
|
1708
|
-
NAPI_EXPORT_FUNCTION(column_init);
|
|
1709
|
-
NAPI_EXPORT_FUNCTION(column_close);
|
|
1710
|
-
|
|
1711
1673
|
NAPI_EXPORT_FUNCTION(iterator_init);
|
|
1712
1674
|
NAPI_EXPORT_FUNCTION(iterator_seek);
|
|
1713
1675
|
NAPI_EXPORT_FUNCTION(iterator_close);
|
package/index.js
CHANGED
|
@@ -8,8 +8,8 @@ const { ChainedBatch } = require('./chained-batch')
|
|
|
8
8
|
const { Iterator } = require('./iterator')
|
|
9
9
|
|
|
10
10
|
const kContext = Symbol('context')
|
|
11
|
-
const kLocation = Symbol('location')
|
|
12
11
|
const kColumns = Symbol('columns')
|
|
12
|
+
const kLocation = Symbol('location')
|
|
13
13
|
|
|
14
14
|
class RocksLevel extends AbstractLevel {
|
|
15
15
|
constructor (location, options, _) {
|
|
@@ -33,8 +33,6 @@ class RocksLevel extends AbstractLevel {
|
|
|
33
33
|
createIfMissing: true,
|
|
34
34
|
errorIfExists: true,
|
|
35
35
|
additionalMethods: {
|
|
36
|
-
createColumn: true,
|
|
37
|
-
closeColumn: true,
|
|
38
36
|
updates: true,
|
|
39
37
|
query: true
|
|
40
38
|
}
|
|
@@ -42,29 +40,37 @@ class RocksLevel extends AbstractLevel {
|
|
|
42
40
|
|
|
43
41
|
this[kLocation] = location
|
|
44
42
|
this[kContext] = binding.db_init()
|
|
45
|
-
this[kColumns] =
|
|
43
|
+
this[kColumns] = {}
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
get location () {
|
|
49
47
|
return this[kLocation]
|
|
50
48
|
}
|
|
51
49
|
|
|
50
|
+
get columns () {
|
|
51
|
+
return this[kColumns]
|
|
52
|
+
}
|
|
53
|
+
|
|
52
54
|
_open (options, callback) {
|
|
55
|
+
const onOpen = (err, columns) => {
|
|
56
|
+
if (err) {
|
|
57
|
+
callback(err)
|
|
58
|
+
} else {
|
|
59
|
+
this[kColumns] = columns
|
|
60
|
+
callback(null)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
53
63
|
if (options.createIfMissing) {
|
|
54
64
|
fs.mkdir(this[kLocation], { recursive: true }, (err) => {
|
|
55
65
|
if (err) return callback(err)
|
|
56
|
-
binding.db_open(this[kContext], this[kLocation], options,
|
|
66
|
+
binding.db_open(this[kContext], this[kLocation], options, onOpen)
|
|
57
67
|
})
|
|
58
68
|
} else {
|
|
59
|
-
binding.db_open(this[kContext], this[kLocation], options,
|
|
69
|
+
binding.db_open(this[kContext], this[kLocation], options, onOpen)
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
_close (callback) {
|
|
64
|
-
for (const column of this[kColumns]) {
|
|
65
|
-
binding.column_close(column)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
74
|
binding.db_close(this[kContext], callback)
|
|
69
75
|
}
|
|
70
76
|
|
|
@@ -115,99 +121,37 @@ class RocksLevel extends AbstractLevel {
|
|
|
115
121
|
return binding.db_get_property(this[kContext], property)
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
async
|
|
124
|
+
async query (options) {
|
|
119
125
|
if (this.status !== 'open') {
|
|
120
126
|
throw new ModuleError('Database is not open', {
|
|
121
127
|
code: 'LEVEL_DATABASE_NOT_OPEN'
|
|
122
128
|
})
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
async * query (options) {
|
|
133
|
-
if (this.status !== 'open') {
|
|
134
|
-
throw new ModuleError('Database is not open', {
|
|
135
|
-
code: 'LEVEL_DATABASE_NOT_OPEN'
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
class Query {
|
|
140
|
-
constructor (db, options) {
|
|
141
|
-
this.context = binding.iterator_init(db[kContext], options)
|
|
142
|
-
this.closed = false
|
|
143
|
-
this.promise = null
|
|
144
|
-
this.sequence = binding.iterator_get_sequence(this.context)
|
|
145
|
-
this.db = db
|
|
146
|
-
this.db.attachResource(this)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async next () {
|
|
150
|
-
if (this.closed) {
|
|
151
|
-
return {}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
this.promise = new Promise(resolve => binding.iterator_nextv(this.context, 1000, (err, rows, finished) => {
|
|
155
|
-
this.promise = null
|
|
156
|
-
if (err) {
|
|
157
|
-
resolve(Promise.reject(err))
|
|
158
|
-
} else {
|
|
159
|
-
resolve({
|
|
160
|
-
finished,
|
|
161
|
-
rows,
|
|
162
|
-
sequence: this.sequence
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
}))
|
|
166
|
-
|
|
167
|
-
return this.promise
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async close (callback) {
|
|
171
|
-
try {
|
|
172
|
-
await this.promise
|
|
173
|
-
} catch {
|
|
174
|
-
// Do nothing...
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
if (!this.closed) {
|
|
179
|
-
this.closed = true
|
|
180
|
-
binding.iterator_close(this.context)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (callback) {
|
|
184
|
-
process.nextTick(callback)
|
|
185
|
-
}
|
|
186
|
-
} catch (err) {
|
|
187
|
-
if (callback) {
|
|
188
|
-
process.nextTick(callback, err)
|
|
189
|
-
} else {
|
|
190
|
-
throw err
|
|
191
|
-
}
|
|
192
|
-
} finally {
|
|
193
|
-
this.db.detachResource(this)
|
|
194
|
-
}
|
|
131
|
+
const context = binding.iterator_init(this[kContext], options)
|
|
132
|
+
const sequence = binding.iterator_get_sequence(context)
|
|
133
|
+
const resource = {
|
|
134
|
+
callback: null,
|
|
135
|
+
close (callback) {
|
|
136
|
+
this.callback = callback
|
|
195
137
|
}
|
|
196
138
|
}
|
|
197
139
|
|
|
198
|
-
const query = new Query(this, options)
|
|
199
140
|
try {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return
|
|
141
|
+
this.attachResource(resource)
|
|
142
|
+
return await new Promise((resolve, reject) => binding.iterator_nextv(context, options.limit || 1000, (err, rows) => {
|
|
143
|
+
if (err) {
|
|
144
|
+
reject(err)
|
|
145
|
+
} else {
|
|
146
|
+
resolve({ rows, sequence })
|
|
207
147
|
}
|
|
208
|
-
}
|
|
148
|
+
}))
|
|
209
149
|
} finally {
|
|
210
|
-
|
|
150
|
+
this.detachResource(resource)
|
|
151
|
+
binding.iterator_close(this.context)
|
|
152
|
+
if (resource.callback) {
|
|
153
|
+
resource.callback()
|
|
154
|
+
}
|
|
211
155
|
}
|
|
212
156
|
}
|
|
213
157
|
|