Skip to content
Browse files

Implement database#close()

  • Loading branch information...
1 parent 80be9da commit 60569c6898c9be30e9a6bbf7fffcb85810041516 @darashi darashi committed
Showing with 74 additions and 6 deletions.
  1. +4 −0 README.md
  2. +38 −0 src/nroonga.cc
  3. +5 −4 src/nroonga.h
  4. +27 −2 test/database.test.coffee
View
4 README.md
@@ -67,6 +67,10 @@ Send `command` to groonga. Block until results returned.
Asynchronously send `command` to groonga. Callback will be given two arguments `(error, data)`.
+### database.close()
+
+Close database. After `close` called, any API calls for the database raise an exception.
+
### License
LGPL 2.1 or later. See license/lgpl-2.1.txt.
View
38 src/nroonga.cc
@@ -21,6 +21,7 @@ void Database::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "commandString", Database::CommandString);
NODE_SET_PROTOTYPE_METHOD(t, "commandSyncString", Database::CommandSyncString);
+ NODE_SET_PROTOTYPE_METHOD(t, "close", Database::Close);
target->Set(String::NewSymbol("Database"), t->GetFunction());
}
@@ -35,6 +36,7 @@ Handle<Value> Database::New(const Arguments& args) {
}
Database *db = new Database();
+ db->closed = true;
grn_ctx *ctx = &db->context;
grn_ctx_init(ctx, 0);
if (args[0]->IsUndefined()) {
@@ -53,10 +55,38 @@ Handle<Value> Database::New(const Arguments& args) {
return ThrowException(Exception::TypeError(String::New("Bad parameter")));
}
+ db->closed = false;
db->Wrap(args.Holder());
return args.This();
}
+bool Database::Cleanup() {
+ if (grn_obj_close(&context, database) != GRN_SUCCESS) {
+ return false;
+ }
+ if (grn_ctx_fin(&context) != GRN_SUCCESS) {
+ return false;
+ }
+ this->closed = true;
+
+ return true;
+}
+
+Handle<Value> Database::Close(const Arguments& args) {
+ HandleScope scope;
+ Database *db = ObjectWrap::Unwrap<Database>(args.Holder());
+
+ if (db->closed) {
+ return ThrowException(Exception::Error(String::New("Database already closed")));
+ }
+
+ if (db->Cleanup()) {
+ return True();
+ } else {
+ return ThrowException(Exception::Error(String::New("Failed to close the database")));
+ }
+}
+
void Database::CommandWork(uv_work_t* req) {
Baton *baton = static_cast<Baton*>(req->data);
int rc = -1;
@@ -122,6 +152,10 @@ Handle<Value> Database::CommandString(const Arguments& args) {
}
}
+ if (db->closed) {
+ return ThrowException(Exception::Error(String::New("Database already closed")));
+ }
+
Baton* baton = new Baton();
baton->request.data = baton;
baton->callback = Persistent<Function>::New(callback);
@@ -153,6 +187,10 @@ Handle<Value> Database::CommandSyncString(const Arguments& args) {
int flags;
String::Utf8Value command(args[0]->ToString());
+ if (db->closed) {
+ return ThrowException(Exception::Error(String::New("Database already closed")));
+ }
+
rc = grn_ctx_send(ctx, *command, command.length(), 0);
if (rc < 0) {
return ThrowException(Exception::Error(String::New("grn_ctx_send returned error")));
View
9 src/nroonga.h
@@ -15,6 +15,8 @@ namespace nroonga {
class Database : ObjectWrap {
grn_ctx context;
grn_obj *database;
+ bool closed;
+
public:
static void Initialize(v8::Handle<v8::Object> target);
@@ -34,13 +36,12 @@ class Database : ObjectWrap {
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> CommandString(const v8::Arguments& args);
static v8::Handle<v8::Value> CommandSyncString(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Close(const v8::Arguments& args);
Database() : ObjectWrap() {
}
- void CleanupDatabase() {
- grn_ctx_fin(&context);
- }
+ bool Cleanup();
~Database() {
- CleanupDatabase();
+ Cleanup();
}
static void CommandWork(uv_work_t* req);
static void CommandAfter(uv_work_t* req);
View
29 test/database.test.coffee
@@ -11,6 +11,7 @@ temporaryDatabase = (callback) ->
try
callback(db)
finally
+ db.close()
fs.readdir tempdir, (err, files) ->
throw err if err?
re = RegExp('^' + databaseName)
@@ -57,11 +58,13 @@ withTestDatabase = (callback) ->
callback(db)
describe 'nroonga.Database', ->
- db = new nroonga.Database()
+ db = null
+ beforeEach ->
+ db = new nroonga.Database()
describe '#commandSync', ->
- status = db.commandSync('status')
it 'should return groonga results', ->
+ status = db.commandSync('status')
should.exist(status.version)
describe '#command', ->
@@ -71,6 +74,28 @@ describe 'nroonga.Database', ->
should.exist(data.version)
done()
+ describe 'duplicated #close call', ->
+ it 'should raise an exception', ->
+ db.close()
+ (->
+ db.close()
+ ).should.throw('Database already closed');
+
+ describe '#commandSync for closed database', ->
+ it 'should raise an exception', ->
+ db.close()
+ (->
+ db.commandSync 'status'
+ ).should.throw('Database already closed');
+
+ describe '#command for closed database', ->
+ it 'should return an error', ->
+ db.close()
+ (->
+ db.command 'status', (error, data) ->
+ # do nothing
+ ).should.throw('Database already closed');
+
describe 'empty database', ->
db = new nroonga.Database()

0 comments on commit 60569c6

Please sign in to comment.
Something went wrong with that request. Please try again.