| 550 | } |
| 551 | |
| 552 | statement_backend::exec_fetch_result |
| 553 | postgresql_statement_backend::fetch(int number) |
| 554 | { |
| 555 | if (single_row_mode_ && (number > 1)) |
| 556 | { |
| 557 | throw soci_error("Bulk operations are not supported with single-row mode."); |
| 558 | } |
| 559 | |
| 560 | if (numberOfRows_ == 0) |
| 561 | { |
| 562 | // There is nothing to fetch and normally we shouldn't be even called |
| 563 | // in this case, but don't do anything stupid if we are. |
| 564 | return ef_no_data; |
| 565 | } |
| 566 | |
| 567 | // Note: |
| 568 | // In the multi-row mode this function does not actually fetch anything from anywhere |
| 569 | // - the data was already retrieved from the server in the execute() |
| 570 | // function, and the actual consumption of this data will take place |
| 571 | // in the postFetch functions, called for each into element. |
| 572 | // Here, we only prepare for this to happen (to emulate "the Oracle way"). |
| 573 | // In the single-row mode the fetch of single row of data is performed as expected. |
| 574 | |
| 575 | // forward the "cursor" from the last fetch |
| 576 | currentRow_ += rowsToConsume_; |
| 577 | |
| 578 | if (currentRow_ >= numberOfRows_) |
| 579 | { |
| 580 | if (single_row_mode_) |
| 581 | { |
| 582 | PGresult* res = PQgetResult(session_.conn_); |
| 583 | result_.reset(res); |
| 584 | |
| 585 | if (res == nullptr) |
| 586 | { |
| 587 | return ef_no_data; |
| 588 | } |
| 589 | |
| 590 | currentRow_ = 0; |
| 591 | rowsToConsume_ = 0; |
| 592 | |
| 593 | numberOfRows_ = PQntuples(result_); |
| 594 | if (numberOfRows_ == 0) |
| 595 | { |
| 596 | return ef_no_data; |
| 597 | } |
| 598 | else |
| 599 | { |
| 600 | rowsToConsume_ = 1; |
| 601 | |
| 602 | return ef_success; |
| 603 | } |
| 604 | } |
| 605 | else |
| 606 | { |
| 607 | // default multi-row execution |
| 608 | |
| 609 | // all rows were already consumed |