Example #1
0
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);
    }
}