Skip to content

Commit 56b283c

Browse files
committed
implement db.getProperty() closes facebook#23
1 parent 3db0d9a commit 56b283c

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Tested & supported platforms
3636
* <a href="#leveldown_del"><code><b>leveldown#del()</b></code></a>
3737
* <a href="#leveldown_batch"><code><b>leveldown#batch()</b></code></a>
3838
* <a href="#leveldown_approximateSize"><code><b>leveldown#approximateSize()</b></code></a>
39+
* <a href="#leveldown_getProperty"><code><b>leveldown#getProperty()</b></code></a>
3940
* <a href="#leveldown_iterator"><code><b>leveldown#iterator()</b></code></a>
4041
* <a href="#iterator_next"><code><b>iterator#next()</b></code></a>
4142
* <a href="#iterator_end"><code><b>iterator#end()</b></code></a>
@@ -157,6 +158,20 @@ The `start` and `end` parameters may be either `String` or Node.js `Buffer` obje
157158
The `callback` function will be called with no arguments if the operation is successful or with a single `error` argument if the operation failed for any reason.
158159

159160

161+
--------------------------------------------------------
162+
<a name="leveldown_getProperty"></a>
163+
### leveldown#getProperty(property)
164+
<code>getProperty</code> can be used to get internal details from LevelDB. When issued with a valid property string, a readable string will be returned (this method is synchronous).
165+
166+
Currently, the only valid properties are:
167+
168+
* <b><code>'leveldb.num-files-at-levelN'</code></b>: return the number of files at level *N*, where N is an integer representing a valid level (e.g. "0").
169+
170+
* <b><code>'leveldb.stats'</code></b>: returns a multi-line string describing statistics about LevelDB's internal operation.
171+
172+
* <b><code>'leveldb.sstables'</code></b>: returns a multi-line string describing all of the *sstables* that make up contents of the current database.
173+
174+
160175
--------------------------------------------------------
161176
<a name="createIterator"></a>
162177
### leveldown#iterator([options])
@@ -294,4 +309,4 @@ Copyright (c) 2012-2013 LevelDOWN contributors (listed above).
294309

295310
LevelDOWN is licensed under an MIT +no-false-attribs license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
296311

