Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
23c7a30
cli: fix start and end arguments
maxlath Apr 20, 2018
56d5b72
readme: removing disable cli command
maxlath Apr 20, 2018
f583788
cli: add a line format option
maxlath Apr 20, 2018
2f74975
cli: exit with a non-zero code when an error occurs
maxlath Apr 21, 2018
96f1966
cli: fixed batch command by parsing the batch operations JSON
maxlath Apr 21, 2018
fa0462a
typo
maxlath Apr 21, 2018
66a33a2
cli: fixed '--match' range limit
maxlath Apr 21, 2018
89d1c9c
cli: remove unnecessary padding lines in tabular mode
maxlath Apr 21, 2018
17f0e6f
readme: documenting missing CLI commands and adding examples
maxlath Apr 21, 2018
742ffc2
cli: fixed and renamed '--createReadStream' into '--stream'
maxlath Apr 21, 2018
35a00b0
cli: reordering commands
maxlath Apr 21, 2018
21595cb
cli: refactoring valueEncoding
maxlath Apr 21, 2018
c451b54
adding missing semicolons
maxlath Apr 21, 2018
5cefa88
cli: refactoring --stream (renamed --all), --match, --keys, and --val…
maxlath Apr 21, 2018
105790f
cli: added command --length
maxlath Apr 21, 2018
44e670d
readme: updated match examples
maxlath Apr 21, 2018
c00e273
readme: improving --batch documentation
maxlath Apr 22, 2018
0b0fb6d
cli: improving performance by requesting both keys and values only if…
maxlath Apr 22, 2018
3b573ea
readme: improved --length doc
maxlath Apr 22, 2018
9dee398
cli: batch: added the possibility to pass operations as a file path
maxlath Apr 24, 2018
a7ec7c9
location: prevent creating a database in a non-database file
maxlath Apr 24, 2018
6948431
cli: refactor --batch from file to accept large inputs
maxlath Apr 29, 2018
dbf16d9
cli: let the --batch option take a --del flag to delete by range
maxlath May 1, 2018
a6bc1b1
cli: default to --all when --start, --end or --limit args are set
maxlath May 1, 2018
28ae32f
cli: add --map option
maxlath May 2, 2018
a0071f2
cli: fix limit when used with --map
maxlath May 2, 2018
af62c96
locate: ask for confirmation before creating a new database
maxlath May 8, 2018
81fc85c
package: updated minimatch (vulnerability)
maxlath May 8, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 180 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,198 @@ These all match the parameters used with
[`levelup`](https://github.com/rvagg/node-levelup). The default encoding
for the database is set to `json`.

## --start <key-pattern>
Specify the start of the current range. You can also use `gt` or `gte`.
## --get <key>
Get a value
```sh
lev --get foo
```

## --end <key-pattern>
Specify the end of the current range. You can also use `lt` and `lte`.
## --put <key>
Put a value
```sh
lev --put foo --value bar
```

## --del <key>
Delete a value
```sh
lev --del foo
```

## --batch <operations>
Put or delete several values, using [`levelup` batch syntax](https://github.com/Level/levelup#dbbatcharray-options-callback-array-form)
```sh
lev --batch '[
{"type":"del","key":"father"},
{"type":"put","key":"name","value":"Yuri Irsenovich Kim"},
{"type":"put","key":"dob","value":"16 February 1941"},
{"type":"put","key":"spouse","value":"Kim Young-sook"},
{"type":"put","key":"occupation","value":"Clown"}
]'
```
or from a file
```sh
# there should be one entry per line
# either as valid JSON
echo '[
{"type":"del","key":"father"},
{"type":"put","key":"name","value":"Yuri Irsenovich Kim"},
{"type":"put","key":"dob","value":"16 February 1941"},
{"type":"put","key":"spouse","value":"Kim Young-sook"},
{"type":"put","key":"occupation","value":"Clown"}
]' > ops.json
# or as newline-delimited JSON
echo '
{"type":"del","key":"father"}
{"type":"put","key":"name","value":"Yuri Irsenovich Kim"}
{"type":"put","key":"dob","value":"16 February 1941"}
{"type":"put","key":"spouse","value":"Kim Young-sook"}
{"type":"put","key":"occupation","value":"Clown"}
' > ops.json
lev --batch ./ops.json
```

### Import / Export
If the type is omitted, defaults to `put`, which allows to use the command to do imports/exports, in combination with [`--all`](#--all):
```sh
lev --all > leveldb.export
lev /tmp/my-new-db --batch leveldb.export
```
If it's a large export, you can compress it on the fly
```sh
lev --all | gzip -9 > leveldb.export.gz
gzip -dk leveldb.export.gz
lev /tmp/my-new-db --batch leveldb.export
```

### Delete by range
The `--batch` option can also be used to delete key/values by range in 2 steps:
```
# 1 - collect all the key/values to delete
lev --all --start 'foo' --end 'fooz' > ./to_delete
# 2 - pass the file as argument to the --batch option with a --del flag
lev --batch ./to_delete --del
```

## --keys
List all the keys in the current range. Will tabularize the output by default (see `--line`).
```sh
lev --keys
```

## --values
Only list the all of the values in the current range.
List all the values in the current range.
Emit as a new-line delimited stream of json.
```sh
lev --values
```

## --keys
Only list all of the keys in the current range. Will tabularize the output.
## --all
List all the keys and values in the current range.
Emit as a new-line delimited stream of json.
```sh
lev --all
```
It can be used to create an export of the database, to be imported with [`--batch`](#--batch)
```sh
lev --all > leveldb.export
lev /tmp/my-new-db --batch leveldb.export
```

## --keyEncoding <string>
Specify the encoding for the keys.
## --start <key-pattern>
Specify the start of the current range. You can also use `gt` or `gte`.
```sh
# output all keys after 'foo'
lev --keys --start 'foo'
# which is equivalent to
lev --keys --gte 'foo'
# the same for values
lev --values --start 'foo'
```

## --valueEncoding <string>
Specify the encoding for the values.
## --end <key-pattern>
Specify the end of the current range. You can also use `lt` and `lte`.
```sh
# output all keys before 'fooz'
lev --keys --end 'fooz'
# which is equivalent to
lev --keys --lte 'fooz'
# the same for values
lev --values --end 'fooz'
# output all keys between 'foo' and 'fooz'
lev --keys --start 'foo' --end 'fooz'
```

## --match <key-pattern>
Filter keys or values by a pattern applied on the key
```sh
lev --keys --match 'f*'
lev --values --match 'f*'
lev --all --match 'f*'
# Equivalent to
lev --match 'f*'
```

See [`minimatch` doc](https://github.com/isaacs/minimatch#readme) for patterns

## --limit <number>
Limit the number of records emitted in the current range.
```sh
lev --keys --limit 10
lev --values --start 'foo' --end 'fooz' --limit 100
lev --match 'f*' --limit 10
```

## --reverse
Reverse the stream.
```sh
lev --keys --reverse
lev --keys --start 'foo' --end 'fooz' --limit 100 --reverse
```

## --line
Output one key per line (instead of the default tabularized output)
```sh
lev --keys --line
```

## --length
Output the length of the current range
```sh
# Count all the key/value pairs in the database
lev --length
# Counts the keys and values between 'foo' and 'fooz'
lev --start 'foo' --end 'fooz' --length
```

## --valueEncoding <string>
Specify the encoding for the values (Defaults to 'json').
```sh
lev --values --valueEncoding buffer
```

## --location <string>
Specify the path to the LevelDB to use. Defaults to the current directory.
```sh
lev --location /tmp/test-db --keys
# Equivalent to
lev /tmp/test-db --keys
```

## --map <JS function string or path>
Pass streams results in a map function
* either inline
```sh
lev --keys --map 'key => key.split(":")[1]'
lev --all --map 'data => data.value.replace(data.key, "")'
```
* or from a JS file that exports a function
```js
# in ./map_fn.js
module.exports = key => key.split(":")[1]
```
```sh
lev --keys --map ./map_fn.js
```

If the function, returns null or undefined, the result is filtered-out
20 changes: 14 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,31 @@ module.exports = function(args) {
// find where the location by examining the arguments
// and create an instance to work with.
//
locate(args);
locate(args, function (err) {
if (err) {
console.error(err);
return process.exit(1);
}
init(args);
});
};

function init (args) {
var db = getDB(args);

//
// if any of these commands are specified as arguments
// than the program should not be run in REPL mode.
//
var cliCommands = [
'keys', 'values', 'get', 'match',
'put', 'del', 'createReadStream', 'batch'
'keys', 'values', 'get', 'match', 'put', 'del',
'all', 'batch', 'length', 'start', 'end', 'limit', 'map'
];

var cliMode = Object.keys(args).some(function(cmd) {
return cliCommands.indexOf(cmd) > -1;
});

if (cliMode) {
return cli(db, args);
}
Expand All @@ -39,6 +48,5 @@ module.exports = function(args) {

history(repl, args);
completion(repl, cache);

};

52 changes: 52 additions & 0 deletions lib/batch_from_file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
var fs = require('fs');
var path = require('path');
var split = require('split');
var printAndExit = require('./print_and_exit');

module.exports = function(db, file, del) {
var batch = [];
var total = 0;

fs.createReadStream(path.resolve(file))
.pipe(split())
.on('data', function(line) {
if (line[0] !== '{') return
line = line.replace(/,$/, '')

//
// add each line to the batch
//
var entry = JSON.parse(line);
entry.type = del ? 'del' : (entry.type || 'put');
batch.push(entry)

//
// run operations by batches of 10000 entries
//
if (batch.length >= 10000) {
var stream = this;
stream.pause();
db.batch(batch, function(err, val) {
if (err) return printAndExit(err, val);
total += batch.length
console.log('ops run:', total)
batch = [];
stream.resume();
})
}

})
.on('close', function() {
if (batch.length > 0) {
db.batch(batch, function(err, val) {
if (err) return printAndExit(err, val);
total += batch.length;
console.log('total ops:', total)
});
}
else {
console.log('total ops:', total)
}
})
}

2 changes: 1 addition & 1 deletion lib/cache.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* cahce.js
* cache.js
* save the keys from the readstream into an
* array so that they can be autocompleted and suggested.
*
Expand Down
Loading