@ohos-ports/lmdb 2.5.3-beta.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.
- package/LICENSE +21 -0
- package/README.md +536 -0
- package/SECURITY.md +12 -0
- package/binding.gyp +111 -0
- package/build/Release/lmdb.node +0 -0
- package/caching.js +156 -0
- package/dependencies/lmdb/libraries/liblmdb/COPYRIGHT +20 -0
- package/dependencies/lmdb/libraries/liblmdb/Doxyfile +1631 -0
- package/dependencies/lmdb/libraries/liblmdb/LICENSE +47 -0
- package/dependencies/lmdb/libraries/liblmdb/Makefile +136 -0
- package/dependencies/lmdb/libraries/liblmdb/chacha8.c +183 -0
- package/dependencies/lmdb/libraries/liblmdb/chacha8.h +14 -0
- package/dependencies/lmdb/libraries/liblmdb/crypto.c +121 -0
- package/dependencies/lmdb/libraries/liblmdb/intro.doc +192 -0
- package/dependencies/lmdb/libraries/liblmdb/lmdb.h +1792 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb.c +12429 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_copy.1 +74 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_copy.c +106 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_drop.1 +53 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_drop.c +154 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_dump.1 +94 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_dump.c +333 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_load.1 +97 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_load.c +530 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_stat.1 +83 -0
- package/dependencies/lmdb/libraries/liblmdb/mdb_stat.c +276 -0
- package/dependencies/lmdb/libraries/liblmdb/midl.c +452 -0
- package/dependencies/lmdb/libraries/liblmdb/midl.h +208 -0
- package/dependencies/lmdb/libraries/liblmdb/module.c +101 -0
- package/dependencies/lmdb/libraries/liblmdb/module.h +16 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest.c +178 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest2.c +124 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest3.c +133 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest4.c +168 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest5.c +135 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest6.c +141 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest_enc.c +190 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest_enc2.c +189 -0
- package/dependencies/lmdb/libraries/liblmdb/mtest_remap.c +177 -0
- package/dependencies/lmdb/libraries/liblmdb/sample-bdb.txt +73 -0
- package/dependencies/lmdb/libraries/liblmdb/sample-mdb.txt +62 -0
- package/dependencies/lmdb/libraries/liblmdb/tooltag +27 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/COPYRIGHT +20 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/Doxyfile +1631 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/LICENSE +47 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/Makefile +118 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/intro.doc +192 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/lmdb.h +1653 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb.c +11359 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_copy.1 +61 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_copy.c +84 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_drop.1 +40 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_drop.c +135 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_dump.1 +81 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_dump.c +319 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_load.1 +84 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_load.c +492 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_stat.1 +70 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_stat.c +264 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/midl.c +421 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/midl.h +200 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest.c +177 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest2.c +124 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest3.c +133 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest4.c +168 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest5.c +135 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest6.c +141 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/sample-bdb.txt +73 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/sample-mdb.txt +62 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/tooltag +27 -0
- package/dependencies/lz4/LICENSE +11 -0
- package/dependencies/lz4/lib/LICENSE +24 -0
- package/dependencies/lz4/lib/README.md +137 -0
- package/dependencies/lz4/lib/dll/example/README.md +69 -0
- package/dependencies/lz4/lib/dll/example/fullbench-dll.sln +25 -0
- package/dependencies/lz4/lib/dll/example/fullbench-dll.vcxproj +182 -0
- package/dependencies/lz4/lib/dll/liblz4.def +62 -0
- package/dependencies/lz4/lib/liblz4-dll.rc.in +35 -0
- package/dependencies/lz4/lib/liblz4.pc.in +14 -0
- package/dependencies/lz4/lib/lz4.c +2495 -0
- package/dependencies/lz4/lib/lz4.h +774 -0
- package/dependencies/lz4/lib/lz4frame.c +1899 -0
- package/dependencies/lz4/lib/lz4frame.h +623 -0
- package/dependencies/lz4/lib/lz4frame_static.h +47 -0
- package/dependencies/lz4/lib/lz4hc.c +1615 -0
- package/dependencies/lz4/lib/lz4hc.h +413 -0
- package/dependencies/lz4/lib/xxhash.c +1030 -0
- package/dependencies/lz4/lib/xxhash.h +328 -0
- package/dependencies/v8/v8-fast-api-calls-v16.h +791 -0
- package/dependencies/v8/v8-fast-api-calls.h +888 -0
- package/dict/dict.txt +1 -0
- package/dict/dict2.txt +1 -0
- package/dist/index.cjs +2478 -0
- package/dist/index.cjs.map +1 -0
- package/index.d.ts +385 -0
- package/index.js +37 -0
- package/keys.js +102 -0
- package/level.js +27 -0
- package/native.js +82 -0
- package/node-index.js +28 -0
- package/open.js +414 -0
- package/package.json +70 -0
- package/read.js +590 -0
- package/rollup.config.js +12 -0
- package/src/compression.cpp +222 -0
- package/src/cursor.cpp +344 -0
- package/src/dbi.cpp +344 -0
- package/src/env.cpp +762 -0
- package/src/lmdb-js.cpp +64 -0
- package/src/lmdb-js.h +599 -0
- package/src/misc.cpp +324 -0
- package/src/ordered-binary.cpp +46 -0
- package/src/txn.cpp +257 -0
- package/src/v8-functions.cpp +166 -0
- package/src/windows.c +35 -0
- package/src/writer.cpp +452 -0
- package/util/RangeIterable.js +141 -0
- package/util/set-optional-deps.cjs +10 -0
- package/util/when.js +8 -0
- package/write.js +882 -0
package/open.js
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { Compression, getAddress, arch, fs, path as pathModule, lmdbError, EventEmitter, MsgpackrEncoder, Env, Dbi, tmpdir, os, nativeAddon } from './native.js';
|
|
2
|
+
import { CachingStore, setGetLastVersion } from './caching.js';
|
|
3
|
+
import { addReadMethods, makeReusableBuffer } from './read.js';
|
|
4
|
+
import { addWriteMethods } from './write.js';
|
|
5
|
+
import { applyKeyHandling } from './keys.js';
|
|
6
|
+
let moduleRequire = typeof require == 'function' && require;
|
|
7
|
+
export function setRequire(require) {
|
|
8
|
+
moduleRequire = require;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
setGetLastVersion(getLastVersion);
|
|
12
|
+
let keyBytes, keyBytesView;
|
|
13
|
+
const buffers = [];
|
|
14
|
+
const { onExit, getEnvsPointer, setEnvsPointer, getEnvFlags, setJSFlags } = nativeAddon;
|
|
15
|
+
if (globalThis.__lmdb_envs__)
|
|
16
|
+
setEnvsPointer(globalThis.__lmdb_envs__);
|
|
17
|
+
else
|
|
18
|
+
globalThis.__lmdb_envs__ = getEnvsPointer();
|
|
19
|
+
|
|
20
|
+
// this is hard coded as an upper limit because it is important assumption of the fixed buffers in writing instructions
|
|
21
|
+
// this corresponds to the max key size for 8KB pages
|
|
22
|
+
const MAX_KEY_SIZE = 4026;
|
|
23
|
+
const DEFAULT_COMMIT_DELAY = 0;
|
|
24
|
+
|
|
25
|
+
export const allDbs = new Map();
|
|
26
|
+
let defaultCompression;
|
|
27
|
+
let lastSize;
|
|
28
|
+
let hasRegisteredOnExit;
|
|
29
|
+
export function open(path, options) {
|
|
30
|
+
if (!keyBytes) // TODO: Consolidate get buffer and key buffer (don't think we need both)
|
|
31
|
+
allocateFixedBuffer();
|
|
32
|
+
if (typeof path == 'object' && !options) {
|
|
33
|
+
options = path;
|
|
34
|
+
path = options.path;
|
|
35
|
+
}
|
|
36
|
+
options = options || {};
|
|
37
|
+
let userOptions = options;
|
|
38
|
+
if (!path) {
|
|
39
|
+
options = Object.assign({
|
|
40
|
+
deleteOnClose: true,
|
|
41
|
+
noSync: true,
|
|
42
|
+
}, options);
|
|
43
|
+
path = tmpdir() + '/' + Math.floor(Math.random() * 2821109907455).toString(36) + '.mdb'
|
|
44
|
+
} else if (!options)
|
|
45
|
+
options = {};
|
|
46
|
+
let extension = pathModule.extname(path);
|
|
47
|
+
let name = pathModule.basename(path, extension);
|
|
48
|
+
let is32Bit = arch().endsWith('32');
|
|
49
|
+
let remapChunks = options.remapChunks || (options.mapSize ?
|
|
50
|
+
(is32Bit && options.mapSize > 0x100000000) : // larger than fits in address space, must use dynamic maps
|
|
51
|
+
is32Bit); // without a known map size, we default to being able to handle large data correctly/well*/
|
|
52
|
+
options = Object.assign({
|
|
53
|
+
path,
|
|
54
|
+
noSubdir: Boolean(extension),
|
|
55
|
+
isRoot: true,
|
|
56
|
+
maxDbs: 12,
|
|
57
|
+
remapChunks,
|
|
58
|
+
keyBytes,
|
|
59
|
+
pageSize: 4096,
|
|
60
|
+
overlappingSync: (options.noSync || options.readOnly) ? false : (os != 'win32'),
|
|
61
|
+
// default map size limit of 4 exabytes when using remapChunks, since it is not preallocated and we can
|
|
62
|
+
// make it super huge.
|
|
63
|
+
mapSize: remapChunks ? 0x10000000000000 :
|
|
64
|
+
0x20000, // Otherwise we start small with 128KB
|
|
65
|
+
safeRestore: process.env.LMDB_RESTORE == 'safe',
|
|
66
|
+
}, options);
|
|
67
|
+
if (options.asyncTransactionOrder == 'strict') {
|
|
68
|
+
options.strictAsyncOrder = true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!exists(options.noSubdir ? pathModule.dirname(path) : path))
|
|
72
|
+
fs.mkdirSync(options.noSubdir ? pathModule.dirname(path) : path, { recursive: true }
|
|
73
|
+
);
|
|
74
|
+
function makeCompression(compressionOptions) {
|
|
75
|
+
if (compressionOptions instanceof Compression)
|
|
76
|
+
return compressionOptions;
|
|
77
|
+
let useDefault = typeof compressionOptions != 'object';
|
|
78
|
+
if (useDefault && defaultCompression)
|
|
79
|
+
return defaultCompression;
|
|
80
|
+
compressionOptions = Object.assign({
|
|
81
|
+
threshold: 1000,
|
|
82
|
+
dictionary: fs.readFileSync(new URL('./dict/dict.txt', import.meta.url.replace(/dist[\\\/]index.cjs$/, ''))),
|
|
83
|
+
getValueBytes: makeReusableBuffer(0),
|
|
84
|
+
}, compressionOptions);
|
|
85
|
+
let compression = Object.assign(new Compression(compressionOptions), compressionOptions);
|
|
86
|
+
if (useDefault)
|
|
87
|
+
defaultCompression = compression;
|
|
88
|
+
return compression;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (options.compression)
|
|
92
|
+
options.compression = makeCompression(options.compression);
|
|
93
|
+
let flags =
|
|
94
|
+
(options.overlappingSync ? 0x1000 : 0) |
|
|
95
|
+
(options.noSubdir ? 0x4000 : 0) |
|
|
96
|
+
(options.noSync ? 0x10000 : 0) |
|
|
97
|
+
(options.readOnly ? 0x20000 : 0) |
|
|
98
|
+
(options.noMetaSync ? 0x40000 : 0) |
|
|
99
|
+
(options.useWritemap ? 0x80000 : 0) |
|
|
100
|
+
(options.mapAsync ? 0x100000 : 0) |
|
|
101
|
+
(options.noReadAhead ? 0x800000 : 0) |
|
|
102
|
+
(options.noMemInit ? 0x1000000 : 0) |
|
|
103
|
+
(options.usePreviousSnapshot ? 0x2000000 : 0) |
|
|
104
|
+
(options.remapChunks ? 0x4000000 : 0) |
|
|
105
|
+
(options.safeRestore ? 0x8000000 : 0);
|
|
106
|
+
|
|
107
|
+
let env = new Env();
|
|
108
|
+
let jsFlags = (options.overlappingSync ? 0x1000 : 0) |
|
|
109
|
+
(options.separateFlushed ? 1 : 0) |
|
|
110
|
+
(options.deleteOnClose ? 2 : 0)
|
|
111
|
+
let rc = env.open(options, flags, jsFlags);
|
|
112
|
+
if (rc)
|
|
113
|
+
lmdbError(rc);
|
|
114
|
+
let maxKeySize = env.getMaxKeySize();
|
|
115
|
+
maxKeySize = Math.min(maxKeySize, MAX_KEY_SIZE);
|
|
116
|
+
flags = getEnvFlags(env.address); // re-retrieve them, they are not necessarily the same if we are connecting to an existing env
|
|
117
|
+
if (flags & 0x1000) {
|
|
118
|
+
if (userOptions.noSync) {
|
|
119
|
+
env.close();
|
|
120
|
+
throw new Error('Can not set noSync on a database that was opened with overlappingSync');
|
|
121
|
+
}
|
|
122
|
+
} else if (options.overlappingSync) {
|
|
123
|
+
if (userOptions.overlappingSync) {
|
|
124
|
+
env.close();
|
|
125
|
+
throw new Error('Can not enable overlappingSync on a database that was opened without this flag');
|
|
126
|
+
}
|
|
127
|
+
options.overlappingSync = false;
|
|
128
|
+
jsFlags = jsFlags & 0xff; // clear overlapping sync
|
|
129
|
+
setJSFlags(env.address, jsFlags);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
env.readerCheck(); // clear out any stale entries
|
|
133
|
+
let stores = [];
|
|
134
|
+
if ((options.overlappingSync || options.deleteOnClose) && !hasRegisteredOnExit && process.on) {
|
|
135
|
+
hasRegisteredOnExit = true;
|
|
136
|
+
process.on('exit', onExit);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class LMDBStore extends EventEmitter {
|
|
140
|
+
constructor(dbName, dbOptions) {
|
|
141
|
+
super();
|
|
142
|
+
if (dbName === undefined)
|
|
143
|
+
throw new Error('Database name must be supplied in name property (may be null for root database)');
|
|
144
|
+
|
|
145
|
+
if (options.compression && dbOptions.compression !== false && typeof dbOptions.compression != 'object')
|
|
146
|
+
dbOptions.compression = options.compression; // use the parent compression if available
|
|
147
|
+
else if (dbOptions.compression)
|
|
148
|
+
dbOptions.compression = makeCompression(dbOptions.compression);
|
|
149
|
+
|
|
150
|
+
if (dbOptions.dupSort && (dbOptions.useVersions || dbOptions.cache)) {
|
|
151
|
+
throw new Error('The dupSort flag can not be combined with versions or caching');
|
|
152
|
+
}
|
|
153
|
+
let keyIsBuffer = dbOptions.keyIsBuffer
|
|
154
|
+
if (dbOptions.keyEncoding == 'uint32') {
|
|
155
|
+
dbOptions.keyIsUint32 = true;
|
|
156
|
+
} else if (dbOptions.keyEncoder) {
|
|
157
|
+
if (dbOptions.keyEncoder.enableNullTermination) {
|
|
158
|
+
dbOptions.keyEncoder.enableNullTermination()
|
|
159
|
+
} else
|
|
160
|
+
keyIsBuffer = true;
|
|
161
|
+
} else if (dbOptions.keyEncoding == 'binary') {
|
|
162
|
+
keyIsBuffer = true;
|
|
163
|
+
}
|
|
164
|
+
let flags = (dbOptions.reverseKey ? 0x02 : 0) |
|
|
165
|
+
(dbOptions.dupSort ? 0x04 : 0) |
|
|
166
|
+
(dbOptions.dupFixed ? 0x10 : 0) |
|
|
167
|
+
(dbOptions.integerDup ? 0x20 : 0) |
|
|
168
|
+
(dbOptions.reverseDup ? 0x40 : 0) |
|
|
169
|
+
(!options.readOnly && dbOptions.create !== false ? 0x40000 : 0) |
|
|
170
|
+
(dbOptions.useVersions ? 0x1000 : 0);
|
|
171
|
+
let keyType = (dbOptions.keyIsUint32 || dbOptions.keyEncoding == 'uint32') ? 2 : keyIsBuffer ? 3 : 0;
|
|
172
|
+
if (keyType == 2)
|
|
173
|
+
flags |= 0x08; // integer key
|
|
174
|
+
|
|
175
|
+
if (options.readOnly) {
|
|
176
|
+
// in read-only mode we use a read-only txn to open the database
|
|
177
|
+
// TODO: LMDB is actually not entire thread-safe when it comes to opening databases with
|
|
178
|
+
// read-only transactions since there is a race condition on setting the update dbis that
|
|
179
|
+
// occurs outside the lock
|
|
180
|
+
// make sure we are using a fresh read txn, so we don't want to share with a cursor txn
|
|
181
|
+
this.resetReadTxn();
|
|
182
|
+
this.ensureReadTxn();
|
|
183
|
+
this.db = new Dbi(env, flags, dbName, keyType, dbOptions.compression);
|
|
184
|
+
} else {
|
|
185
|
+
this.transactionSync(() => {
|
|
186
|
+
this.db = new Dbi(env, flags, dbName, keyType, dbOptions.compression);
|
|
187
|
+
}, options.overlappingSync ? 0x10002 : 2); // no flush-sync, but synchronously commit
|
|
188
|
+
}
|
|
189
|
+
this._commitReadTxn(); // current read transaction becomes invalid after opening another db
|
|
190
|
+
if (!this.db || this.db.dbi == 0xffffffff) {// not found
|
|
191
|
+
throw new Error('Database not found')
|
|
192
|
+
}
|
|
193
|
+
this.dbAddress = this.db.address
|
|
194
|
+
this.db.name = dbName || null;
|
|
195
|
+
this.name = dbName;
|
|
196
|
+
this.status = 'open';
|
|
197
|
+
this.env = env;
|
|
198
|
+
this.reads = 0;
|
|
199
|
+
this.writes = 0;
|
|
200
|
+
this.transactions = 0;
|
|
201
|
+
this.averageTransactionTime = 5;
|
|
202
|
+
if (dbOptions.syncBatchThreshold)
|
|
203
|
+
console.warn('syncBatchThreshold is no longer supported');
|
|
204
|
+
if (dbOptions.immediateBatchThreshold)
|
|
205
|
+
console.warn('immediateBatchThreshold is no longer supported');
|
|
206
|
+
this.commitDelay = DEFAULT_COMMIT_DELAY;
|
|
207
|
+
Object.assign(this, { // these are the options that are inherited
|
|
208
|
+
path: options.path,
|
|
209
|
+
encoding: options.encoding,
|
|
210
|
+
strictAsyncOrder: options.strictAsyncOrder,
|
|
211
|
+
}, dbOptions);
|
|
212
|
+
let Encoder;
|
|
213
|
+
if (this.encoder && this.encoder.Encoder) {
|
|
214
|
+
Encoder = this.encoder.Encoder;
|
|
215
|
+
this.encoder = null; // don't copy everything from the module
|
|
216
|
+
}
|
|
217
|
+
if (!Encoder && !(this.encoder && this.encoder.encode) && (!this.encoding || this.encoding == 'msgpack' || this.encoding == 'cbor')) {
|
|
218
|
+
Encoder = (this.encoding == 'cbor' ? moduleRequire('cbor-x').Encoder : MsgpackrEncoder);
|
|
219
|
+
}
|
|
220
|
+
if (Encoder) {
|
|
221
|
+
this.encoder = new Encoder(Object.assign(
|
|
222
|
+
assignConstrainedProperties(['copyBuffers', 'getStructures', 'saveStructures', 'useFloat32', 'useRecords', 'structuredClone', 'variableMapSize', 'useTimestamp32', 'largeBigIntToFloat', 'encodeUndefinedAsNil', 'int64AsNumber', 'onInvalidDate', 'mapsAsObjects', 'useTag259ForMaps', 'pack', 'maxSharedStructures', 'shouldShareStructure'],
|
|
223
|
+
this.sharedStructuresKey ? this.setupSharedStructures() : {
|
|
224
|
+
copyBuffers: true, // need to copy any embedded buffers that are found since we use unsafe buffers
|
|
225
|
+
}, options, dbOptions), this.encoder));
|
|
226
|
+
}
|
|
227
|
+
if (this.encoding == 'json') {
|
|
228
|
+
this.encoder = {
|
|
229
|
+
encode: JSON.stringify,
|
|
230
|
+
};
|
|
231
|
+
} else if (this.encoder) {
|
|
232
|
+
this.decoder = this.encoder;
|
|
233
|
+
this.decoderCopies = !this.encoder.needsStableBuffer
|
|
234
|
+
}
|
|
235
|
+
this.maxKeySize = maxKeySize;
|
|
236
|
+
applyKeyHandling(this);
|
|
237
|
+
allDbs.set(dbName ? name + '-' + dbName : name, this);
|
|
238
|
+
stores.push(this);
|
|
239
|
+
}
|
|
240
|
+
openDB(dbName, dbOptions) {
|
|
241
|
+
if (this.dupSort && this.name == null)
|
|
242
|
+
throw new Error('Can not open named databases if the main database is dupSort')
|
|
243
|
+
if (typeof dbName == 'object' && !dbOptions) {
|
|
244
|
+
dbOptions = dbName;
|
|
245
|
+
dbName = dbOptions.name;
|
|
246
|
+
} else
|
|
247
|
+
dbOptions = dbOptions || {};
|
|
248
|
+
try {
|
|
249
|
+
return dbOptions.cache ?
|
|
250
|
+
new (CachingStore(LMDBStore, env))(dbName, dbOptions) :
|
|
251
|
+
new LMDBStore(dbName, dbOptions);
|
|
252
|
+
} catch(error) {
|
|
253
|
+
if (error.message == 'Database not found')
|
|
254
|
+
return; // return undefined to indicate db not found
|
|
255
|
+
if (error.message.indexOf('MDB_DBS_FULL') > -1) {
|
|
256
|
+
error.message += ' (increase your maxDbs option)';
|
|
257
|
+
}
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
open(dbOptions, callback) {
|
|
262
|
+
let db = this.openDB(dbOptions);
|
|
263
|
+
if (callback)
|
|
264
|
+
callback(null, db);
|
|
265
|
+
return db;
|
|
266
|
+
}
|
|
267
|
+
backup(path) {
|
|
268
|
+
return new Promise((resolve, reject) => env.copy(path, false, (error) => {
|
|
269
|
+
if (error) {
|
|
270
|
+
reject(error);
|
|
271
|
+
} else {
|
|
272
|
+
resolve();
|
|
273
|
+
}
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
isOperational() {
|
|
277
|
+
return this.status == 'open';
|
|
278
|
+
}
|
|
279
|
+
sync(callback) {
|
|
280
|
+
return env.sync(callback || function(error) {
|
|
281
|
+
if (error) {
|
|
282
|
+
console.error(error);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
deleteDB() {
|
|
287
|
+
console.warn('deleteDB() is deprecated, use drop or dropSync instead');
|
|
288
|
+
return this.dropSync();
|
|
289
|
+
}
|
|
290
|
+
dropSync() {
|
|
291
|
+
this.transactionSync(() =>
|
|
292
|
+
this.db.drop({
|
|
293
|
+
justFreePages: false
|
|
294
|
+
}), options.overlappingSync ? 0x10002 : 2);
|
|
295
|
+
}
|
|
296
|
+
clear(callback) {
|
|
297
|
+
if (typeof callback == 'function')
|
|
298
|
+
return this.clearAsync(callback);
|
|
299
|
+
console.warn('clear() is deprecated, use clearAsync or clearSync instead');
|
|
300
|
+
this.clearSync();
|
|
301
|
+
}
|
|
302
|
+
clearSync() {
|
|
303
|
+
if (this.encoder) {
|
|
304
|
+
if (this.encoder.clearSharedData)
|
|
305
|
+
this.encoder.clearSharedData()
|
|
306
|
+
else if (this.encoder.structures)
|
|
307
|
+
this.encoder.structures = []
|
|
308
|
+
}
|
|
309
|
+
this.transactionSync(() =>
|
|
310
|
+
this.db.drop({
|
|
311
|
+
justFreePages: true
|
|
312
|
+
}), options.overlappingSync ? 0x10002 : 2);
|
|
313
|
+
}
|
|
314
|
+
readerCheck() {
|
|
315
|
+
return env.readerCheck();
|
|
316
|
+
}
|
|
317
|
+
readerList() {
|
|
318
|
+
return env.readerList().join('');
|
|
319
|
+
}
|
|
320
|
+
setupSharedStructures() {
|
|
321
|
+
const getStructures = () => {
|
|
322
|
+
let lastVersion; // because we are doing a read here, we may need to save and restore the lastVersion from the last read
|
|
323
|
+
if (this.useVersions)
|
|
324
|
+
lastVersion = getLastVersion();
|
|
325
|
+
let buffer = this.getBinary(this.sharedStructuresKey);
|
|
326
|
+
if (this.useVersions)
|
|
327
|
+
setLastVersion(lastVersion);
|
|
328
|
+
return buffer && this.decoder.decode(buffer);
|
|
329
|
+
};
|
|
330
|
+
return {
|
|
331
|
+
saveStructures: (structures, isCompatible) => {
|
|
332
|
+
return this.transactionSync(() => {
|
|
333
|
+
let existingStructuresBuffer = this.getBinary(this.sharedStructuresKey);
|
|
334
|
+
let existingStructures = existingStructuresBuffer && this.decoder.decode(existingStructuresBuffer);
|
|
335
|
+
if (typeof isCompatible == 'function' ?
|
|
336
|
+
!isCompatible(existingStructures) :
|
|
337
|
+
(existingStructures && existingStructures.length != isCompatible))
|
|
338
|
+
return false; // it changed, we need to indicate that we couldn't update
|
|
339
|
+
this.put(this.sharedStructuresKey, structures);
|
|
340
|
+
}, options.overlappingSync ? 0x10000 : 0);
|
|
341
|
+
},
|
|
342
|
+
getStructures,
|
|
343
|
+
copyBuffers: true, // need to copy any embedded buffers that are found since we use unsafe buffers
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// if caching class overrides putSync, don't want to double call the caching code
|
|
348
|
+
const putSync = LMDBStore.prototype.putSync;
|
|
349
|
+
const removeSync = LMDBStore.prototype.removeSync;
|
|
350
|
+
addReadMethods(LMDBStore, { env, maxKeySize, keyBytes, keyBytesView, getLastVersion });
|
|
351
|
+
if (!options.readOnly)
|
|
352
|
+
addWriteMethods(LMDBStore, { env, maxKeySize, fixedBuffer: keyBytes,
|
|
353
|
+
resetReadTxn: LMDBStore.prototype.resetReadTxn, ...options });
|
|
354
|
+
LMDBStore.prototype.supports = {
|
|
355
|
+
permanence: true,
|
|
356
|
+
bufferKeys: true,
|
|
357
|
+
promises: true,
|
|
358
|
+
snapshots: true,
|
|
359
|
+
clear: true,
|
|
360
|
+
status: true,
|
|
361
|
+
deferredOpen: true,
|
|
362
|
+
openCallback: true,
|
|
363
|
+
};
|
|
364
|
+
let Class = options.cache ? CachingStore(LMDBStore, env) : LMDBStore;
|
|
365
|
+
return options.asClass ? Class : new Class(options.name || null, options);
|
|
366
|
+
}
|
|
367
|
+
export function openAsClass(path, options) {
|
|
368
|
+
if (typeof path == 'object' && !options) {
|
|
369
|
+
options = path;
|
|
370
|
+
path = options.path;
|
|
371
|
+
}
|
|
372
|
+
options = options || {};
|
|
373
|
+
options.asClass = true;
|
|
374
|
+
return open(path, options);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function getLastVersion() {
|
|
378
|
+
return keyBytesView.getFloat64(16, true);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export function setLastVersion(version) {
|
|
382
|
+
return keyBytesView.setFloat64(16, version, true);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const KEY_BUFFER_SIZE = 4096;
|
|
386
|
+
function allocateFixedBuffer() {
|
|
387
|
+
keyBytes = typeof Buffer != 'undefined' ? Buffer.allocUnsafeSlow(KEY_BUFFER_SIZE) : new Uint8Array(KEY_BUFFER_SIZE);
|
|
388
|
+
const keyBuffer = keyBytes.buffer;
|
|
389
|
+
keyBytesView = keyBytes.dataView || (keyBytes.dataView = new DataView(keyBytes.buffer, 0, KEY_BUFFER_SIZE)); // max key size is actually 4026
|
|
390
|
+
keyBytes.uint32 = new Uint32Array(keyBuffer, 0, KEY_BUFFER_SIZE >> 2);
|
|
391
|
+
keyBytes.float64 = new Float64Array(keyBuffer, 0, KEY_BUFFER_SIZE >> 3);
|
|
392
|
+
keyBytes.uint32.address = keyBytes.address = keyBuffer.address = getAddress(keyBytes);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function exists(path) {
|
|
396
|
+
if (fs.existsSync)
|
|
397
|
+
return fs.existsSync(path);
|
|
398
|
+
try {
|
|
399
|
+
return fs.statSync(path);
|
|
400
|
+
} catch (error) {
|
|
401
|
+
return false
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function assignConstrainedProperties(allowedProperties, target) {
|
|
406
|
+
for (let i = 2; i < arguments.length; i++) {
|
|
407
|
+
let source = arguments[i];
|
|
408
|
+
for (let key in source) {
|
|
409
|
+
if (allowedProperties.includes(key))
|
|
410
|
+
target[key] = source[key];
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return target;
|
|
414
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ohos-ports/lmdb",
|
|
3
|
+
"author": "Kris Zyp",
|
|
4
|
+
"version": "2.5.3-beta.0",
|
|
5
|
+
"description": "Simple, efficient, scalable, high-performance LMDB interface (HarmonyOS arm64 port)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ohos-ports/ohos-ports.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ohos-ports/ohos-ports/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/ohos-ports/ohos-ports#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"lmdb",
|
|
17
|
+
"database",
|
|
18
|
+
"mdb",
|
|
19
|
+
"lightning",
|
|
20
|
+
"key-value store",
|
|
21
|
+
"storage",
|
|
22
|
+
"adapter",
|
|
23
|
+
"performance",
|
|
24
|
+
"harmonyos",
|
|
25
|
+
"ohos"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "dist/index.cjs",
|
|
29
|
+
"module": "index.js",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"node": {
|
|
33
|
+
"require": "./dist/index.cjs",
|
|
34
|
+
"import": "./node-index.js"
|
|
35
|
+
},
|
|
36
|
+
"default": "./index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"/dist",
|
|
41
|
+
"/util",
|
|
42
|
+
"/dict",
|
|
43
|
+
"/dependencies",
|
|
44
|
+
"/src",
|
|
45
|
+
"/build/Release/lmdb.node",
|
|
46
|
+
"*.md",
|
|
47
|
+
"/*.js",
|
|
48
|
+
"index.d.ts",
|
|
49
|
+
"/*.ts",
|
|
50
|
+
"/*.gyp"
|
|
51
|
+
],
|
|
52
|
+
"types": "./index.d.ts",
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "node-gyp configure && node-gyp build && rollup -c",
|
|
55
|
+
"rebuild": "node-gyp build && rollup -c",
|
|
56
|
+
"build-js": "rollup -c",
|
|
57
|
+
"recompile": "node-gyp clean && node-gyp configure && node-gyp build",
|
|
58
|
+
"test": "mocha test/**.test.js --recursive && npm run test:types",
|
|
59
|
+
"benchmark": "node ./benchmark/index.js"
|
|
60
|
+
},
|
|
61
|
+
"gypfile": false,
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"msgpackr": "^1.5.4",
|
|
64
|
+
"node-addon-api": "^4.3.0",
|
|
65
|
+
"node-gyp-build-optional-packages": "5.0.3",
|
|
66
|
+
"ordered-binary": "^1.2.4",
|
|
67
|
+
"weak-lru-cache": "^1.2.2"
|
|
68
|
+
},
|
|
69
|
+
"optionalDependencies": {}
|
|
70
|
+
}
|