00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef MYSQLPP_RESULT_H
00029 #define MYSQLPP_RESULT_H
00030
00031 #include "defs.h"
00032
00033 #include "exceptions.h"
00034 #include "fields.h"
00035 #include "field_names.h"
00036 #include "field_types.h"
00037 #include "noexceptions.h"
00038 #include "resiter.h"
00039 #include "row.h"
00040
00041 #include <mysql.h>
00042
00043 #include <map>
00044 #include <set>
00045 #include <string>
00046
00047 namespace mysqlpp {
00048
00049 class Connection;
00050
00060
00061 class ResUse : public OptionalExceptions
00062 {
00063 public:
00065 ResUse() :
00066 OptionalExceptions(),
00067 conn_(0),
00068 result_(0),
00069 initialized_(false),
00070 names_(0),
00071 types_(0),
00072 fields_(this)
00073 {
00074 }
00075
00077 MYSQLPP_EXPORT ResUse(MYSQL_RES* result, Connection* c = 0, bool te = true);
00078
00080 ResUse(const ResUse& other) :
00081 OptionalExceptions(),
00082 initialized_(false)
00083 {
00084 copy(other);
00085 other.result_ = 0;
00086 }
00087
00089 MYSQLPP_EXPORT virtual ~ResUse();
00090
00092 ResUse& operator =(const ResUse& other);
00093
00095 MYSQL_RES* raw_result()
00096 {
00097 return result_;
00098 }
00099
00104 Row fetch_row()
00105 {
00106 if (!result_) {
00107 if (throw_exceptions()) {
00108 throw BadQuery("Results not fetched");
00109 }
00110 else {
00111 return Row();
00112 }
00113 }
00114 MYSQL_ROW row = mysql_fetch_row(result_);
00115 unsigned long* length = mysql_fetch_lengths(result_);
00116 if (!row || !length) {
00117 if (throw_exceptions()) {
00118 throw EndOfResults();
00119 }
00120 else {
00121 return Row();
00122 }
00123 }
00124 return Row(row, this, length, throw_exceptions());
00125 }
00126
00128 unsigned long *fetch_lengths() const
00129 {
00130 return mysql_fetch_lengths(result_);
00131 }
00132
00134 Field& fetch_field() const
00135 {
00136 return *mysql_fetch_field(result_);
00137 }
00138
00140 void field_seek(int field)
00141 {
00142 mysql_field_seek(result_, field);
00143 }
00144
00146 int num_fields() const
00147 {
00148 return mysql_num_fields(result_);
00149 }
00150
00152 void parent_leaving()
00153 {
00154 conn_ = 0;
00155 }
00156
00162 void purge()
00163 {
00164 if (result_) {
00165 mysql_free_result(result_);
00166 result_ = 0;
00167 }
00168
00169 delete names_;
00170 names_ = 0;
00171
00172 delete types_;
00173 types_ = 0;
00174
00175 table_.erase();
00176 }
00177
00191 operator bool() const
00192 {
00193 return result_;
00194 }
00195
00197 unsigned int columns() const
00198 {
00199 return num_fields();
00200 }
00201
00203 std::string& table()
00204 {
00205 return table_;
00206 }
00207
00211 const std::string& table() const
00212 {
00213 return table_;
00214 }
00215
00219 MYSQLPP_EXPORT inline int field_num(const std::string&) const;
00220
00224 MYSQLPP_EXPORT inline std::string& field_name(int);
00225
00227 MYSQLPP_EXPORT inline const std::string& field_name(int) const;
00228
00230 MYSQLPP_EXPORT inline FieldNames& field_names();
00231
00233 MYSQLPP_EXPORT inline const FieldNames& field_names() const;
00234
00237 MYSQLPP_EXPORT inline void reset_field_names();
00238
00240 MYSQLPP_EXPORT inline mysql_type_info& field_type(int i);
00241
00243 MYSQLPP_EXPORT inline const mysql_type_info& field_type(int) const;
00244
00247 MYSQLPP_EXPORT inline FieldTypes& field_types();
00248
00251 MYSQLPP_EXPORT inline const FieldTypes& field_types() const;
00252
00254 MYSQLPP_EXPORT inline void reset_field_types();
00255
00257 MYSQLPP_EXPORT inline int names(const std::string & s) const;
00258
00260 MYSQLPP_EXPORT inline std::string& names(int i);
00261
00263 MYSQLPP_EXPORT inline const std::string& names(int i) const;
00264
00266 MYSQLPP_EXPORT inline FieldNames& names();
00267
00269 MYSQLPP_EXPORT inline const FieldNames& names() const;
00270
00272 MYSQLPP_EXPORT inline void reset_names();
00273
00275 MYSQLPP_EXPORT inline mysql_type_info& types(int i);
00276
00278 MYSQLPP_EXPORT inline const mysql_type_info& types(int i) const;
00279
00281 MYSQLPP_EXPORT inline FieldTypes& types();
00282
00284 MYSQLPP_EXPORT inline const FieldTypes& types() const;
00285
00287 MYSQLPP_EXPORT inline void reset_types();
00288
00290 const Fields& fields() const
00291 {
00292 return fields_;
00293 }
00294
00296 const Field& fields(unsigned int i) const
00297 {
00298 return fields_.at(i);
00299 }
00300
00306 bool operator ==(const ResUse& other) const
00307 {
00308 return result_ == other.result_;
00309 }
00310
00313 bool operator !=(const ResUse& other) const
00314 {
00315 return result_ != other.result_;
00316 }
00317
00318 protected:
00319 Connection* conn_;
00320 mutable MYSQL_RES* result_;
00321 bool initialized_;
00322 mutable FieldNames* names_;
00323 mutable FieldTypes* types_;
00324 Fields fields_;
00325 std::string table_;
00326
00330 MYSQLPP_EXPORT void copy(const ResUse& other);
00331 };
00332
00333
00345
00346 class Result : public ResUse,
00347 public const_subscript_container<Result, Row, const Row>
00348 {
00349 public:
00351 Result()
00352 {
00353 }
00354
00356 Result(MYSQL_RES* result, bool te = true) :
00357 ResUse(result, 0, te)
00358 {
00359 }
00360
00362 Result(const Result& other) :
00363 ResUse(other),
00364 const_subscript_container<Result, Row, const Row>()
00365 {
00366 conn_ = 0;
00367 }
00368
00370 virtual ~Result() { }
00371
00377 const Row fetch_row() const
00378 {
00379 if (!result_) {
00380 if (throw_exceptions()) {
00381 throw BadQuery("Results not fetched");
00382 }
00383 else {
00384 return Row();
00385 }
00386 }
00387 MYSQL_ROW row = mysql_fetch_row(result_);
00388 unsigned long* length = mysql_fetch_lengths(result_);
00389 if (!row || !length) {
00390 if (throw_exceptions()) {
00391 throw EndOfResults();
00392 }
00393 else {
00394 return Row();
00395 }
00396 }
00397 return Row(row, this, length, throw_exceptions());
00398 }
00399
00401 my_ulonglong num_rows() const
00402 {
00403 if (initialized_)
00404 return mysql_num_rows(result_);
00405 else
00406 return 0;
00407 }
00408
00410 void data_seek(uint offset) const
00411 {
00412 mysql_data_seek(result_, offset);
00413 }
00414
00416 size_type size() const
00417 {
00418 return size_type(num_rows());
00419 }
00420
00422 size_type rows() const
00423 {
00424 return size_type(num_rows());
00425 }
00426
00428 const Row at(size_type i) const
00429 {
00430 data_seek(i);
00431 return fetch_row();
00432 }
00433 };
00434
00435
00437 inline void swap(ResUse& x, ResUse& y)
00438 {
00439 ResUse tmp = x;
00440 x = y;
00441 y = tmp;
00442 }
00443
00445 inline void swap(Result& x, Result& y)
00446 {
00447 Result tmp = x;
00448 x = y;
00449 y = tmp;
00450 }
00451
00454 class ResNSel
00455 {
00456 public:
00457 bool success;
00458 my_ulonglong insert_id;
00459 my_ulonglong rows;
00460 std::string info;
00461
00462 ResNSel() :
00463 success(false)
00464 {
00465 }
00466
00468 MYSQLPP_EXPORT ResNSel(Connection* q);
00469
00471 operator bool() { return success; }
00472 };
00473
00474
00475 inline int ResUse::field_num(const std::string& i) const
00476 {
00477 if (!names_) {
00478 names_ = new FieldNames(this);
00479 }
00480
00481 size_t index = (*names_)[i];
00482 if ((index >= names_->size()) && throw_exceptions()) {
00483 throw BadFieldName(i.c_str());
00484 }
00485
00486 return int(index);
00487 }
00488
00489 inline std::string& ResUse::field_name(int i)
00490 {
00491 if (!names_) {
00492 names_ = new FieldNames(this);
00493 }
00494 return (*names_)[i];
00495 }
00496
00497 inline const std::string& ResUse::field_name(int i) const
00498 {
00499 if (!names_) {
00500 names_ = new FieldNames(this);
00501 }
00502 return (*names_)[i];
00503 }
00504
00505 inline FieldNames& ResUse::field_names()
00506 {
00507 if (!names_) {
00508 names_ = new FieldNames(this);
00509 }
00510 return *names_;
00511 }
00512
00513 inline const FieldNames& ResUse::field_names() const
00514 {
00515 if (!names_) {
00516 names_ = new FieldNames(this);
00517 }
00518 return *names_;
00519 }
00520
00521 inline void ResUse::reset_field_names()
00522 {
00523 delete names_;
00524 names_ = 0;
00525 names_ = new FieldNames(this);
00526 }
00527
00528 inline mysql_type_info& ResUse::field_type(int i)
00529 {
00530 if (!types_) {
00531 types_ = new FieldTypes(this);
00532 }
00533 return (*types_)[i];
00534 }
00535
00536 inline const mysql_type_info& ResUse::field_type(int i) const
00537 {
00538 if (!types_) {
00539 types_ = new FieldTypes(this);
00540 }
00541 return (*types_)[i];
00542 }
00543
00544 inline FieldTypes& ResUse::field_types()
00545 {
00546 if (!types_) {
00547 types_ = new FieldTypes(this);
00548 }
00549 return *types_;
00550 }
00551
00552 inline const FieldTypes& ResUse::field_types() const
00553 {
00554 if (!types_) {
00555 types_ = new FieldTypes(this);
00556 }
00557 return *types_;
00558 }
00559
00560 inline void ResUse::reset_field_types()
00561 {
00562 delete types_;
00563 types_ = 0;
00564 types_ = new FieldTypes(this);
00565 }
00566
00567 inline int ResUse::names(const std::string& s) const
00568 {
00569 return field_num(s);
00570 }
00571
00572 inline std::string& ResUse::names(int i)
00573 {
00574 return field_name(i);
00575 }
00576
00577 inline const std::string& ResUse::names(int i) const
00578 {
00579 return field_name(i);
00580 }
00581
00582 inline FieldNames& ResUse::names()
00583 {
00584 return field_names();
00585 }
00586
00587 inline const FieldNames& ResUse::names() const
00588 {
00589 return field_names();
00590 }
00591
00592 inline void ResUse::reset_names()
00593 {
00594 reset_field_names();
00595 }
00596
00597 inline mysql_type_info& ResUse::types(int i)
00598 {
00599 return field_type(i);
00600 }
00601
00602 inline const mysql_type_info& ResUse::types(int i) const
00603 {
00604 return field_type(i);
00605 }
00606
00607 inline FieldTypes& ResUse::types()
00608 {
00609 return field_types();
00610 }
00611
00612 inline const FieldTypes& ResUse::types() const
00613 {
00614 return field_types();
00615 }
00616
00617 inline void ResUse::reset_types()
00618 {
00619 reset_field_types();
00620 }
00621
00622 inline ResUse& ResUse::operator =(const ResUse& other)
00623 {
00624 if (this == &other) {
00625 return *this;
00626 }
00627 copy(other);
00628 other.result_ = 0;
00629 return *this;
00630 }
00631
00632 }
00633
00634 #endif