297-
*LevelDOWN builds on the excellent work of the LevelDB and Snappy teams from Google and additional contributors. LevelDB and Snappy are both issued under the [New BSD Licence](http://opensource.org/licenses/BSD-3-Clause).*
312+
*LevelDOWN builds on the excellent work of the LevelDB and Snappy teams from Google and additional contributors. LevelDB and Snappy are both issued under the [New BSD Licence](http://opensource.org/licenses/BSD-3-Clause).*

src/database.cc

+37
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ uint64_t Database::ApproximateSizeFromDatabase (const leveldb::Range* range) {
7878
return size;
7979
}
8080

81+
void Database::GetPropertyFromDatabase (
82+
const leveldb::Slice& property
83+
, std::string* value) {
84+
db->GetProperty(property, value);
85+
}
86+
8187
leveldb::Iterator* Database::NewIterator (leveldb::ReadOptions* options) {
8288
return db->NewIterator(*options);
8389
}
@@ -149,6 +155,10 @@ void Database::Init () {
149155
v8::String::NewSymbol("approximateSize")
150156
, v8::FunctionTemplate::New(ApproximateSize)->GetFunction()
151157
);
158+
tpl->PrototypeTemplate()->Set(
159+
v8::String::NewSymbol("getProperty")
160+
, v8::FunctionTemplate::New(GetProperty)->GetFunction()
161+
);
152162
tpl->PrototypeTemplate()->Set(
153163
v8::String::NewSymbol("iterator")
154164
, v8::FunctionTemplate::New(Iterator)->GetFunction()
@@ -522,6 +532,33 @@ v8::Handle<v8::Value> Database::ApproximateSize (const v8::Arguments& args) {
522532
return v8::Undefined();
523533
}
524534

535+
v8::Handle<v8::Value> Database::GetProperty (const v8::Arguments& args) {
536+
v8::HandleScope scope;
537+
538+
v8::Local<v8::Value> propertyV = args[0];
539+
v8::Local<v8::Function> callback; // for LD_CB_ERR_IF_NULL_OR_UNDEFINED
540+
541+
if (!propertyV->IsString()) {
542+
LD_THROW_RETURN(getProperty() requires a valid `property` argument)
543+
}
544+
545+
LD_CB_ERR_IF_NULL_OR_UNDEFINED(propertyV, property)
546+
547+
LD_STRING_OR_BUFFER_TO_SLICE(property, propertyV, property)
548+
549+
leveldown::Database* database =
550+
node::ObjectWrap::Unwrap<leveldown::Database>(args.This());
551+
552+
std::string* value = new std::string();
553+
database->GetPropertyFromDatabase(property, value);
554+
v8::Local<v8::String> returnValue
555+
= v8::String::New(value->c_str(), value->length());
556+
delete value;
557+
delete property.data();
558+
559+
return returnValue;
560+
}
561+
525562
v8::Handle<v8::Value> Database::Iterator (const v8::Arguments& args) {
526563
v8::HandleScope scope;
527564

src/database.h

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class Database : public node::ObjectWrap {
7575
, leveldb::WriteBatch* batch
7676
);
7777
uint64_t ApproximateSizeFromDatabase (const leveldb::Range* range);
78+
void GetPropertyFromDatabase (const leveldb::Slice& property, std::string* value);
7879
leveldb::Iterator* NewIterator (leveldb::ReadOptions* options);
7980
const leveldb::Snapshot* NewSnapshot ();
8081
void ReleaseSnapshot (const leveldb::Snapshot* snapshot);
@@ -107,6 +108,7 @@ class Database : public node::ObjectWrap {
107108
LD_V8_METHOD( Write )
108109
LD_V8_METHOD( Iterator )
109110
LD_V8_METHOD( ApproximateSize )
111+
LD_V8_METHOD( GetProperty )
110112
};
111113

112114
} // namespace leveldown

test/getproperty-test.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const test = require('tap').test
2+
, testCommon = require('abstract-leveldown/testCommon')
3+
, leveldown = require('../')
4+
5+
var db
6+
7+
test('setUp common', testCommon.setUp)
8+
9+
test('setUp db', function (t) {
10+
db = leveldown(testCommon.location())
11+
db.open(t.end.bind(t))
12+
})
13+
14+
test('test argument-less getProperty() throws', function (t) {
15+
t.throws(
16+
db.getProperty.bind(db)
17+
, { name: 'Error', message: 'getProperty() requires a valid `property` argument' }
18+
, 'no-arg getProperty() throws'
19+
)
20+
t.end()
21+
})
22+
23+
test('test non-string getProperty() throws', function (t) {
24+
t.throws(
25+
db.getProperty.bind(db, {})
26+
, { name: 'Error', message: 'getProperty() requires a valid `property` argument' }
27+
, 'no-arg getProperty() throws'
28+
)
29+
t.end()
30+
})
31+
32+
test('test invalid getProperty() returns empty string', function (t) {
33+
t.equal(db.getProperty('foo'), '', 'invalid property')
34+
t.equal(db.getProperty('leveldb.foo'), '', 'invalid leveldb.* property')
35+
t.end()
36+
})
37+
38+
test('test invalid getProperty("leveldb.num-files-at-levelN") returns numbers', function (t) {
39+
for (var i = 0; i < 7; i++)
40+
t.equal(db.getProperty('leveldb.num-files-at-level' + i), '0', '"leveldb.num-files-at-levelN" === "0"')
41+
t.end()
42+
})
43+
44+
test('test invalid getProperty("leveldb.stats")', function (t) {
45+
t.ok(db.getProperty('leveldb.stats').split('\n').length > 3, 'leveldb.stats has > 3 newlines')
46+
t.end()
47+
})
48+
49+
test('test invalid getProperty("leveldb.sstables")', function (t) {
50+
var expected = [0,1,2,3,4,5,6].map(function (l) { return '--- level ' + l + ' ---' }).join('\n') + '\n'
51+
t.equal(db.getProperty('leveldb.sstables'), expected, 'leveldb.sstables')
52+
t.end()
53+
})
54+
55+
test('tearDown', function (t) {
56+
db.close(testCommon.tearDown.bind(null, t))
57+
})

0 commit comments

Comments
 (0)