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 }
00086
00088 MYSQLPP_EXPORT virtual ~ResUse();
00089
00091 ResUse& operator =(const ResUse& other);
00092
00094 MYSQL_RES* raw_result()
00095 {
00096 return result_;
00097 }
00098
00103 Row fetch_row()
00104 {
00105 if (!result_) {
00106 if (throw_exceptions()) {
00107 throw BadQuery("Results not fetched");
00108 }
00109 else {
00110 return Row();
00111 }
00112 }
00113 MYSQL_ROW row = mysql_fetch_row(result_);
00114 unsigned long* length = mysql_fetch_lengths(result_);
00115 if (!row || !length) {
00116 if (throw_exceptions()) {
00117 throw EndOfResults();
00118 }
00119 else {
00120 return Row();
00121 }
00122 }
00123 return Row(row, this, length, throw_exceptions());
00124 }
00125
00127 unsigned long *fetch_lengths() const
00128 {
00129 return mysql_fetch_lengths(result_);
00130 }
00131
00133 Field& fetch_field() const
00134 {
00135 return *mysql_fetch_field(result_);
00136 }
00137
00139 void field_seek(int field)
00140 {
00141 mysql_field_seek(result_, field);
00142 }
00143
00145 int num_fields() const
00146 {
00147 return mysql_num_fields(result_);
00148 }
00149
00151 void parent_leaving()
00152 {
00153 conn_ = 0;
00154 }
00155
00161 void purge()
00162 {
00163 if (result_) {
00164 mysql_free_result(result_);
00165 result_ = 0;
00166 }
00167
00168 delete names_;
00169 names_ = 0;
00170
00171 delete types_;
00172 types_ = 0;
00173
00174 table_.erase();
00175 }
00176
00190 operator bool() const
00191 {
00192 return result_;
00193 }
00194
00196 unsigned int columns() const
00197 {
00198 return num_fields();
00199 }
00200
00202 std::string& table()
00203 {
00204 return table_;
00205 }
00206
00210 const std::string& table() const
00211 {
00212 return table_;
00213 }
00214
00218 MYSQLPP_EXPORT inline int field_num(const std::string&) const;
00219
00223 MYSQLPP_EXPORT inline std::string& field_name(int);
00224
00226 MYSQLPP_EXPORT inline const std::string& field_name(int) const;
00227
00229 MYSQLPP_EXPORT inline FieldNames& field_names();
00230
00232 MYSQLPP_EXPORT inline const FieldNames& field_names() const;
00233
00236 MYSQLPP_EXPORT inline void reset_field_names();
00237
00239 MYSQLPP_EXPORT inline mysql_type_info& field_type(int i);
00240
00242 MYSQLPP_EXPORT inline const mysql_type_info& field_type(int) const;
00243
00246 MYSQLPP_EXPORT inline FieldTypes& field_types();
00247
00250 MYSQLPP_EXPORT inline const FieldTypes& field_types() const;
00251
00253 MYSQLPP_EXPORT inline void reset_field_types();
00254
00256 MYSQLPP_EXPORT inline int names(const std::string & s) const;
00257
00259 MYSQLPP_EXPORT inline std::string& names(int i);
00260
00262 MYSQLPP_EXPORT inline const std::string& names(int i) const;
00263
00265 MYSQLPP_EXPORT inline FieldNames& names();
00266
00268 MYSQLPP_EXPORT inline const FieldNames& names() const;
00269
00271 MYSQLPP_EXPORT inline void reset_names();
00272
00274 MYSQLPP_EXPORT inline mysql_type_info& types(int i);
00275
00277 MYSQLPP_EXPORT inline const mysql_type_info& types(int i) const;
00278
00280 MYSQLPP_EXPORT inline FieldTypes& types();
00281
00283 MYSQLPP_EXPORT inline const FieldTypes& types() const;
00284
00286 MYSQLPP_EXPORT inline void reset_types();
00287
00289 const Fields& fields() const
00290 {
00291 return fields_;
00292 }
00293
00295 const Field& fields(unsigned int i) const
00296 {
00297 return fields_.at(i);
00298 }
00299
00305 bool operator ==(const ResUse& other) const
00306 {
00307 return result_ == other.result_;
00308 }
00309
00312 bool operator !=(const ResUse& other) const
00313 {
00314 return result_ != other.result_;
00315 }
00316
00317 protected:
00318 Connection* conn_;
00319 mutable MYSQL_RES* result_;
00320 bool initialized_;
00321 mutable FieldNames* names_;
00322 mutable FieldTypes* types_;
00323 Fields fields_;
00324 std::string table_;
00325
00329 MYSQLPP_EXPORT void copy(const ResUse& other);
00330 };
00331
00332
00344
00345 class Result : public ResUse,
00346 public const_subscript_container<Result, Row, const Row>
00347 {
00348 public:
00350 Result()
00351 {
00352 }
00353
00355 Result(MYSQL_RES* result, bool te = true) :
00356 ResUse(result, 0, te)
00357 {
00358 }
00359
00361 Result(const Result& other) :
00362 ResUse(other),
00363 const_subscript_container<Result, Row, const Row>()
00364 {
00365 conn_ = 0;
00366 }
00367
00369 virtual ~Result() { }
00370
00376 const Row fetch_row() const
00377 {
00378 if (!result_) {
00379 if (throw_exceptions()) {
00380 throw BadQuery("Results not fetched");
00381 }
00382 else {
00383 return Row();
00384 }
00385 }
00386 MYSQL_ROW row = mysql_fetch_row(result_);
00387 unsigned long* length = mysql_fetch_lengths(result_);
00388 if (!row || !length) {
00389 if (throw_exceptions()) {
00390 throw EndOfResults();
00391 }
00392 else {
00393 return Row();
00394 }
00395 }
00396 return Row(row, this, length, throw_exceptions());
00397 }
00398
00400 my_ulonglong num_rows() const
00401 {
00402 if (initialized_)
00403 return mysql_num_rows(result_);
00404 else
00405 return 0;
00406 }
00407
00409 void data_seek(uint offset) const
00410 {
00411 mysql_data_seek(result_, offset);
00412 }
00413
00415 size_type size() const
00416 {
00417 return size_type(num_rows());
00418 }
00419
00421 size_type rows() const
00422 {
00423 return size_type(num_rows());
00424 }
00425
00427 const Row at(size_type i) const
00428 {
00429 data_seek(i);
00430 return fetch_row();
00431 }
00432 };
00433
00434
00436 inline void swap(ResUse& x, ResUse& y)
00437 {
00438 ResUse tmp = x;
00439 x = y;
00440 y = tmp;
00441 }
00442
00444 inline void swap(Result& x, Result& y)
00445 {
00446 Result tmp = x;
00447 x = y;
00448 y = tmp;
00449 }
00450
00453 class ResNSel
00454 {
00455 public:
00456 bool success;
00457 my_ulonglong insert_id;
00458 my_ulonglong rows;
00459 std::string info;
00460
00461 ResNSel() :
00462 success(false)
00463 {
00464 }
00465
00467 MYSQLPP_EXPORT ResNSel(Connection* q);
00468
00470 operator bool() { return success; }
00471 };
00472
00473
00474 inline int ResUse::field_num(const std::string& i) const
00475 {
00476 if (!names_) {
00477 names_ = new FieldNames(this);
00478 }
00479
00480 size_t index = (*names_)[i];
00481 if ((index >= names_->size()) && throw_exceptions()) {
00482 throw BadFieldName(i.c_str());
00483 }
00484
00485 return int(index);
00486 }
00487
00488 inline std::string& ResUse::field_name(int i)
00489 {
00490 if (!names_) {
00491 names_ = new FieldNames(this);
00492 }
00493 return (*names_)[i];
00494 }
00495
00496 inline const std::string& ResUse::field_name(int i) const
00497 {
00498 if (!names_) {
00499 names_ = new FieldNames(this);
00500 }
00501 return (*names_)[i];
00502 }
00503
00504 inline FieldNames& ResUse::field_names()
00505 {
00506 if (!names_) {
00507 names_ = new FieldNames(this);
00508 }
00509 return *names_;
00510 }
00511
00512 inline const FieldNames& ResUse::field_names() const
00513 {
00514 if (!names_) {
00515 names_ = new FieldNames(this);
00516 }
00517 return *names_;
00518 }
00519
00520 inline void ResUse::reset_field_names()
00521 {
00522 delete names_;
00523 names_ = 0;
00524 names_ = new FieldNames(this);
00525 }
00526
00527 inline mysql_type_info& ResUse::field_type(int i)
00528 {
00529 if (!types_) {
00530 types_ = new FieldTypes(this);
00531 }
00532 return (*types_)[i];
00533 }
00534
00535 inline const mysql_type_info& ResUse::field_type(int i) const
00536 {
00537 if (!types_) {
00538 types_ = new FieldTypes(this);
00539 }
00540 return (*types_)[i];
00541 }
00542
00543 inline FieldTypes& ResUse::field_types()
00544 {
00545 if (!types_) {
00546 types_ = new FieldTypes(this);
00547 }
00548 return *types_;
00549 }
00550
00551 inline const FieldTypes& ResUse::field_types() const
00552 {
00553 if (!types_) {
00554 types_ = new FieldTypes(this);
00555 }
00556 return *types_;
00557 }
00558
00559 inline void ResUse::reset_field_types()
00560 {
00561 delete types_;
00562 types_ = 0;
00563 types_ = new FieldTypes(this);
00564 }
00565
00566 inline int ResUse::names(const std::string& s) const
00567 {
00568 return field_num(s);
00569 }
00570
00571 inline std::string& ResUse::names(int i)
00572 {
00573 return field_name(i);
00574 }
00575
00576 inline const std::string& ResUse::names(int i) const
00577 {
00578 return field_name(i);
00579 }
00580
00581 inline FieldNames& ResUse::names()
00582 {
00583 return field_names();
00584 }
00585
00586 inline const FieldNames& ResUse::names() const
00587 {
00588 return field_names();
00589 }
00590
00591 inline void ResUse::reset_names()
00592 {
00593 reset_field_names();
00594 }
00595
00596 inline mysql_type_info& ResUse::types(int i)
00597 {
00598 return field_type(i);
00599 }
00600
00601 inline const mysql_type_info& ResUse::types(int i) const
00602 {
00603 return field_type(i);
00604 }
00605
00606 inline FieldTypes& ResUse::types()
00607 {
00608 return field_types();
00609 }
00610
00611 inline const FieldTypes& ResUse::types() const
00612 {
00613 return field_types();
00614 }
00615
00616 inline void ResUse::reset_types()
00617 {
00618 reset_field_types();
00619 }
00620
00621 inline ResUse& ResUse::operator =(const ResUse& other)
00622 {
00623 if (this == &other) {
00624 return *this;
00625 }
00626 copy(other);
00627 other.result_ = 0;
00628 return *this;
00629 }
00630
00631 }
00632
00633 #endif