Struct odbc_api::CursorRow

source ·
pub struct CursorRow<'s> { /* private fields */ }
Expand description

An individual row of an result set. See crate::Cursor::next_row.

Implementations§

Fills a suitable target buffer with a field from the current row of the result set. This method drains the data from the field. It can be called repeatedly to if not all the data fit in the output buffer at once. It should not called repeatedly to fetch the same value twice. Column index starts at 1.

Examples found in repository?
src/cursor.rs (line 128)
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    pub fn get_text(&mut self, col_or_param_num: u16, buf: &mut Vec<u8>) -> Result<bool, Error> {
        // Utilize all of the allocated buffer. We must make sure buffer can at least hold the
        // terminating zero. We do a bit more than that though, to avoid to many repeated calls to
        // get_data.
        buf.resize(max(256, buf.capacity()), 0);
        // We repeatedly fetch data and add it to the buffer. The buffer length is therefore the
        // accumulated value size. This variable keeps track of the number of bytes we added with
        // the next call to get_data.
        let mut fetch_size = buf.len();
        let mut target = VarCharSliceMut::from_buffer(buf.as_mut_slice(), Indicator::Null);
        // Fetch binary data into buffer.
        self.get_data(col_or_param_num, &mut target)?;
        let not_null = loop {
            match target.indicator() {
                // Value is `NULL`. We are done here.
                Indicator::Null => {
                    buf.clear();
                    break false;
                }
                // We do not know how large the value is. Let's fetch the data with repeated calls
                // to get_data.
                Indicator::NoTotal => {
                    let old_len = buf.len();
                    // Use an exponential strategy for increasing buffer size.
                    buf.resize(old_len * 2, 0);
                    let buf_extend = &mut buf[(old_len - 1)..];
                    fetch_size = buf_extend.len();
                    target = VarCharSliceMut::from_buffer(buf_extend, Indicator::Null);
                    self.get_data(col_or_param_num, &mut target)?;
                }
                // We did get the complete value, including the terminating zero. Let's resize the
                // buffer to match the retrieved value exactly (excluding terminating zero).
                Indicator::Length(len) if len < fetch_size => {
                    // Since the indicator refers to value length without terminating zero, this
                    // also implicitly drops the terminating zero at the end of the buffer.
                    let shrink_by = fetch_size - len;
                    buf.resize(buf.len() - shrink_by, 0);
                    break true;
                }
                // We did not get all of the value in one go, but the data source has been friendly
                // enough to tell us how much is missing.
                Indicator::Length(len) => {
                    let still_missing = len - fetch_size + 1;
                    let old_len = buf.len();
                    buf.resize(old_len + still_missing, 0);
                    let buf_extend = &mut buf[(old_len - 1)..];
                    fetch_size = buf_extend.len();
                    target = VarCharSliceMut::from_buffer(buf_extend, Indicator::Null);
                    self.get_data(col_or_param_num, &mut target)?;
                }
            }
        };
        Ok(not_null)
    }

    /// Retrieves arbitrary large binary data from the row and stores it in the buffer. Column index
    /// starts at `1`.
    ///
    /// # Return
    ///
    /// `true` indicates that the value has not been `NULL` and the value has been placed in `buf`.
    /// `false` indicates that the value is `NULL`. The buffer is cleared in that case.
    pub fn get_binary(&mut self, col_or_param_num: u16, buf: &mut Vec<u8>) -> Result<bool, Error> {
        // Utilize all of the allocated buffer. Make sure buffer can at least hold one element.
        buf.resize(max(1, buf.capacity()), 0);
        // We repeatedly fetch data and add it to the buffer. The buffer length is therefore the
        // accumulated value size. This variable keeps track of the number of bytes we added with
        // the current call to get_data.
        let mut fetch_size = buf.len();
        let mut target = VarBinarySliceMut::from_buffer(buf.as_mut_slice(), Indicator::Null);
        // Fetch binary data into buffer.
        self.get_data(col_or_param_num, &mut target)?;
        let not_null = loop {
            match target.indicator() {
                // Value is `NULL`. We are done here.
                Indicator::Null => {
                    buf.clear();
                    break false;
                }
                // We do not know how large the value is. Let's fetch the data with repeated calls
                // to get_data.
                Indicator::NoTotal => {
                    let old_len = buf.len();
                    // Use an exponential strategy for increasing buffer size.
                    buf.resize(old_len * 2, 0);
                    let buf_extend = &mut buf[old_len..];
                    fetch_size = buf_extend.len();
                    target = VarBinarySliceMut::from_buffer(buf_extend, Indicator::Null);
                    self.get_data(col_or_param_num, &mut target)?;
                }
                // We did get the complete value, including the terminating zero. Let's resize the
                // buffer to match the retrieved value exactly (excluding terminating zero).
                Indicator::Length(len) if len <= fetch_size => {
                    let shrink_by = fetch_size - len;
                    buf.resize(buf.len() - shrink_by, 0);
                    break true;
                }
                // We did not get all of the value in one go, but the data source has been friendly
                // enough to tell us how much is missing.
                Indicator::Length(len) => {
                    let still_missing = len - fetch_size;
                    let old_len = buf.len();
                    buf.resize(old_len + still_missing, 0);
                    let buf_extend = &mut buf[old_len..];
                    fetch_size = buf_extend.len();
                    target = VarBinarySliceMut::from_buffer(buf_extend, Indicator::Null);
                    self.get_data(col_or_param_num, &mut target)?;
                }
            }
        };
        Ok(not_null)
    }

Retrieves arbitrary large character data from the row and stores it in the buffer. Column index starts at 1.

Return

true indicates that the value has not been NULL and the value has been placed in buf. false indicates that the value is NULL. The buffer is cleared in that case.

Retrieves arbitrary large binary data from the row and stores it in the buffer. Column index starts at 1.

Return

true indicates that the value has not been NULL and the value has been placed in buf. false indicates that the value is NULL. The buffer is cleared in that case.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.