kyoto-client – Kyoto Tycoon client for node.js
Introduction
kyoto-client is a node.js module that acts as a client to a Kyoto Tycoon server. Kyoto Tycoon is the server component of Kyoto Cabinet, a fast, efficient key-value store developed by FAL labs. Records can be stored on disk or in memory using a hash table or B+ tree.
Development
kyoto-client is implemented in CoffeeScript and uses nodeunit for
testing. Both are available via npm as coffee-script
and nodeunit
respectfully. It is developed against the current stable node.js version.
The primary documentation for the project is its website, the source of which is also included here. The website is built with nanoc. To get setup for making documentation changes you’ll need to install nanoc and some other RubyGems:
- From the doc directory run
bundle install
(assumes you have previously installed bundler). - Start the nanoc autocompiler with
bundle exec nanoc aco
and navigate to http://localhost:3000/.
Contributions are welcome and should maintain the existing coding style and be
accompanied by tests and documentation. Bugs and desired features are tracked
in the issue tracker. The tests can be run via cake test
.
Licence
kyoto-client is licenced under the BSD licence. Refer to the LICENCE in the repository for the full details.
API
DB
The DB class is the primary interface to a Kyoto Tycoon database.
◆ constructor new()
The constructor takes no arguments and returns a DB object.
Example
var kt = require('kyoto-client');
var db = new kt.Db();
◆ open open(hostname='localhost', port=1978)
Open a connection to the database.
Example
db.open();
// on a different host
db.open('kyoto.example.com');
◆ echo echo(input, callback)
Echo back the input data as the output data
Example
db.echo({test: "Value"}, function(error, output) {
// output -> {test: "Value"}
});
◆ report report(callback)
Get a report on the server.
-
callback(error, output)
Function – Callback function
Example
db.report(function(error, output) {
/* output ->
{ conf_kc_features: '(atomic)(zlib)'
, conf_kc_version: '1.2.30 (7.1)'
, conf_kt_features: '(kqueue)(lua)'
, conf_kt_version: '0.9.19 (1.25)'
, conf_os_name: 'Mac OS X'
, db_0: 'count=2 size=400128 path=tests.kct'
, db_total_count: '2'
, db_total_size: '400128'
, serv_conn: '1'
, serv_task: '0'
, sys_mem_peak: '2777088'
, sys_mem_rss: '2777088'
, sys_mem_size: '2777088'
, sys_proc_id: '70687'
, sys_ru_stime: '73.651796'
, sys_ru_utime: '90.519024'
, sys_time: '351491.752587'
}
*/
});
◆ playScript
Call a procedure of the script language (Lua) extension.
Not yet implemented.
◆ tuneReplication
Configure the replication configuration.
Not yet implemented.
◆ status status([database], callback)
Get the miscellaneous status information about a database.
-
database
String or Number – A database name or index. For example:test.kct
or1
. -
callback(error, output)
Function – Callback function
Example
db.status(function(error, output) {
/* output ->
{ apow: '8'
, bnum: '65536'
, chksum: '188'
, count: '2'
, cusage: '66'
, dfunit: '0'
, first: '1'
, flags: '1'
, fmtver: '5'
, fpow: '10'
, frgcnt: '0'
, icnt: '0'
, ktcapcnt: '-1'
, ktcapsiz: '-1'
, ktopts: '0'
, last: '1'
, lcnt: '1'
, librev: '1'
, libver: '7'
, msiz: '67108864'
, opts: '0'
, path: 'tests.kct'
, pccap: '67108864'
, pnum: '2'
, psiz: '8192'
, rcomp: 'lexical'
, realsize: '400128'
, realtype: '49'
, recovered: '0'
, reorganized: '0'
, root: '1'
, size: '400128'
, trimmed: '0'
, type: '49'
}
*/
});
◆ clear clear([database], callback)
Remove all records from the database.
-
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.clear(function(error, output) {
// output -> {}
});
◆ synchronize
Synchronize updated contents with the file and the device
Not yet implemented.
◆ set set(key, value, [database], callback)
Set value of a record.
-
key
String – The key of the record -
value
– String or Buffer – The value of the record -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error)
Function – Callback function-
error
Error – Set if an error occurs, otherwiseundefined
-
Example
db.set('test', "Value", function(error) {
});
◆ add add(key, value, [database], callback)
Set value of a record. Returns an error if the record already exists.
-
key
String – The key of the record -
value
– String or Buffer – The value of the record -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.add('test', "Value", function(error, output) {
// error -> undefined
});
// when value already exists
db.add('test', "Value", function(error, output) {
db.add('test', "Value", function(error, output) {
// error -> Error("Record exists")
// output -> { ERROR: 'DB: 6: record duplication: record duplication' }
});
});
◆ replace replace(key, value, [database], callback)
Replace the value of a record. Returns an error if the record does not exist.
-
key
String – The key of the record -
value
– String or Buffer – The value of the record -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.set('test', "Test", function(error, output) {
db.replace('test', "Value", function(error, output) {
// error -> undefined
// output -> {}
});
});
// when the record doesn't exist
db.replace('test', "Value", function(error, output) {
// error -> Error("Record does not exist")
// output -> { ERROR: 'DB: 7: no record: no record' }
});
◆ append append(key, value, [database], callback)
Append to the value of a record. Sets the record if it does not exist.
-
key
String – The key of the record -
value
– String or Buffer – The value to append to the record -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.set('test', "Test", function(error, output) {
db.append('test', " Value", function(error, output) {
// error -> undefined
// output -> {}
db.get('test', function(error, value) {
// value -> 'Test Value'
})
});
});
// when the record doesn't exist
db.append('test', "Value", function(error, output) {
// error -> Error("Record does not exist")
// output -> {}
db.get('test', function(error, value) {
// value -> 'Value'
})
});
◆ increment increment(key, num, [database], callback)
Increment the integer value of a compatible record. Sets the record if it does not exist.
Note: It appears that Kyoto Tycoon only allows records that were created
with increment
to be incremented. Attempts to use this procedure on records
set by other means results in an error (Kyoto Tycoon 0.9.29 (2.1) on Mac OS X
(Kyoto Cabinet 1.2.39)).
-
key
String – The key of the record -
num
– Number – The amount to increment the record by. Should be a positive or negative integer. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.increment('count', 1, function(error, output) {
// error -> undefined
// output -> { num: '1' }
db.increment('count', 1, function(error, output) {
// error -> undefined
// output -> { num: '2' }
});
});
// incrementing an incompatible record
db.set('incompatible', "1", function(error, output) {
db.increment('incompatible', 1, function(error, output) {
// error -> Error("The existing record was not compatible")
// output -> { ERROR: 'DB: 8: logical inconsistency: logical inconsistency' }
});
});
◆ incrementDouble incrementDouble(key, num, [database], callback)
Increment the double (floating point) value of a compatible record. Sets the record if it does not exist.
See note about compatible values in increment.
-
key
String – The key of the record -
num
– Number – The amount to increment the record by. Can be positive or negative. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
db.incrementDouble('count', 1.5, function(error, output) {
// error -> undefined
// output -> { num: '1.500000' }
db.incrementDouble('count', -0.25, function(error, output) {
// error -> undefined
// output -> { num: '1.250000' }
});
});
// incrementing an incompatible record
db.set('incompatible', "1", function(error, output) {
db.incrementDouble('incompatible', 1, function(error, output) {
// error -> Error("The existing record was not compatible")
// output -> { ERROR: 'DB: 8: logical inconsistency: logical inconsistency' }
});
});
◆ cas cas(key, oval, nval, [database], callback)
Performs a compare-and-swap operation. The value is only updated if the assumed existing value matches.
-
key
String – The key of the record -
oval
– String or Buffer – The assumed old value -
nval
– String or Buffer – The new value. Set tonull
to remove the record. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
// sets the new value when the old value matches
db.set('test', 'old', function() {
db.cas('test', 'old', 'new', function(error, output) {
db.get('test', function(error, value) {
// value -> 'new'
});
});
});
// doesn't set the new value when the old value differs
db.set('test', 'old', function() {
db.cas('test', 'not old', 'new', function(error, output) {
db.get('test', function(error, value) {
// value -> 'old'
});
});
});
// removes the record when the new value is null
db.set('test', 'old', function() {
db.cas('test', 'old', null, function(error, output) {
db.get('test', function(error, value) {
// value -> null
});
});
});
◆ remove remove(key, [database], callback)
Removes a record.
-
key
String – The key of the record to remove -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error)
Function – Callback function-
error
Error –undefined
if the record was successfully removed.
-
Example
db.set('test', "Value", function() {
db.remove('test', function(error) {
// error -> undefined
});
});
// Non-existent record
db.remove('non-existent', function(error) {
// error -> Error("Record not found")
});
◆ get get(key, [database], callback)
Get the value of a record. Returns null
if the record doesn’t exist.
-
key
String – The key of the record -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, value)
Function – Callback function
Example
db.set('test', "Value", function(error, output) {
db.get('test', function(error, value) {
// error -> undefined
// value -> Buffer("Value")
});
});
// Non-existent record
db.get('not here', function(error, value) {
// error -> undefined
// value -> null
});
◆ setBulk setBulk(records, [database], callback)
Set multiple records at once.
-
records
Object – The records to set with keys and values set appropriately. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
var records = {
bulk1: "Bulk\tValue",
bulk2: "Bulk Value 2"
};
db.setBulk(records, function(error, output) {
// output -> {num: '2'}
});
◆ removeBulk removeBulk(keys, [database], callback)
Remove multiple records at once.
-
keys
Array – An array of keys to remove -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, output)
Function – Callback function
Example
var records = {
bulk1: "Bulk\tValue",
bulk2: "Bulk Value 2"
};
db.setBulk(records, function(error, output) {
db.removeBulk(Object.keys(records), function(error, output) {
// output -> {num: '2'}
})
});
◆ getBulk getBulk(keys, [database], callback)
Retrieve multiple records at once.
-
keys
Array – An array of keys to retrieve -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, results)
Function – Callback function
Example
db.set('bulk1', "Bulk\tValue", function () {
db.set('bulk2', "Bulk Value 2", function() {
db.getBulk(['bulk1', 'bulk2', 'bulk3'], function(error, results) {
// error -> undefined
// results -> { bulk1: 'Bulk\tValue', bulk2: 'Bulk Value 2' }
});
});
});
◆ vacuum vacuum()
Not yet implemented.
◆ matchPrefix matchPrefix(prefix, [max], [database], callback)
Returns keys matching the supplied prefix.
Note: if 3 arguments are supplied they are assumed to be prefix
, max
and callback
.
-
prefix
String – The prefix to match keys against -
max
Number – The maximum number of results to return. If null or less than 0 then no limit is applied. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, results)
Function – Callback function
Example
var records = {
bulk1: "Bulk\tValue",
bulk2: "Bulk Value 2",
test: "Value",
tulk: "Value"
};
db.setBulk(records, function(error, output) {
db.matchprefix('bulk', function(error, output) {
// output -> ['bulk1', 'bulk2']
});
});
// with a limit
db.setBulk(this.records, function(error, output) {
return db.matchPrefix('bulk', 1, function(error, output) {
// output -> ['bulk1']
});
});
◆ matchRegex matchRegex(regex, [max], [database], callback)
Returns keys matching the supplied regular expression.
Note: if 3 arguments are supplied they are assumed to be prefix
, max
and callback
.
-
regex
String – The regex to match keys against. Note: It isn’t clear from the Kyoto Tycoon documentation what regular expression features are supported. It appears from some limited testing that character ranges (E.g.[0-9]
),'.'
,'*'
are supported but not'+'
. -
max
Number – The maximum number of results to return. If null or less than 0 then no limit is applied. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, results)
Function – Callback function
Example
var records = {
bulk1: "Bulk\tValue",
bulk2: "Bulk Value 2",
test: "Value",
tulk: "Value"
};
db.setBulk(records, function(error, output) {
db.matchRegex('[0-9]', function(error, output) {
// output -> ['bulk1', 'bulk2']
});
});
// with a limit
db.setBulk(this.records, function(error, output) {
return db.matchRegex('[0-9]', 1, function(error, output) {
// output -> ['bulk1']
});
});
◆ getCursor getCursor([key], callback)
Obtain a database cursor. A cursor allows you to scan forwards through the records in the database.
TODO: This needs to be amended to accept a database
Example
db.getCursor('bulk1', function(error, cursor) {
cursor.get(function(error, output) {
// output -> {key: 'bulk1', value: 'Some value'}
});
});
Cursor
A cursor allows the records of the database to be traversed. Depending on the
type of database this will either be in order of insertion or order determined
by a hashing function. A Cursor
object is retrieved via the getCursor
function.
◆ jump jump([key], [database], callback)
Jump the cursor to the specified record or the first record if no key is specified.
-
key
String – The key to start scanning from. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, value)
Function – Callback function
Example
// Jump to first record
cursor.jump(function(error, output) {
});
// Jump to a specific record
cursor.jump('test', function(error, output) {
});
◆ jumpBack jumpBack([key], [database], callback)
Jump the cursor to the specified record or the last record if no key is specified.
-
key
String – The key to start scanning from. -
database
String or Number – A database name or index. For example:'test.kct'
or1
. -
callback(error, value)
Function – Callback function
Example
// Jump to first record
cursor.jump(function(error, output) {
});
// Jump to a specific record
cursor.jump('test', function(error, output) {
});
◆ step step(callback)
Steps the cursor to the next record.
-
callback(error, value)
Function – Callback function
Example
// Jump to first record
cursor.jump(function(error, output) {
cursor.step(function(error, output) {
// cursor is now on the second record
});
});
◆ stepBack stepBack(callback)
Steps the cursor to the previous record.
-
callback(error, value)
Function – Callback function
Example
// Jump to last record
cursor.jumpBack(function(error, output) {
cursor.stepBack(function(error, output) {
// cursor is now on the second last record
});
});
◆ setValue setValue(value, [step], callback)
Sets the value of the current record and optionally steps to the next record.
-
value
String or Buffer – The new value for the record -
step
Boolean – Whentrue
step the cursor to the next record -
callback(error, value)
Function – Callback function
Example
cursor.setValue("New Value", function(error, output) {
// value updated
});
// set and step
cursor.setValue("New Value", true, function(error, output) {
// value updated
});
◆ remove remove(callback)
Remove the current record.
-
callback(error, value)
Function – Callback function
Example
cursor.remove(function(error, output) {
});
◆ getKey getKey([step], callback)
Get the key of the current record.
-
step
Boolean – Whentrue
step the cursor to the next record. -
callback(error, value)
Function – Callback function
Example
cursor.getKey(true, function(error, output) {
// output -> {key: 'test'}
});
◆ getValue getValue([step], callback)
Get the value of the current record.
-
step
Boolean – Whentrue
step the cursor to the next record. -
callback(error, value)
Function – Callback function
Example
cursor.getValue(true, function(error, output) {
// output -> {value: "Value"}
});
◆ get get([step], callback)
Get the key and value of the current record.
-
step
Boolean – Whentrue
step the cursor to the next record. -
callback(error, value)
Function – Callback function
Example
cursor.get(true, function(error, output) {
// output -> {key: 'test', value: "Value"}
});
◆ delete delete(callback)
Close the cursor’s connection invalidate it. it will not be valid for subsequent operations.
Note: delete
is a reserved word so the syntax for calling this procedure
is a little awkward. Refer to examples.
-
callback(error, value)
Function – Callback function
Example
cursor["delete"](true, function(error, output) {
// deleted
});
CoffeeScript Example
cursor.delete true, (error, output) ->
// deleted
◆ each each(callback)
Scan the cursor forward from its current record to the last record.
TODO: Add support for cancelling the traversal.
-
callback(error, output)
Function – Callback function, called for each record.
Example
var results = [];
cursor.each(function(error, output) {
if (output.key != null) {
results.push([output.key, output.value]);
} else {
console.log(require('util').inspect(results));
}
});
Changelog
0.1.0 –
Initial release.