From 8bf7fb7bedf899a6a1dd62ad56ad9f09f6228747 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Tue, 21 Oct 2014 01:34:32 +0200 Subject: [PATCH] add: initial mysql-related stuff for job fetching uses libmysqlclient-dev for building --- .gitignore | 3 + Makefile | 4 +- debian/control | 2 +- src/database.cpp | 1 + src/database.h | 17 +++++ src/main.cpp | 22 +++++- src/mysql.cpp | 180 +++++++++++++++++++++++++++++++++++++++++++++++ src/mysql.h | 35 +++++++++ 8 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 src/database.cpp create mode 100644 src/database.h create mode 100644 src/mysql.cpp create mode 100644 src/mysql.h diff --git a/.gitignore b/.gitignore index 9cd9963..5abf918 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ bin dep obj + +# Emacs +*~ diff --git a/Makefile b/Makefile index 6c98274..011da11 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ LD=${LT_LD} CFLAGS=-O3 -g -flto -Wall -Werror -Wextra -pedantic -std=c++11 CXXFLAGS=$(CFLAGS) -LDFLAGS=-O3 -g -flto +LDFLAGS=-O3 -g -flto -lmysqlclient SRC_DIR=src OBJ_DIR=obj @@ -97,7 +97,7 @@ collissiondetect: cassiopeia: bin/cassiopeia bin/cassiopeia: libs ${FS_OBJ} - ${MKDIR} $(shell dirname $@) && ${LT_LD} -o $@ ${FS_OBJ} + ${MKDIR} $(shell dirname $@) && ${LT_LD} ${LDFLAGS} -o $@ ${FS_OBJ} ${DEP_DIR}/%.d: ${SRC_DIR}/%.cpp ${MKDIR} $(shell dirname $@) && $(CXX_DEP) $(CXXFLAGS) -M -MF $@ $< diff --git a/debian/control b/debian/control index 493d920..a124076 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: cassiopeia Section: unknown Priority: extra Maintainer: CAcert Software Team -Build-Depends: debhelper (>= 8.0.0), libtool +Build-Depends: debhelper (>= 8.0.0), libtool, libmysqlclient-dev (>= 5.5) Standards-Version: 3.9.4 Homepage: https://cacert.org/ #Vcs-Git: git://git.debian.org/collab-maint/cassiopeia.git diff --git a/src/database.cpp b/src/database.cpp new file mode 100644 index 0000000..7eabc17 --- /dev/null +++ b/src/database.cpp @@ -0,0 +1 @@ +#include "database.h" diff --git a/src/database.h b/src/database.h new file mode 100644 index 0000000..b189807 --- /dev/null +++ b/src/database.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +struct Job { + std::string id; + std::string task; + std::string from; + std::string to; +}; + +class JobProvider { +public: + virtual std::shared_ptr fetchJob() = 0; + virtual bool finishJob( std::shared_ptr job ) = 0; +}; diff --git a/src/main.cpp b/src/main.cpp index 854bf8f..bf4df81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,10 +16,28 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + +#include "database.h" +#include "mysql.h" int main( int argc, const char* argv[] ) { - ( void )argc; - ( void )argv; + if( argc < 2 ) { + std::cout << argv[0] << " password" << std::endl; + return 1; + } + + std::shared_ptr jp( new MySQLJobProvider( "localhost", "cacert", argv[1], "cacert" ) ); + std::shared_ptr job = jp->fetchJob(); + + if( !job ) { + std::cout << "Nothing to work on" << std::endl; + return 2; + } + + if( !jp->finishJob( job ) ) { + return 1; + } return 0; } diff --git a/src/mysql.cpp b/src/mysql.cpp new file mode 100644 index 0000000..38cb606 --- /dev/null +++ b/src/mysql.cpp @@ -0,0 +1,180 @@ +#include "mysql.h" + +#include + +#include + +//This static variable exists to handle initializing and finalizing the MySQL driver library +std::shared_ptr MySQLJobProvider::lib_ref( + //Initializer: Store the return code as a pointer to an integer + new int( mysql_library_init( 0, NULL, NULL ) ), + //Finalizer: Check the pointer and free resources + []( int* ref ) { + if( !ref ) { + //The library is not initialized + return; + } + + if( *ref ) { + //The library did return an error when initializing + delete ref; + return; + } + + delete ref; + + mysql_library_end(); + } ); + +MySQLJobProvider::MySQLJobProvider( const std::string& server, const std::string& user, const std::string& password, const std::string& database ) { + if( !lib_ref || *lib_ref ) { + throw "MySQL library not initialized!"; + } + + connect( server, user, password, database ); +} + +MySQLJobProvider::~MySQLJobProvider() { + disconnect(); +} + +bool MySQLJobProvider::connect( const std::string& server, const std::string& user, const std::string& password, const std::string& database ) { + if( conn ) { + if( !disconnect() ) { + return false; + } + + conn.reset(); + } + + conn = _connect( server, user, password, database ); + + return !!conn; +} + +std::shared_ptr MySQLJobProvider::_connect( const std::string& server, const std::string& user, const std::string& password, const std::string& database ) { + MYSQL* tmp( mysql_init( NULL ) ); + + if( !tmp ) { + return std::shared_ptr(); + } + + tmp = mysql_real_connect( tmp, server.c_str(), user.c_str(), password.c_str(), database.c_str(), 3306, NULL, CLIENT_COMPRESS ); + + if( !tmp ) { + return std::shared_ptr(); + } + + auto l = lib_ref; + return std::shared_ptr( + tmp, + [l]( MYSQL * c ) { + if( c ) { + mysql_close( c ); + } + } ); +} + +bool MySQLJobProvider::disconnect() { + if( !conn ) { + return false; + } + + conn.reset(); + + return true; +} + +std::pair< int, std::shared_ptr > MySQLJobProvider::query( const std::string& query ) { + if( !conn ) { + return std::make_pair( CR_SERVER_LOST, std::shared_ptr() ); + } + + int err = mysql_real_query( this->conn.get(), query.c_str(), query.size() ); + + if( err ) { + return std::make_pair( err, std::shared_ptr() ); + } + + auto c = conn; + std::shared_ptr res( + mysql_store_result( conn.get() ), + [c]( MYSQL_RES * r ) { + if( !r ) { + return; + } + + mysql_free_result( r ); + } ); + + return std::make_pair( err, res ); +} + +std::shared_ptr MySQLJobProvider::fetchJob() { + std::string q = "SELECT id, targetId, task, executeFrom, executeTo FROM jobs WHERE state='open'"; + + int err = 0; + std::shared_ptr res; + + std::tie( err, res ) = query( q ); + + if( err ) { + return std::shared_ptr(); + } + + unsigned int num = mysql_num_fields( res.get() ); + + MYSQL_ROW row = mysql_fetch_row( res.get() ); + + if( !row ) { + return std::shared_ptr(); + } + + std::shared_ptr job( new Job() ); + + unsigned long* l = mysql_fetch_lengths( res.get() ); + + if( !l ) { + return std::shared_ptr(); + } + + job->id = std::string( row[0], row[0] + l[0] ); + + for( unsigned int i = 0; i < num; i++ ) { + printf( "[%.*s] ", ( int ) l[i], row[i] ? row[i] : "NULL" ); + } + + printf( "\n" ); + + return job; +} + +std::string MySQLJobProvider::escape_string( const std::string& target ) { + if( !conn ) { + throw "Not connected!"; + } + + std::string result; + + result.resize( target.size() * 2 ); + + long unsigned int len = mysql_real_escape_string( conn.get(), const_cast( result.data() ), target.c_str(), target.size() ); + + result.resize( len ); + + return result; +} + +bool MySQLJobProvider::finishJob( std::shared_ptr job ) { + if( !conn ) { + return false; + } + + std::string q = "UPDATE jobs SET state='done' WHERE id='" + this->escape_string( job->id ) + "' LIMIT 1"; + + if( query( q ).first ) { + return false; + } + + return true; +} diff --git a/src/mysql.h b/src/mysql.h new file mode 100644 index 0000000..f27d0d8 --- /dev/null +++ b/src/mysql.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include +#include +#include + +#include "database.h" + +class MySQLJobProvider : public JobProvider { +private: + static std::shared_ptr lib_ref; + + std::shared_ptr conn; + +private: + std::shared_ptr _connect( const std::string& server, const std::string& user, const std::string& password, const std::string& database ); + +public: + MySQLJobProvider( const std::string& server, const std::string& user, const std::string& password, const std::string& database ); + ~MySQLJobProvider(); + +public: + bool connect( const std::string& server, const std::string& user, const std::string& password, const std::string& database ); + bool disconnect(); + + std::string escape_string( const std::string& target ); + + std::pair< int, std::shared_ptr > query( const std::string& query ); + +public: + std::shared_ptr fetchJob(); + bool finishJob( std::shared_ptr job ); +}; -- 2.39.2