mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-11-04 08:04:12 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			208 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// rddb.cpp
 | 
						|
//
 | 
						|
//   Database driver with automatic reconnect
 | 
						|
//
 | 
						|
//   (C) Copyright 2007 Dan Mills <dmills@exponent.myzen.co.uk>
 | 
						|
//   (C) Copyright 2018-2019 Fred Gleason <fredg@paravelsystems.com>
 | 
						|
//
 | 
						|
//   This program is free software; you can redistribute it and/or modify
 | 
						|
//   it under the terms of the GNU General Public License version 2 as
 | 
						|
//   published by the Free Software Foundation.
 | 
						|
//
 | 
						|
//   This program is distributed in the hope that it will be useful,
 | 
						|
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
//   GNU General Public License for more details.
 | 
						|
//
 | 
						|
//   You should have received a copy of the GNU General Public
 | 
						|
//   License along with this program; if not, write to the Free Software
 | 
						|
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
//
 | 
						|
 | 
						|
#include <netdb.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <syslog.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <sys/types.h>
 | 
						|
 | 
						|
#include <QObject>
 | 
						|
#include <QString>
 | 
						|
#include <QTextCodec>
 | 
						|
#include <QTranslator>
 | 
						|
#include <QSqlError>
 | 
						|
#include <QStringList>
 | 
						|
#include <QVariant>
 | 
						|
 | 
						|
#include "rdapplication.h"
 | 
						|
#include "rddb.h"
 | 
						|
#include "rddbheartbeat.h"
 | 
						|
 | 
						|
RDSqlQuery::RDSqlQuery (const QString &query,bool reconnect):
 | 
						|
  QSqlQuery(query)
 | 
						|
{
 | 
						|
  QSqlDatabase db;
 | 
						|
  QString err;
 | 
						|
  sql_columns=0;
 | 
						|
 | 
						|
  if (!isActive() && reconnect) {
 | 
						|
    db = QSqlDatabase::database();
 | 
						|
 | 
						|
    if (db.open()) {
 | 
						|
      clear();
 | 
						|
      exec(query);
 | 
						|
      err=QObject::tr("DB connection re-established");
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      err=QObject::tr("Could not re-establish DB connection")+
 | 
						|
      +"["+db.lastError().text()+"]";
 | 
						|
    }
 | 
						|
 | 
						|
    fprintf(stderr,"%s\n",(const char *)err);
 | 
						|
    if(rda!=NULL) {
 | 
						|
      rda->syslog(LOG_ERR,(const char *)err);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if(isActive()) {
 | 
						|
    //printf("QUERY: %s\n",(const char *)query.toUtf8());
 | 
						|
    QStringList f0=query.split(" ");
 | 
						|
    if(f0[0].toLower()=="select") {
 | 
						|
      for(int i=1;i<f0.size();i++) {
 | 
						|
	if(f0[i].toLower()=="from") {
 | 
						|
	  QString fields;
 | 
						|
	  for(int j=1;j<i;j++) {
 | 
						|
	    fields+=f0[j];
 | 
						|
	  }
 | 
						|
	  QStringList f1=fields.split(",");
 | 
						|
	  sql_columns=f1.size();
 | 
						|
	  continue;
 | 
						|
	}
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    err=QObject::tr("invalid SQL or failed DB connection")+
 | 
						|
      +"["+lastError().text()+"]: "+query;
 | 
						|
 | 
						|
    fprintf(stderr,"%s\n",(const char *)err);
 | 
						|
    if(rda!=NULL) {
 | 
						|
      rda->syslog(LOG_ERR,(const char *)err);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int RDSqlQuery::columns() const
 | 
						|
{
 | 
						|
  return sql_columns;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
QVariant RDSqlQuery::value(int index) const
 | 
						|
{
 | 
						|
  QVariant ret=QSqlQuery::value(index);
 | 
						|
 | 
						|
  if(!ret.isValid()) {
 | 
						|
    fprintf(stderr,"for query: %s\n\n",(const char *)executedQuery().toUtf8());
 | 
						|
  }
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
QVariant RDSqlQuery::run(const QString &sql,bool *ok)
 | 
						|
{
 | 
						|
  QVariant ret;
 | 
						|
 | 
						|
  RDSqlQuery *q=new RDSqlQuery(sql);
 | 
						|
  if(ok!=NULL) {
 | 
						|
    *ok=q->isActive();
 | 
						|
  }
 | 
						|
  ret=q->lastInsertId();
 | 
						|
  delete q;
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDSqlQuery::apply(const QString &sql,QString *err_msg)
 | 
						|
{
 | 
						|
  bool ret=false;
 | 
						|
 | 
						|
  RDSqlQuery *q=new RDSqlQuery(sql);
 | 
						|
  ret=q->isActive();
 | 
						|
  if((err_msg!=NULL)&&(!ret)) {
 | 
						|
    *err_msg="sql error: "+q->lastError().text()+" query: "+sql;
 | 
						|
  }
 | 
						|
  delete q;
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int RDSqlQuery::rows(const QString &sql)
 | 
						|
{
 | 
						|
  int ret=0;
 | 
						|
 | 
						|
  RDSqlQuery *q=new RDSqlQuery(sql);
 | 
						|
  ret=q->size();
 | 
						|
  delete q;
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool RDOpenDb (int *schema,QString *err_str,RDConfig *config)
 | 
						|
{
 | 
						|
  QSqlDatabase db;
 | 
						|
  QString sql;
 | 
						|
  QSqlQuery *q;
 | 
						|
 | 
						|
  if (!db.isOpen()){
 | 
						|
    db=QSqlDatabase::addDatabase(config->mysqlDriver());
 | 
						|
    if(!db.isValid()) {
 | 
						|
      *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!"));
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    db.setHostName(config->mysqlHostname());
 | 
						|
    db.setDatabaseName(config->mysqlDbname());
 | 
						|
    db.setUserName(config->mysqlUsername());
 | 
						|
    db.setPassword(config->mysqlPassword());
 | 
						|
    if(!db.open()) {
 | 
						|
      *err_str+=QString(QObject::tr("Couldn't open MySQL connection on"))+
 | 
						|
	" \""+config->mysqlHostname()+"\".";
 | 
						|
      db.removeDatabase(config->mysqlDbname());
 | 
						|
      db.close();
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  new RDDbHeartbeat(config->mysqlHeartbeatInterval());
 | 
						|
  sql=QString("set NAMES utf8mb4 collate utf8mb4_general_ci");
 | 
						|
  q=new QSqlQuery(sql);
 | 
						|
  delete q;
 | 
						|
 | 
						|
  *schema=-1;
 | 
						|
  sql=QString("show tables where ")+
 | 
						|
    "Tables_in_"+config->mysqlDbname()+"=\"VERSION\"";
 | 
						|
  q=new QSqlQuery(sql);
 | 
						|
  if(q->first()) {
 | 
						|
    delete q;
 | 
						|
    q=new QSqlQuery("select DB from VERSION");
 | 
						|
    if(q->first()) {
 | 
						|
      *schema=q->value(0).toUInt();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    delete q;
 | 
						|
    sql=QString("show tables");
 | 
						|
    q=new QSqlQuery(sql);
 | 
						|
    if(!q->first()) {
 | 
						|
      *schema=0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  delete q;
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 |