Mysql: WhenReconnect

git-svn-id: svn://ultimatepp.org/upp/trunk@5035 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2012-06-03 18:01:56 +00:00
parent 38970db433
commit ca0e70b110
5 changed files with 81 additions and 26 deletions

View file

@ -140,7 +140,7 @@ inline void UnlockLog() {}
#define DDUMPM(x) @
#define DTIMING(x) @
#define DLOGHEX(x) @
#define DUMPHEX(nx) @
#define DDUMPHEX(nx) @
#define DEBUGCODE(x) LOG_NOP

View file

@ -245,7 +245,7 @@ void Thread::Priority(int percent)
SetThreadPriority(handle, prior);
#endif
#ifdef PLATFORM_POSIX
//!! todo
// ToDo
#endif
}

View file

@ -99,6 +99,9 @@ value is not null)&]
[s4; &]
[s5;:Thread`:`:Priority`(int`): [@(0.0.255) void]_[* Priority]([@(0.0.255) int]_[*@3 percent])
&]
[s2;%% Sets the treads priority to [%-*@3 percent ][%- (0 to 100)].&]
[s2;%% Sets the treads priority to [%-*@3 percent ][%- (0 to 200)]. In
reality, current implementation supports only 5 levels, 25%,
75%, 125%, 175% and more than 175%; last two levels require root
priviledges.&]
[s3;%% &]
[s0; ]

View file

@ -2,6 +2,8 @@
#ifndef flagNOMYSQL
#define LLOG(x) DLOG(x)
NAMESPACE_UPP
class MySqlConnection : public SqlConnection {
@ -31,6 +33,7 @@ private:
String MakeQuery() const;
void FreeResult();
String EscapeString(const String& v);
bool MysqlQuery(const char *query);
public:
MySqlConnection(MySqlSession& session, MYSQL *mysql);
@ -43,12 +46,13 @@ static const char *sEmpNull(const char *s) {
return s && *s == '\0' ? NULL : s;
}
bool MySqlSession::Connect(const char *user, const char *password, const char *database,
const char *host, int port, const char *socket) {
bool MySqlSession::DoConnect()
{
mysql = mysql_init((MYSQL*) 0);
if(mysql && mysql_real_connect(mysql, sEmpNull(host), sEmpNull(user),
sEmpNull(password), sEmpNull(database), port,
sEmpNull(socket), 0)) {
level = 0;
if(mysql && mysql_real_connect(mysql, sEmpNull(connect_host), sEmpNull(connect_user),
sEmpNull(connect_password), sEmpNull(connect_database),
connect_port, sEmpNull(connect_socket), 0)) {
Sql sql(*this);
username = sql.Select("substring_index(USER(),'@',1)");
mysql_set_character_set(mysql, "utf8");
@ -60,6 +64,24 @@ bool MySqlSession::Connect(const char *user, const char *password, const char *d
return false;
}
bool MySqlSession::Reconnect()
{
LLOG("Trying to reconnect");
Close();
return DoConnect();
}
bool MySqlSession::Connect(const char *user, const char *password, const char *database,
const char *host, int port, const char *socket) {
connect_user = user;
connect_password = password;
connect_database = database;
connect_host = host;
connect_port = port;
connect_socket = socket;
return DoConnect();
}
inline static const char *EmpNull(const String& s)
{
return *s ? (const char *)s : 0;
@ -70,7 +92,6 @@ bool MySqlSession::Open(const char *connect) {
String database = Null;
String host = Null;
int port = MYSQL_PORT;
level = 0;
const char *p = connect, *b;
for(b = p; *p && *p != '/' && *p != '@'; p++)
;
@ -117,14 +138,35 @@ void MySqlSession::Close() {
}
}
bool MySqlSession::MysqlQuery(const char *query)
{
int itry = 0;
for(;;) {
if(!mysql_query(mysql, query))
break;
int code = mysql_errno(mysql);
if(level == 0 && itry++ == 0 &&
(code == 2006 || code == 2013 || code == 2055) &&
WhenReconnect())
continue;
SetError(mysql_error(mysql), query, code);
return false;
}
return true;
}
bool MySqlConnection::MysqlQuery(const char *query)
{
return session.MysqlQuery(query);
}
void MySqlSession::Begin()
{
static const char btrans[] = "start transaction";
if(trace)
*trace << btrans << ";\n";
if(mysql_query(mysql, btrans))
SetError(mysql_error(mysql), btrans);
level++;
if(MysqlQuery(btrans))
level++;
}
void MySqlSession::Commit()
@ -132,9 +174,8 @@ void MySqlSession::Commit()
static const char ctrans[] = "commit";
if(trace)
*trace << ctrans << ";\n";
if(mysql_query(mysql, ctrans))
SetError(mysql_error(mysql), ctrans);
level--;
if(MysqlQuery(ctrans))
level--;
}
void MySqlSession::Rollback()
@ -142,9 +183,8 @@ void MySqlSession::Rollback()
static const char rtrans[] = "rollback";
if(trace)
*trace << rtrans << ";\n";
if(mysql_query(mysql, rtrans))
SetError(mysql_error(mysql), rtrans);
if(level > 0) level--;
if(MysqlQuery(rtrans) && level > 0)
level--;
}
int MySqlSession::GetTransactionLevel() const
@ -261,14 +301,8 @@ bool MySqlConnection::Execute() {
s++;
}
Cancel();
/* Stream *trace = session.GetTrace();
dword time;
if(session.IsTraceTime())
time = GetTickCount();*/
if(mysql_query(mysql, query)) {
session.SetError(mysql_error(mysql), query);
if(!MysqlQuery(query))
return false;
}
result = mysql_store_result(mysql);
rows = (int)mysql_affected_rows(mysql);
if(result) {

View file

@ -44,9 +44,25 @@ private:
MYSQL *mysql;
String username;
double lastid;
int level;
int level;
String connect_user;
String connect_password;
String connect_database;
String connect_host;
int connect_port;
String connect_socket;
bool MysqlQuery(const char *query);
bool DoConnect();
bool Reconnect();
friend class MySqlConnection;
typedef MySqlSession CLASSNAME;
public:
Gate WhenReconnect;
bool Connect(const char *user = NULL, const char *password = NULL, const char *database = NULL,
const char *host = NULL, int port = MYSQL_PORT, const char *socket = NULL);
bool Open(const char *connect);
@ -60,6 +76,8 @@ public:
virtual void Commit();
virtual void Rollback();
virtual int GetTransactionLevel() const;
void AutoReconnect() { WhenReconnect = THISBACK(Reconnect); }
MySqlSession() { mysql = NULL; Dialect(MY_SQL); }
~MySqlSession() { Close(); }