]> WPIA git - cassiopeia.git/commitdiff
add: initial mysql-related stuff for job fetching
authorFelix Dörre <felix@dogcraft.de>
Mon, 20 Oct 2014 23:34:32 +0000 (01:34 +0200)
committerBenny Baumann <BenBE@geshi.org>
Fri, 7 Nov 2014 22:52:10 +0000 (23:52 +0100)
uses libmysqlclient-dev for building

.gitignore
Makefile
debian/control
src/database.cpp [new file with mode: 0644]
src/database.h [new file with mode: 0644]
src/main.cpp
src/mysql.cpp [new file with mode: 0644]
src/mysql.h [new file with mode: 0644]

index 9cd9963bf82d5b5ce3ab04b91e42b638a931cf7b..5abf918e1702c7a9c47a14b1302261515e3a6245 100644 (file)
@@ -24,3 +24,6 @@
 bin
 dep
 obj
+
+# Emacs
+*~
index 6c982744e383cc21453ce242c50509d4f7568724..011da11564aef1e222125515a0362092f4eb840b 100644 (file)
--- 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 $@ $<
index 493d9207b295cc7a43937d8e2455627ccf4256d9..a124076b61c8bcfa0994e40992b4cb6e3b7a0e66 100644 (file)
@@ -2,7 +2,7 @@ Source: cassiopeia
 Section: unknown
 Priority: extra
 Maintainer: CAcert Software Team <cacert-devel@cacert.org>
-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 (file)
index 0000000..7eabc17
--- /dev/null
@@ -0,0 +1 @@
+#include "database.h"
diff --git a/src/database.h b/src/database.h
new file mode 100644 (file)
index 0000000..b189807
--- /dev/null
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <string>
+#include <memory>
+
+struct Job {
+    std::string id;
+    std::string task;
+    std::string from;
+    std::string to;
+};
+
+class JobProvider {
+public:
+    virtual std::shared_ptr<Job> fetchJob() = 0;
+    virtual bool finishJob( std::shared_ptr<Job> job ) = 0;
+};
index 854bf8fd71ad198d7dcfe775e128394be64f1e0c..bf4df813209d7d384769989ab0e9782a770d8419 100644 (file)
     with this program; if not, write to the Free Software Foundation, Inc.,
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#include <iostream>
+
+#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<JobProvider> jp( new MySQLJobProvider( "localhost", "cacert", argv[1], "cacert" ) );
+    std::shared_ptr<Job> 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 (file)
index 0000000..38cb606
--- /dev/null
@@ -0,0 +1,180 @@
+#include "mysql.h"
+
+#include <stdio.h>
+
+#include <mysql/errmsg.h>
+
+//This static variable exists to handle initializing and finalizing the MySQL driver library
+std::shared_ptr<int> 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<MYSQL> 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<MYSQL>();
+    }
+
+    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<MYSQL>();
+    }
+
+    auto l = lib_ref;
+    return std::shared_ptr<MYSQL>(
+        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<MYSQL_RES> > MySQLJobProvider::query( const std::string& query ) {
+    if( !conn ) {
+        return std::make_pair( CR_SERVER_LOST, std::shared_ptr<MYSQL_RES>() );
+    }
+
+    int err = mysql_real_query( this->conn.get(), query.c_str(), query.size() );
+
+    if( err ) {
+        return std::make_pair( err, std::shared_ptr<MYSQL_RES>() );
+    }
+
+    auto c = conn;
+    std::shared_ptr<MYSQL_RES> 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<Job> MySQLJobProvider::fetchJob() {
+    std::string q = "SELECT id, targetId, task, executeFrom, executeTo FROM jobs WHERE state='open'";
+
+    int err = 0;
+    std::shared_ptr<MYSQL_RES> res;
+
+    std::tie( err, res ) = query( q );
+
+    if( err ) {
+        return std::shared_ptr<Job>();
+    }
+
+    unsigned int num = mysql_num_fields( res.get() );
+
+    MYSQL_ROW row = mysql_fetch_row( res.get() );
+
+    if( !row ) {
+        return std::shared_ptr<Job>();
+    }
+
+    std::shared_ptr<Job> job( new Job() );
+
+    unsigned long* l = mysql_fetch_lengths( res.get() );
+
+    if( !l ) {
+        return std::shared_ptr<Job>();
+    }
+
+    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<char*>( result.data() ), target.c_str(), target.size() );
+
+    result.resize( len );
+
+    return result;
+}
+
+bool MySQLJobProvider::finishJob( std::shared_ptr<Job> 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 (file)
index 0000000..f27d0d8
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <mysql/mysql.h>
+
+#include <string>
+#include <memory>
+#include <tuple>
+
+#include "database.h"
+
+class MySQLJobProvider : public JobProvider {
+private:
+    static std::shared_ptr<int> lib_ref;
+
+    std::shared_ptr<MYSQL> conn;
+
+private:
+    std::shared_ptr<MYSQL> _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<MYSQL_RES> > query( const std::string& query );
+
+public:
+    std::shared_ptr<Job> fetchJob();
+    bool finishJob( std::shared_ptr<Job> job );
+};