| 180 | } |
| 181 | |
| 182 | void MyField::print(ThrowStatusWrapper* st, IAttachment* att, ITransaction* tra, unsigned char* buf) |
| 183 | { |
| 184 | printf("%s: ", name); |
| 185 | if (as<short>(buf + null)) |
| 186 | { |
| 187 | printf("<Null>\n"); |
| 188 | return; |
| 189 | } |
| 190 | |
| 191 | // IBlob makes it possible to read/write BLOB data |
| 192 | IBlob* blob = NULL; |
| 193 | switch (type) |
| 194 | { |
| 195 | // text fields |
| 196 | case SQL_TEXT: |
| 197 | printf("%*.*s\n", length, length, buf + offset); |
| 198 | break; |
| 199 | |
| 200 | case SQL_VARYING: |
| 201 | { |
| 202 | unsigned l = as<short>(buf + offset); |
| 203 | printf("%*.*s\n", l, l, buf + offset + sizeof(short)); |
| 204 | } |
| 205 | break; |
| 206 | |
| 207 | // numeric fields |
| 208 | case SQL_SHORT: |
| 209 | printf("%d\n", as<short>(buf + offset)); |
| 210 | break; |
| 211 | |
| 212 | case SQL_DOUBLE: |
| 213 | printf("%f\n", as<double>(buf + offset)); |
| 214 | break; |
| 215 | |
| 216 | // blob requires more handling in DB |
| 217 | case SQL_BLOB: |
| 218 | try |
| 219 | { |
| 220 | // use attachment's method to access BLOB object |
| 221 | blob = att->openBlob(st, tra, (ISC_QUAD*) (buf + offset), 0, NULL); |
| 222 | |
| 223 | char segbuf[16]; |
| 224 | unsigned len; |
| 225 | // read data segment by segment |
| 226 | for (;;) |
| 227 | { |
| 228 | int cc = blob->getSegment(st, sizeof(segbuf), segbuf, &len); |
| 229 | if (cc != IStatus::RESULT_OK && cc != IStatus::RESULT_SEGMENT) |
| 230 | break; |
| 231 | fwrite(segbuf, sizeof(char), len, stdout); |
| 232 | } |
| 233 | |
| 234 | // close BLOB after receiving all data |
| 235 | blob->close(st); |
| 236 | blob = NULL; |
| 237 | printf("\n"); |
| 238 | } |
| 239 | catch (...) |
no test coverage detected