Created
May 13, 2011 14:52
-
-
Save HarryR/970667 to your computer and use it in GitHub Desktop.
Easy interface to HandlerSocket for QT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef EASYHS_HPP_ | |
#define EASYHS_HPP_ | |
#pragma once | |
#include <handlersocket/hstcpcli.hpp> | |
#include <QList> | |
#include <QVariant> | |
#include <QRunnable> | |
#include <QObject> | |
#include <QMetaProperty> | |
#include <QMetaObject> | |
class EasyHS { | |
private: | |
struct dena::config hs_cfg; | |
struct dena::socket_args hs_sa; | |
dena::hstcpcli_ptr cli; | |
size_t hs_id; | |
public: | |
EasyHS(const char *host, const char *port) | |
: hs_id(0) | |
{ | |
hs_cfg["host"] = host; | |
hs_cfg["port"] = port; | |
hs_sa.set(hs_cfg); | |
cli = dena::hstcpcli_i::create(hs_sa); | |
} | |
~EasyHS() | |
{ cli->close(); } | |
int error_code() | |
{ return cli->get_error_code(); } | |
bool is_stable() | |
{ return cli->stable_point(); } | |
struct dena::hstcpcli_i *get_cli() | |
{ return cli.get(); } | |
size_t next_id() | |
{ return ++hs_id; } | |
}; | |
template <typename Tr, typename Ti> | |
class HSIndex { | |
int m_id; | |
EasyHS *m_hs; | |
public: | |
typedef QList<Tr*> results_t; | |
public: | |
HSIndex() | |
: m_id(-1), m_hs(NULL) | |
{} | |
HSIndex(EasyHS *hs) | |
: m_id(-1), m_hs(hs) | |
{} | |
bool | |
open( const char *db = NULL, const char *table = NULL, const char *index = NULL ) { | |
// Get parameters from classinfo | |
if( db == NULL || table == NULL || index == NULL ) | |
{ | |
const QMetaObject mo = Ti::staticMetaObject; | |
if( db == NULL ) { | |
int mo_db = mo.indexOfClassInfo("database"); | |
assert( mo_db >= 0 ); | |
db = mo.classInfo(mo_db).value(); | |
} | |
if( table == NULL ) { | |
int mo_table = mo.indexOfClassInfo("table"); | |
assert( mo_table >= 0 ); | |
table = mo.classInfo(mo_table).value(); | |
} | |
if( index == NULL ) { | |
int mo_index = mo.indexOfClassInfo("index"); | |
assert( mo_index >= 0 ); | |
index = mo.classInfo(mo_index).value(); | |
} | |
} | |
// Fields which will be returned | |
QByteArray fields; | |
const QMetaObject mo = Tr::staticMetaObject; | |
assert( mo.propertyCount() > 0 ); | |
for( int i = mo.propertyOffset(); i < mo.propertyCount(); i++ ) { | |
QMetaProperty qmp = mo.property(i); | |
assert( qmp.isWritable() ); | |
assert( qmp.isValid() ); | |
if( fields.size() ) { | |
fields.append(","); | |
} | |
fields.append( qmp.name() ); | |
} | |
size_t id = m_hs->next_id(); | |
struct dena::hstcpcli_i *cli = m_hs->get_cli(); | |
cli->request_buf_open_index(id, db, table, index, fields.data()); | |
if( cli->get_error_code() < 0 ) { | |
return false; | |
} | |
if( cli->request_send() != 0 ) { | |
return false; | |
} | |
size_t num_flds; | |
int result = cli->response_recv(num_flds); | |
if( result >= 0 ) { | |
cli->response_buf_remove(); | |
m_id = id; | |
} | |
return result >= 0; | |
} | |
results_t* select(const char *op, Ti* fields_obj, int limit = 1, int skip = 0 ) | |
{ | |
dena::string_ref op_ref = dena::string_ref(op, strlen(op)); | |
dena::string_ref modop_ref; | |
struct dena::hstcpcli_i * cli = m_hs->get_cli(); | |
assert( m_hs->is_stable() ); | |
const QMetaObject *mo = fields_obj->metaObject(); | |
assert( mo->propertyCount() > 0 ); | |
std::vector<dena::string_ref> fields; | |
{ | |
int i; | |
for( i = mo->propertyOffset(); i < mo->propertyCount(); i++ ) { | |
QMetaProperty qmp = mo->property(i); | |
assert( qmp.isWritable() ); | |
assert( qmp.isValid() ); | |
QString value = qmp.read(fields_obj).toString(); | |
fields.push_back( dena::string_ref( value.toAscii(), value.size() ) ); | |
} | |
} | |
if( limit < 0 ) limit = 0; | |
if( skip < 0 ) skip = 0; | |
cli->request_buf_exec_generic( | |
m_id, op_ref, &fields[0], fields.size(), limit, skip, | |
// Other parameters not required for selects | |
dena::string_ref(), 0, 0); | |
if( cli->request_send() != 0 ) { | |
return NULL; | |
} | |
mo = &Tr::staticMetaObject; | |
size_t result_num_flds = fields.size(); | |
int result = cli->response_recv(result_num_flds); | |
results_t* results = NULL; | |
if( result >= 0 ) { | |
const dena::string_ref * row; | |
results = new results_t(); //new results_t(); | |
do { | |
if( results->size() >= limit ) { | |
break; | |
} | |
row = cli->get_next_row(); | |
if( row ) { | |
Tr *obj = new Tr(); | |
int i; | |
for( i = mo->propertyOffset(); i < mo->propertyCount(); i++ ) { | |
if( i - mo->propertyOffset() >= result_num_flds ) break; | |
QMetaProperty qmp = mo->property(i); | |
Q_ASSERT( qmp.isReadable() ); | |
Q_ASSERT( qmp.isWritable() ); | |
Q_ASSERT( qmp.isValid() ); | |
Q_ASSERT( qmp.isScriptable() ); | |
const dena::string_ref ref = row[i - mo->propertyOffset()]; | |
qmp.write(obj, QString::fromUtf8(ref.begin(), ref.size())); | |
} | |
results->append( obj ); | |
} | |
} while( row != NULL ); | |
} | |
cli->response_buf_remove(); | |
return results; | |
} | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It uses QObjects with properties and classinfo to infer which fields should be retrieved and to populate the return objects.
In order to run queries against an index and return rows you would use: