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 "resiter.h"
00038 #include "row.h"
00039
00040 #include <mysql.h>
00041
00042 #include <map>
00043 #include <set>
00044 #include <string>
00045
00046 namespace mysqlpp {
00047
00048 class Connection;
00049
00059
00060 class ResUse
00061 {
00062 protected:
00063 Connection* mysql;
00064 mutable MYSQL_RES* mysql_res;
00065 bool throw_exceptions;
00066 bool initialized;
00067 mutable FieldNames* _names;
00068 mutable FieldTypes* _types;
00069 Fields _fields;
00070 std::string _table;
00071
00075 void copy(const ResUse & other);
00076
00077 public:
00079 ResUse() :
00080 mysql(0),
00081 mysql_res(0),
00082 throw_exceptions(false),
00083 initialized(false),
00084 _names(0),
00085 _types(0),
00086 _fields(this)
00087 {
00088 }
00089
00091 ResUse(MYSQL_RES* result, Connection* m = 0, bool te = false);
00092
00094 ResUse(const ResUse& other) :
00095 initialized(false)
00096 {
00097 copy(other);
00098 }
00099
00101 ~ResUse();
00102
00104 ResUse& operator =(const ResUse& other);
00105
00107 MYSQL_RES* mysql_result()
00108 {
00109 return mysql_res;
00110 }
00111
00116 Row fetch_row() {
00117 if (!mysql_res) {
00118 if (throw_exceptions) {
00119 throw BadQuery("Results not fetched");
00120 }
00121 else {
00122 return Row();
00123 }
00124 }
00125 MYSQL_ROW row = mysql_fetch_row(mysql_res);
00126 unsigned long *length = mysql_fetch_lengths(mysql_res);
00127 if (!row || !length) {
00128 if (throw_exceptions) {
00129 throw BadQuery("Bad row");
00130 }
00131 else {
00132 return Row();
00133 }
00134 }
00135 return Row(row, this, length, throw_exceptions);
00136 }
00137
00139 bool eof() const
00140 {
00141 return mysql_eof(mysql_res) != 0;
00142 }
00143
00145 unsigned long *fetch_lengths() const {
00146 return mysql_fetch_lengths(mysql_res);
00147 }
00148
00150 Field & fetch_field() const {
00151 return *mysql_fetch_field(mysql_res);
00152 }
00153
00155 void field_seek(int field) {
00156 mysql_field_seek(mysql_res, field);
00157 }
00158
00160 int num_fields() const
00161 {
00162 return mysql_num_fields(mysql_res);
00163 }
00164
00166 void parent_leaving()
00167 {
00168 mysql = 0;
00169 }
00170
00176 void purge()
00177 {
00178 if (mysql_res) {
00179 mysql_free_result(mysql_res);
00180 mysql_res = 0;
00181 }
00182 if (_names) {
00183 delete _names;
00184 _names = 0;
00185 }
00186 if (_types) {
00187 delete _types;
00188 _types = 0;
00189 }
00190 _table.erase();
00191 }
00192
00206 operator bool() const
00207 {
00208 return mysql_res;
00209 }
00210
00212 unsigned int columns() const
00213 {
00214 return num_fields();
00215 }
00216
00218 std::string& table()
00219 {
00220 return _table;
00221 }
00222
00226 const std::string& table() const
00227 {
00228 return _table;
00229 }
00230
00234 inline int field_num(const std::string&) const;
00235
00239 inline std::string& field_name(int);
00240
00242 inline const std::string& field_name(int) const;
00243
00245 inline FieldNames& field_names();
00246
00248 inline const FieldNames& field_names() const;
00249
00251 inline void reset_field_names();
00252
00254 inline mysql_type_info& field_type(int i);
00255
00257 inline const mysql_type_info& field_type(int) const;
00258
00261 inline FieldTypes& field_types();
00262
00265 inline const FieldTypes& field_types() const;
00266
00268 inline void reset_field_types();
00269
00271 inline int names(const std::string & s) const;
00272
00274 inline std::string& names(int i);
00275
00277 inline const std::string& names(int i) const;
00278
00280 inline FieldNames& names();
00281
00283 inline const FieldNames& names() const;
00284
00286 inline void reset_names();
00287
00289 inline mysql_type_info& types(int i);
00290
00292 inline const mysql_type_info& types(int i) const;
00293
00295 inline FieldTypes& types();
00296
00298 inline const FieldTypes& types() const;
00299
00301 inline void reset_types();
00302
00304 const Fields& fields() const
00305 {
00306 return _fields;
00307 }
00308
00310 const Field& fields(unsigned int i) const
00311 {
00312 return _fields[i];
00313 }
00314
00320 bool operator ==(const ResUse& other) const
00321 {
00322 return mysql_res == other.mysql_res;
00323 }
00324
00327 bool operator !=(const ResUse& other) const
00328 {
00329 return mysql_res != other.mysql_res;
00330 }
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 = false) :
00357 ResUse(result, 0, te)
00358 {
00359 mysql = 0;
00360 }
00361
00363 Result(const Result& other) :
00364 ResUse(other),
00365 const_subscript_container<Result, Row, const Row>()
00366 {
00367 mysql = 0;
00368 }
00369
00370 virtual ~Result()
00371 {
00372 }
00373
00379 const Row fetch_row() const
00380 {
00381 if (!mysql_res) {
00382 if (throw_exceptions) {
00383 throw BadQuery("Results not fetched");
00384 }
00385 else {
00386 return Row();
00387 }
00388 }
00389 MYSQL_ROW row = mysql_fetch_row(mysql_res);
00390 unsigned long* length = mysql_fetch_lengths(mysql_res);
00391 if (!row || !length) {
00392 if (throw_exceptions) {
00393 throw BadQuery("Bad row");
00394 }
00395 else {
00396 return Row();
00397 }
00398 }
00399 return Row(row, this, length, throw_exceptions);
00400 }
00401
00403 my_ulonglong num_rows() const
00404 {
00405 if (initialized)
00406 return mysql_num_rows(mysql_res);
00407 else
00408 return 0;
00409 }
00410
00412 void data_seek(uint offset) const
00413 {
00414 mysql_data_seek(mysql_res, offset);
00415 }
00416
00418 size_type size() const
00419 {
00420 return size_type(num_rows());
00421 }
00423 size_type rows() const
00424 {
00425 return size_type(num_rows());
00426 }
00428 const Row operator [](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 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 return (*_names)[i];
00481 }
00482
00483 inline std::string& ResUse::field_name(int i)
00484 {
00485 if (!_names) {
00486 _names = new FieldNames(this);
00487 }
00488 return (*_names)[i];
00489 }
00490
00491 inline const std::string& ResUse::field_name(int i) const
00492 {
00493 if (!_names) {
00494 _names = new FieldNames(this);
00495 }
00496 return (*_names)[i];
00497 }
00498
00499 inline FieldNames& ResUse::field_names()
00500 {
00501 if (!_names) {
00502 _names = new FieldNames(this);
00503 }
00504 return *_names;
00505 }
00506
00507 inline const FieldNames& ResUse::field_names() const
00508 {
00509 if (!_names) {
00510 _names = new FieldNames(this);
00511 }
00512 return *_names;
00513 }
00514
00515 inline void ResUse::reset_field_names()
00516 {
00517 delete _names;
00518 _names = new FieldNames(this);
00519 }
00520
00521 inline mysql_type_info& ResUse::field_type(int i)
00522 {
00523 if (!_types) {
00524 _types = new FieldTypes(this);
00525 }
00526 return (*_types)[i];
00527 }
00528
00529 inline const mysql_type_info& ResUse::field_type(int i) const
00530 {
00531 if (!_types) {
00532 _types = new FieldTypes(this);
00533 }
00534 return (*_types)[i];
00535 }
00536
00537 inline FieldTypes& ResUse::field_types()
00538 {
00539 if (!_types) {
00540 _types = new FieldTypes(this);
00541 }
00542 return *_types;
00543 }
00544
00545 inline const FieldTypes& ResUse::field_types() const
00546 {
00547 if (!_types) {
00548 _types = new FieldTypes(this);
00549 }
00550 return *_types;
00551 }
00552
00553 inline void ResUse::reset_field_types()
00554 {
00555 delete _types;
00556 _types = new FieldTypes(this);
00557 }
00558
00559 inline int ResUse::names(const std::string& s) const
00560 {
00561 return field_num(s);
00562 }
00563
00564 inline std::string& ResUse::names(int i)
00565 {
00566 return field_name(i);
00567 }
00568
00569 inline const std::string& ResUse::names(int i) const
00570 {
00571 return field_name(i);
00572 }
00573
00574 inline FieldNames& ResUse::names()
00575 {
00576 return field_names();
00577 }
00578
00579 inline const FieldNames& ResUse::names() const
00580 {
00581 return field_names();
00582 }
00583
00584 inline void ResUse::reset_names()
00585 {
00586 reset_field_names();
00587 }
00588
00589 inline mysql_type_info& ResUse::types(int i)
00590 {
00591 return field_type(i);
00592 }
00593
00594 inline const mysql_type_info& ResUse::types(int i) const
00595 {
00596 return field_type(i);
00597 }
00598
00599 inline FieldTypes& ResUse::types()
00600 {
00601 return field_types();
00602 }
00603
00604 inline const FieldTypes& ResUse::types() const
00605 {
00606 return field_types();
00607 }
00608
00609 inline void ResUse::reset_types()
00610 {
00611 reset_field_types();
00612 }
00613
00614 inline ResUse& ResUse::operator =(const ResUse& other)
00615 {
00616 if (this == &other) {
00617 return *this;
00618 }
00619 copy(other);
00620 other.mysql_res = 0;
00621 return *this;
00622 }
00623
00624 }
00625
00626 #endif