// Any new return statements added here should call MakeWeak() on bufferHandle_, // if it is not empty. void CallbackOverride(SQLRETURN ret) { EOS_DEBUG_METHOD(); if (!SQL_SUCCEEDED(ret) && ret != SQL_NO_DATA) { if (!bufferHandle_.IsEmpty()) NanDisposePersistent(bufferHandle_); return CallbackErrorOverride(ret); } EOS_DEBUG(L"Final Result: %hi\n", ret); Handle<Value> argv[4]; argv[0] = NanUndefined(); if (totalLength_ != SQL_NO_TOTAL) argv[2] = NanNew<Number>(totalLength_); else argv[2] = NanUndefined(); argv[3] = NanNew<Boolean>(totalLength_ > bufferLength_ || (totalLength_ == SQL_NO_TOTAL && ret == SQL_SUCCESS_WITH_INFO)); if (ret == SQL_NO_DATA) argv[1] = NanUndefined(); else if (totalLength_ == SQL_NULL_DATA) argv[1] = NanNull(); else if (raw_) { assert(!bufferHandle_.IsEmpty()); argv[1] = NanNew(bufferHandle_); } else if (cType_ == SQL_C_BINARY) { if (totalLength_ >= bufferLength_) argv[1] = NanNew(bufferHandle_); else argv[1] = JSBuffer::Slice(NanNew(bufferHandle_), 0, totalLength_); } else { argv[1] = Eos::ConvertToJS(buffer_, totalLength_, bufferLength_, cType_); if (argv[1]->IsUndefined()) argv[0] = OdbcError("Unable to interpret contents of result buffer"); } // Can we Dispose() things that JS-land is referencing? We'll soon find out! if (!bufferHandle_.IsEmpty()) NanDisposePersistent(bufferHandle_); MakeCallback(argv); }
namespace mssql { // error returned when a string returns no data but it's not a NULL field // ODBC returns SQL_NO_DATA so we translate this into an error and return it to node.js OdbcError OdbcError::NODE_SQL_NO_DATA = OdbcError( "IMNOD", "No data returned", 1 ); }
OdbcExpected<bool> SqlLexer::Shift() { if (IsEod()) { SetEod(); return false; } TokenType::Type tokenType = TokenType::EOD; while (!IsEod()) { int32_t tokenBegin = pos; switch (sql[pos]) { case '-': { // Full-line comment. if (HaveData(1) && sql[pos + 1] == '-') { pos += 2; while (!IsEod() && sql[pos] != '\n' && sql[pos] != '\r') ++pos; continue; } // Minus. tokenType = TokenType::MINUS; break; } case '"': { // Quoted string. while (true) { ++pos; if (IsEod()) return OdbcError(SqlState::SHY000_GENERAL_ERROR, "Unclosed quoted identifier."); if (sql[pos] == '"') { if (!HaveData(2) || sql[pos + 1] != '"') break; ++pos; } } tokenType = TokenType::QUOTED; break; } case '\'': { // String literal. while (true) { ++pos; if (IsEod()) return OdbcError(SqlState::SHY000_GENERAL_ERROR, "Unclosed string literal."); if (sql[pos] == '\'') { if (!HaveData(2) || sql[pos + 1] != '\'') break; ++pos; } } tokenType = TokenType::STRING; break; } case '.': { tokenType = TokenType::DOT; break; } case ',': { tokenType = TokenType::COMMA; break; } case ';': { tokenType = TokenType::SEMICOLON; break; } case '(': { tokenType = TokenType::PARENTHESIS_LEFT; break; } case ')': { tokenType = TokenType::PARENTHESIS_RIGHT; break; } default: { // Skipping spaces. if (iscntrl(sql[pos]) || isspace(sql[pos])) { do { ++pos; } while (!IsEod() && (iscntrl(sql[pos]) || isspace(sql[pos]))); continue; } // Word. while (!IsEod() && !IsDelimiter(sql[pos])) ++pos; --pos; tokenType = TokenType::WORD; break; } } ++pos; if (tokenType != TokenType::EOD) { currentToken = SqlToken(&sql[tokenBegin], pos - tokenBegin, tokenType); return true; } } SetEod(); return false; }