static int fetchExecuteResult(struct nuodb *db, Statement *stmt, int64_t *rows_affected, int64_t *last_insert_id) { ResultSet *resultSet = 0; try { resultSet = stmt->getGeneratedKeys(); // NuoDB uses -1 as a flag for zero-rows-affected *rows_affected = std::max(0, stmt->getUpdateCount()); if (*rows_affected > 0 && resultSet->getMetaData()->getColumnCount() > 0) { while (resultSet->next()) { // TODO find out how to read the last id first } switch (resultSet->getMetaData()->getColumnType(1)) { case NUOSQL_TINYINT: case NUOSQL_SMALLINT: case NUOSQL_INTEGER: case NUOSQL_BIGINT: case NUOSQL_FLOAT: case NUOSQL_DOUBLE: case NUOSQL_NUMERIC: case NUOSQL_DECIMAL: *last_insert_id = resultSet->getLong(1); break; default: // This is to avoid a failure when trying to call resultSet->getLong() when // the generated column has a string type and a default sequence. If the user // passes a string that cannot be converted to long, an exception is thrown. // // Since this only happens when the string is user-provided, we don't need to // worry about trying to parse the returned value to return to the user. // // See TestStringSequence for more details. *last_insert_id = 0; break; } } else { *last_insert_id = 0; } resultSet->close(); return 0; } catch (SQLException &e) { if (resultSet) { resultSet->close(); } return setError(db, e); } }
static int fetchExecuteResult(struct nuodb *db, Statement *stmt, int64_t *rows_affected, int64_t *last_insert_id) { ResultSet *resultSet = 0; try { resultSet = stmt->getGeneratedKeys(); // NuoDB uses -1 as a flag for zero-rows-affected *rows_affected = std::max(0, stmt->getUpdateCount()); if (*rows_affected > 0 && resultSet->getMetaData()->getColumnCount() > 0) { while (resultSet->next()) { // TODO find out how to read the last id first } *last_insert_id = resultSet->getLong(1); } else { *last_insert_id = 0; } resultSet->close(); return 0; } catch (SQLException &e) { if (resultSet) { resultSet->close(); } return setError(db, e); } }
int nuodb_resultset_next(struct nuodb *db, struct nuodb_resultset *rs, int *has_values, struct nuodb_value values[]) { ResultSet *resultSet = reinterpret_cast<ResultSet *>(rs); try { *has_values = resultSet->next(); if (*has_values) { ResultSetMetaData *resultSetMetaData = resultSet->getMetaData(); int columnCount = resultSetMetaData->getColumnCount(); for (int i=0; i < columnCount; ++i) { int64_t i64 = 0; int32_t i32 = 0; enum nuodb_value_type vt = NUODB_TYPE_NULL; int columnIndex = i+1; switch (resultSetMetaData->getColumnType(columnIndex)) { case NUOSQL_NULL: vt = NUODB_TYPE_NULL; break; case NUOSQL_TINYINT: case NUOSQL_SMALLINT: case NUOSQL_INTEGER: case NUOSQL_BIGINT: if (resultSetMetaData->getScale(columnIndex) == 0) { i64 = resultSet->getLong(columnIndex); if (!resultSet->wasNull()) { vt = NUODB_TYPE_INT64; } break; } // fallthrough; must be fetched as a string case NUOSQL_NUMERIC: case NUOSQL_DECIMAL: { const char *string = resultSet->getString(columnIndex); if (!resultSet->wasNull()) { vt = NUODB_TYPE_BYTES; // strings are returned as bytes i64 = reinterpret_cast<int64_t>(string); i32 = std::strlen(string); } break; } case NUOSQL_FLOAT: case NUOSQL_DOUBLE: { union { double float64; int64_t i64; } value = { resultSet->getDouble(columnIndex) }; if (!resultSet->wasNull()) { vt = NUODB_TYPE_FLOAT64; i64 = value.i64; } break; } case NUOSQL_BIT: case NUOSQL_BOOLEAN: i64 = resultSet->getBoolean(columnIndex); if (!resultSet->wasNull()) { vt = NUODB_TYPE_BOOL; } break; case NUOSQL_DATE: case NUOSQL_TIME: case NUOSQL_TIMESTAMP: { Timestamp *ts = resultSet->getTimestamp(columnIndex); if (ts && !resultSet->wasNull()) { vt = NUODB_TYPE_TIME; i64 = ts->getSeconds(); i32 = ts->getNanos(); } break; } default: { const Bytes b = resultSet->getBytes(columnIndex); if (!resultSet->wasNull()) { vt = NUODB_TYPE_BYTES; i64 = reinterpret_cast<int64_t>(b.data); i32 = b.length; } break; } } values[i].i64 = i64; values[i].i32 = i32; values[i].vt = vt; } } return 0; } catch (SQLException &e) { return setError(db, e); } }