32 MCS_DEBUG_SETUP(0,
"DBConn");
34 lconnInitialized =
false;
55 lconn = mysql_init(lconn);
59 lconnInitialized =
true;
60 mysql_options(lconn, MYSQL_OPT_CONNECT_TIMEOUT,
"5");
62 ret = mysql_real_connect(lconn, lhost.c_str(), luser.c_str(), lpass.c_str(),
63 ldb.c_str(), 0, MYSQL_SOCK, 0);
67 throw MCS_ERROR(MSG_CANT_OPEN_MYSQL_CONNECTION, mysql_error(lconn));
73 if (lconnInitialized) {
83 lconnInitialized =
false;
99 unsigned long lid = mysql_thread_id(lconn);
108 dbc->
connect(luser, lpass, ldb, lhost);
110 if (mysql_errno(dbc->
lconn))
111 throw MCS_ERROR(MSG_CANT_OPEN_MYSQL_CONNECTION, mysql_error(dbc->
lconn));
134 MCS_DEBUG_SETUP(0,
"Query");
176 Record* mcs::Query::newRecord()
182 bool mcs::Query::fetch(
unsigned int newpos,
bool random)
185 mysql_stmt_data_seek(
lstmt, newpos);
187 int ret = mysql_stmt_fetch(
lstmt);
192 return ! (ret == MYSQL_NO_DATA);
211 bool mcs::Query::gotRecordSet()
225 MYSQL_RES* res = NULL;
243 if (mysql_stmt_prepare(
lstmt, SQL.c_str(), SQL.length()))
248 nlparam = mysql_stmt_param_count(
lstmt);
250 lbparam = (MYSQL_BIND*) malloc(
sizeof(MYSQL_BIND) * nlparam);
264 n = mysql_stmt_field_count(
lstmt);
266 res = mysql_stmt_result_metadata(
lstmt);
270 lbrec = (MYSQL_BIND*) malloc(
sizeof(MYSQL_BIND) * n);
273 myrec =
new Record(
false);
275 fields = mysql_fetch_fields(res);
276 numfields = mysql_num_fields(res);
278 for (i=0; i<numfields; i++) {
280 throw MCS_ERROR(MSG_TYPE_NOT_HANDLED, i, fields[i].type);
286 ((
bool) (fields[i].flags & UNSIGNED_FLAG)),
292 mysql_free_result(res);
313 SQL = string(
"SELECT ") + field + string(
" FROM ") + table;
316 SQL +=
string(
" WHERE ") + where ;
318 SQL += string(
" LIMIT 1");
337 throw MCS_ERROR(MSG_STMT_NOT_YET_PREPARED);
339 if (mysql_stmt_execute(
lstmt))
347 if (mysql_stmt_store_result(
lstmt))
351 mysql_stmt_num_rows(
lstmt), myrec);
372 scmp = SQL.substr(0, 6);
374 if ((strcasecmp(scmp.c_str(),
"SELECT") == 0) ||
375 (strcasecmp(scmp.c_str(),
"INSERT") == 0) ||
376 (strcasecmp(scmp.c_str(),
"REPLAC") == 0) ||
377 (strcasecmp(scmp.c_str(),
"UPDATE") == 0) ||
378 (strcasecmp(scmp.c_str(),
"DELETE") == 0)
402 mysql_stmt_free_result(
lstmt);
411 mysql_stmt_close(
lstmt);
425 unsigned int ntbl, i;
429 res = mysql_list_tables(
lconn,
"%");
431 ntbl = mysql_num_rows(res);
432 for (i=0; i<ntbl; i++) {
433 record = mysql_fetch_row(res);
437 mysql_free_result(res);
445 string s =
"SHOW COLUMNS FROM " + tbl;
450 throw MCS_ERROR(MSG_CANT_GET_INFO_TABLE, tbl.csz);
456 unsigned int& nfields,
459 static string tab =
"\t";
460 static string null =
"NULL";
462 unsigned int i, j, f;
471 nrows = mysql_num_rows(res);
472 f = mysql_num_fields(res); nfields = f;
473 fields = mysql_fetch_fields(res);
476 s += fields[j].name + tab;
479 for (i=0; i<nrows; i++) {
480 record = mysql_fetch_row(res);
484 s+=string(record[j]) + tab;
498 nfields = metarec().
count();
501 for (i=0; i<nfields; i++)
502 s += metarec()[i].name() + tab;
508 for (
int i=0; i<rec().
count(); i++)
509 if (rec()[i].isNull())
512 s += rec()[i].sval() + tab;
535 unsigned int& nfields)
542 if (mysql_query(
lconn, SQL.c_str()))
545 res = mysql_store_result(
lconn);
553 mysql_free_result(res);
692 buf.push_back( pre +
"Prepared query: " + SQL );
693 buf.push_back( pre +
"Number of parameters: " +
itos(
param().count()) );
696 buf.push_back(
"Param #" +
itos(i) +
string(
" value: ") +
lparam[i].sval() );
699 buf.push_back( pre +
"SELECT-LIKE query: " + SQL );
700 buf.push_back( pre +
"Number of records: " +
itos(nRows()) );
701 buf.push_back( pre +
"Number of fields: " +
itos(
nFields()) );
702 buf.push_back( pre +
"Fields detail follows:" );
705 buf.push_back( pre +
"Field #" +
itos(i) +
":" );
706 buf.push_back( pre +
" Name : " + metarec()[i].name() );
707 buf.push_back( pre +
" Type : " +
Types2Str(rec()[i].type(),
false) );
708 buf.push_back( pre +
" Unsigned : " +
btos(rec()[i].isUnsigned()) );
709 buf.push_back( pre +
" Max length: " +
itos(rec()[i].maxLength()) );
710 buf.push_back( pre +
" Length : " +
itos(rec()[i].length()) );
714 buf.push_back( pre +
"INSERT-LIKE query" );
728 string null =
"NULL";
732 MCS_DEBUG(chunksize <<
" " << firstTime);
739 if (det.length() > chunksize)
740 throw MCS_ERROR(MSG_NOT_ENOUGH_SPACE, det.length(), chunksize);
742 memcpy(buf, det.c_str(), det.length());
743 chunksize = det.length();
757 if (rec()[i].isNull())
760 s += rec()[i].sval();
765 if (data.length() + s.length() < chunksize) {
773 memcpy(buf, data.c_str(), data.length());
774 chunksize = data.length();
784 ofstream of(fn.c_str());
785 bool firstTime =
true;
788 throw MCS_ERROR(MSG_CANT_OPEN_FILE, fn.csz);
790 char* p = (
char*) malloc(chunk);
804 string table,
string where,
int nrec)
808 for (i=0; i<nfields; i++) {
816 void mcs::Query::parseFieldList(
int op,
string& fields,
string& values,
827 if (metarec()[i].isAutoIncrement())
836 fields +=
"`"+ metarec()[i].name() +
"`";
839 if (op == MCS_PAB_UPDATE)
849 string sql, comma_fields, marks =
"";
850 string tab_quoted = table;
853 if (tab_quoted.find(
"`") == std::string::npos)
854 tab_quoted =
"`"+ table +
"`";
856 fields =
trim(fields);
860 comma_fields =
subst(fields,
" +",
", ");
862 sql =
"SELECT " + comma_fields +
" FROM " + tab_quoted;
864 sql +=
" WHERE " + where;
875 parseFieldList(op, fields, marks, autoIncr);
879 sql =
"INSERT INTO " + tab_quoted +
"(" + fields +
") VALUES ";
880 marks =
"(" + marks +
")";
881 for (
int irec=0; irec<nrec; irec++) {
883 if (irec == 0) {marks =
", " + marks;}
886 case MCS_PAB_REPLACE:
887 sql =
"REPLACE INTO " + tab_quoted +
"(" + fields +
") VALUES (" + marks +
")";
890 sql =
"UPDATE " + tab_quoted +
" SET " + fields +
" WHERE " + where;
898 for (
int irec=0; irec<nrec; irec++) {
899 for (i=0; i<tmprec.
count(); i++) {
902 (
char*) tmprec[i].name().c_str(),
903 tmprec[i].maxLength(),
904 tmprec[i].isUnsigned());
908 memcpy(
lparam[i].buffer(), tmprec[i].buffer(),
lparam[i].maxLength());
932 Query(db, true), newrec(false)
934 MCS_DEBUG_SETUP(0,
"Table");
968 insert_or_update(MCS_PAB_INSERT);
975 insert_or_update(MCS_PAB_UPDATE);
981 insert_or_update(MCS_PAB_REPLACE);
985 void mcs::Table::insert_or_update(
int op)
994 if (op == MCS_PAB_UPDATE) {
1003 if (
param()[i].isAutoIncrement() ||
bool isOpen()
Tell if a connection to the server is opened.
string btos(bool b)
Convert a boolean to a string containing "true" or "false".
string itos(int i)
Convert an integer to a string.
int posWhoseNameIs(string name, enum ThrowExceptions throwexc=THROW)
Return the index of the first Data objects whose name is "name".
Record & param()
Returns a reference to a Record object containing all the input parameters.
#define MCS_RS_USEMETAREC
Flag for RecordSet::init().
MYSQL_STMT * lstmt
Mysql statement structure.
vector< string > tableInfo(string tbl)
Retrieve information about a table.
unsigned int laffectedRows
Rows affected by the last INSERT-LIKE query.
Query(const Query &)
Declared to avoid using of default copy constructor.
vector< string > tableList
A vector<string> containing the table list.
Execute queries on the database.
Record & newRec()
Return a reference to a Record object for insert.
Data & lookup(string field, string table, string where="")
Returns the current record set.
vector< string > ExecutionDetails(string pre="")
Returns a vector of strings containing details of query execution.
void prepare_with_parameters(int op, string fields, string table, string where="", int nrec=1)
Prepare a query with input parameters.
long long int lastid
Last generated id on an AUTO_INCREMENT column.
Table(const Table &)
Declared to avoid using of default copy constructor.
unsigned long id()
Returns the same value as mysql_thread_id.
vector< string > simpleQuery(string SQL, unsigned int &nrows, unsigned int &nfields)
Execute a query and return result in a vector of strings.
void bind()
Bind parameters.
Hold informations about an event.
A dynamic array of Data objects.
DBConn * newDBConn()
Creates a new DB connection with the same parameters.
void Result2Ascii(string fn)
Writes a table into an ASCII file using the customFillBuffer() method.
bool setFirst()
Set the record pointer to the first position.
void query(string SQL, bool StoreResult=false)
Wrapper aropund prepare() and execute().
void customFillBuffer(char *buf, unsigned int &chunksize, bool firstTime)
Fills a buffer with a result-set.
void replace()
Insert (or replace) a new record.
unsigned int nAffectedRows()
Returns number of affected records by the last execute() call.
#define MCS_DEFAULTCHUNKSIZE
File chunk size.
void setNull()
Set all Data object's name to null values.
MYSQL * lconn
Mysql connection to use.
void close()
Closes a db connection.
The base class that implement the data abstraction layer.
#define MCS_ERROR(A, rest...)
Facility to easily pass all necessary parameter to an Event constructor.
void update()
Update the current record.
long long int last_id()
Returns the last value generated for an AUTO_INCREMENT column.
void connect(string user, string pass, string db, string host="")
Connect to a databae server.
string Types2Str(Types type, bool isunsigned)
Return the name of the type given in "type" and "isunsigned".
unsigned int posfieldkey
Position of the index field.
void readTableList()
Reads the list of tables in the current database.
~DBConn()
Destructor, calls close().
void loadTable()
Reload the table.
string vtos(vector< string > vec)
Join a vector of strings in a single string using newlines.
unsigned int size()
If knowSize() is true, return the size of the entire block of data.
int nFields()
Returns number of fields.
void insert()
Insert a new record.
vector< string > printResultSet(unsigned int &nrows, unsigned int &nfields, MYSQL_RES *res=NULL)
Prints all the result set in a vector of string.
void startFetch()
Must be called when record fetching is possible.
MYSQL_BIND * lbrec
Record of binding structure for output.
void close()
Close the statement and frees anything has been allocated.
Handle database connection.
Main include file for all MCS based applications.
void addField(Data *d)
Wrapper around Dynamic_Array.push.
#define MCS_RS_KNOW_NROWS
Flag for RecordSet::init().
void emptyName()
Set all Data object's name to an empty string.
bool VarLenType(Types type)
Tell if "type" is a variable length type.
MYSQL * lconn
MYSQL connection structure.
void init(unsigned char code, unsigned int nrows=0, Record *meta=NULL, short int id=0)
Initailize the Record set.
A general purpose data type.
void prepare(string SQL="")
Prepare the SQL statement.
#define MCS_RS_RANDOM
Flag for RecordSet::init().
bool MYSQL2Types(enum_field_types mtype, Types &type)
Convert a MySQL type into a MCS type.
string subst(string s, string what, string with, int op=0)
Perform substitutions on a string.
Record newrec
Array of values for insert.
string trim(string s)
Remove any leading or trailing blanks.
void execute(bool StoreResult=false)
Execute the prepared statement.
int count()
Wrapper around Dynamic_Array.count.
bool lhandleNewDBConn
Flag to indicate that a new DBConn object has been created.
bool gotResult
True if we got a result from the last query.
bool setNext()
Set the record pointer to the next position.
string lfieldkey
Name of the index field.
bool gotStmtInitialized
True if the statement has been initialized.
DBConn * ldbc
Internal reference to the DBConn object used to connect to db.
Namespace for MCS library.
MYSQL_BIND * lbparam
Record of binding structure for input (parameters).
Types
Enumeration of base type for Data.
Record lparam
Record of binded Data objects for input (parameters).