Main Page Namespace List Class Hierarchy Compound List File List Namespace Members Compound Members

# result.h

Go to the documentation of this file.

    00001
    00002
    00003
    00004 /***********************************************************************
    00005  Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
    00006  MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
    00007  Others may also hold copyrights on code in this file.  See the CREDITS
    00008  file in the top directory of the distribution for details.
    00009
    00010  This file is part of MySQL++.
    00011
    00012  MySQL++ is free software; you can redistribute it and/or modify it
    00013  under the terms of the GNU Lesser General Public License as published
    00014  by the Free Software Foundation; either version 2.1 of the License, or
    00015  (at your option) any later version.
    00016
    00017  MySQL++ is distributed in the hope that it will be useful, but WITHOUT
    00018  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    00019  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
    00020  License for more details.
    00021
    00022  You should have received a copy of the GNU Lesser General Public
    00023  License along with MySQL++; if not, write to the Free Software
    00024  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
    00025  USA
    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>() // no copying here
    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 } // end namespace mysqlpp
    00633
    00634 #endif