Skip to content

Commit 78cfca4

Browse files
committed
cleanup pass on reader implementation
1 parent 0d885e5 commit 78cfca4

File tree

3 files changed

+31
-38
lines changed

3 files changed

+31
-38
lines changed

lib/oracle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ function Reader(handle) {
4444
this._rows = [];
4545
}
4646

47-
Reader.prototype.nextRows = function(cb, count) {
48-
this._handle.nextRows(cb, count);
47+
Reader.prototype.nextRows = function() {
48+
this._handle.nextRows.apply(this._handle, arguments);
4949
}
5050

5151
Reader.prototype.nextRow = function(cb) {

src/reader.cpp

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ uni::CallbackType Reader::NextRows(const uni::FunctionCallbackInfo& args) {
4848
Local<String> message = String::New(baton->error->c_str());
4949
UNI_THROW(Exception::Error(message));
5050
}
51+
if (baton->busy) {
52+
UNI_THROW(Exception::Error(String::New("invalid state: reader is busy with another nextRows call")));
53+
}
54+
baton->busy = true;
5155

5256
if (args.Length() > 1) {
5357
REQ_INT_ARG(0, count);
@@ -75,66 +79,53 @@ void Reader::EIO_NextRows(uv_work_t* req) {
7579
baton->rows = new vector<row_t*>();
7680
if (baton->done) return;
7781

78-
try {
79-
if(! baton->connection->getConnection()) {
80-
baton->error = new std::string("Connection already closed");
81-
return;
82-
}
83-
if (!baton->rs) {
82+
if (!baton->connection->getConnection()) {
83+
baton->error = new std::string("Connection already closed");
84+
return;
85+
}
86+
if (!baton->rs) {
87+
try {
8488
baton->stmt = baton->connection->getConnection()->createStatement(baton->sql);
8589
baton->stmt->setAutoCommit(baton->connection->getAutoCommit());
8690
baton->stmt->setPrefetchRowCount(baton->count);
8791
Connection::SetValuesOnStatement(baton->stmt, baton);
88-
if (baton->error) goto cleanup;
92+
if (baton->error) return;
8993

9094
int status = baton->stmt->execute();
91-
if(status != oracle::occi::Statement::RESULT_SET_AVAILABLE) {
95+
if (status != oracle::occi::Statement::RESULT_SET_AVAILABLE) {
9296
baton->error = new std::string("Connection already closed");
9397
return;
9498
}
9599
baton->rs = baton->stmt->getResultSet();
96-
Connection::CreateColumnsFromResultSet(baton->rs, baton, baton->columns);
97-
if (baton->error) goto cleanup;
98-
}
99-
100-
for (int i = 0; i < baton->count && baton->rs->next(); i++) {
101-
row_t* row = Connection::CreateRowFromCurrentResultSetRow(baton->rs, baton, baton->columns);
102-
if (baton->error) goto cleanup;
103-
baton->rows->push_back(row);
100+
} catch (oracle::occi::SQLException &ex) {
101+
baton->error = new string(ex.getMessage());
102+
return;
104103
}
105-
if (baton->rows->size() < (size_t)baton->count) baton->done = true;
106-
} catch(oracle::occi::SQLException &ex) {
107-
baton->error = new string(ex.getMessage());
108-
} catch (const exception& ex) {
109-
baton->error = new string(ex.what());
110-
} catch (...) {
111-
baton->error = new string("Unknown Error");
104+
Connection::CreateColumnsFromResultSet(baton->rs, baton, baton->columns);
105+
if (baton->error) return;
112106
}
113-
cleanup:
114-
// nothing for now, cleanup happens in destructor
115-
;
107+
for (int i = 0; i < baton->count && baton->rs->next(); i++) {
108+
row_t* row = Connection::CreateRowFromCurrentResultSetRow(baton->rs, baton, baton->columns);
109+
if (baton->error) return;
110+
baton->rows->push_back(row);
111+
}
112+
if (baton->rows->size() < (size_t)baton->count) baton->done = true;
116113
}
117114

118115
void Reader::EIO_AfterNextRows(uv_work_t* req, int status) {
119116
UNI_SCOPE(scope);
120117
ReaderBaton* baton = static_cast<ReaderBaton*>(req->data);
121118

119+
baton->busy = false;
122120
baton->connection->Unref();
123121
// transfer callback to local and dispose persistent handle
124122
// must be done before invoking callback because callback may set another callback into baton->callback
125123
Local<Function> cb = uni::Deref(baton->callback);
126124
baton->callback.Dispose();
127125

128-
try {
129-
Handle<Value> argv[2];
130-
Connection::handleResult(baton, argv);
131-
node::MakeCallback(Context::GetCurrent()->Global(), cb, 2, argv);
132-
} catch(const exception &ex) {
133-
Handle<Value> argv[2];
134-
argv[0] = Exception::Error(String::New(ex.what()));
135-
argv[1] = Undefined();
136-
node::MakeCallback(Context::GetCurrent()->Global(), cb, 2, argv);
137-
}
126+
Handle<Value> argv[2];
127+
Connection::handleResult(baton, argv);
128+
node::MakeCallback(Context::GetCurrent()->Global(), cb, 2, argv);
138129

139130
baton->ResetRows();
140131
if (baton->done || baton->error) {

src/readerBaton.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class ReaderBaton : public ExecuteBaton {
1111
stmt = NULL;
1212
rs = NULL;
1313
done = false;
14+
busy = false;
1415
}
1516
~ReaderBaton() {
1617
ResetStatement();
@@ -33,6 +34,7 @@ class ReaderBaton : public ExecuteBaton {
3334
oracle::occi::ResultSet* rs;
3435
int count;
3536
bool done;
37+
bool busy;
3638
};
3739

3840
#endif

0 commit comments

Comments
 (0)