optionally (compile-time change for now) store message data as

b64-encoded TEXT instead of BYTEA, which on my laptop is getting
corrupted sometimes.
This commit is contained in:
Eric House 2013-01-21 19:39:57 -08:00
parent ae9ec31863
commit d374d0f3d8
3 changed files with 60 additions and 34 deletions

View file

@ -27,6 +27,8 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <glib.h>
#include "dbmgr.h" #include "dbmgr.h"
#include "mlock.h" #include "mlock.h"
#include "configs.h" #include "configs.h"
@ -60,6 +62,7 @@ DBMgr::Get()
DBMgr::DBMgr() DBMgr::DBMgr()
{ {
logf( XW_LOGINFO, "%s called", __func__ ); logf( XW_LOGINFO, "%s called", __func__ );
m_useB64 = false;
pthread_key_create( &m_conn_key, destr_function ); pthread_key_create( &m_conn_key, destr_function );
@ -785,30 +788,67 @@ DBMgr::StoreMessage( const char* const connName, int hid,
size_t newLen; size_t newLen;
const char* fmt = "INSERT INTO " MSGS_TABLE const char* fmt = "INSERT INTO " MSGS_TABLE
" (connname, hid, devid, token, msg, msglen)" " (connname, hid, devid, token, %s, msglen)"
" VALUES( '%s', %d, %d, " " VALUES( '%s', %d, %d, "
"(SELECT tokens[%d] from " GAMES_TABLE " where connname='%s'), " "(SELECT tokens[%d] from " GAMES_TABLE " where connname='%s'), "
"E'%s', %d)"; "%s'%s', %d)";
string query;
if ( m_useB64 ) {
gchar* b64 = g_base64_encode( buf, len );
string_printf( query, fmt, "msg64", connName, hid, devID, hid, connName,
"", b64, len );
g_free( b64 );
} else {
unsigned char* bytes = PQescapeByteaConn( getThreadConn(), buf, unsigned char* bytes = PQescapeByteaConn( getThreadConn(), buf,
len, &newLen ); len, &newLen );
assert( NULL != bytes ); assert( NULL != bytes );
string query; string_printf( query, fmt, "msg", connName, hid, devID, hid, connName,
string_printf( query, fmt, connName, hid, devID, hid, connName, "E", bytes, len );
bytes, len );
PQfreemem( bytes ); PQfreemem( bytes );
}
logf( XW_LOGINFO, "%s: query: %s", __func__, query.c_str() ); logf( XW_LOGINFO, "%s: query: %s", __func__, query.c_str() );
execSql( query ); execSql( query );
} }
void
decodeMessage( PGresult* result, bool useB64, int b64indx, int byteaIndex,
unsigned char* buf, size_t* buflen )
{
const char* from = NULL;
if ( useB64 ) {
from = PQgetvalue( result, 0, b64indx );
}
if ( NULL == from ) {
useB64 = false;
from = PQgetvalue( result, 0, byteaIndex );
}
size_t to_length;
if ( useB64 ) {
gsize out_len;
guchar* txt = g_base64_decode( (const gchar*)from, &out_len );
to_length = out_len;
assert( to_length <= *buflen );
memcpy( buf, txt, to_length );
g_free( txt );
} else {
unsigned char* bytes = PQunescapeBytea( (const unsigned char*)from,
&to_length );
assert( to_length <= *buflen );
memcpy( buf, bytes, to_length );
PQfreemem( bytes );
}
*buflen = to_length;
}
bool bool
DBMgr::GetNthStoredMessage( const char* const connName, int hid, int nn, DBMgr::GetNthStoredMessage( const char* const connName, int hid, int nn,
unsigned char* buf, size_t* buflen, int* msgID ) unsigned char* buf, size_t* buflen, int* msgID )
{ {
const char* fmt = "SELECT id, msg, msglen FROM " MSGS_TABLE const char* fmt = "SELECT id, msg, msg64, msglen FROM " MSGS_TABLE
" WHERE connName = '%s' AND hid = %d " " WHERE connName = '%s' AND hid = %d "
#ifdef HAVE_STIME #ifdef HAVE_STIME
"AND stime IS NULL " "AND stime IS NULL "
@ -827,18 +867,9 @@ DBMgr::GetNthStoredMessage( const char* const connName, int hid, int nn,
if ( NULL != msgID ) { if ( NULL != msgID ) {
*msgID = atoi( PQgetvalue( result, 0, 0 ) ); *msgID = atoi( PQgetvalue( result, 0, 0 ) );
} }
size_t msglen = atoi( PQgetvalue( result, 0, 2 ) ); size_t msglen = atoi( PQgetvalue( result, 0, 3 ) );
decodeMessage( result, m_useB64, 2, 1, buf, buflen );
/* int len = PQgetlength( result, 0, 1 ); */ assert( 0 == msglen || msglen == *buflen );
const unsigned char* from =
(const unsigned char* )PQgetvalue( result, 0, 1 );
size_t to_length;
unsigned char* bytes = PQunescapeBytea( from, &to_length );
assert( to_length <= *buflen );
memcpy( buf, bytes, to_length );
PQfreemem( bytes );
*buflen = to_length;
assert( 0 == msglen || to_length == msglen );
} }
PQclear( result ); PQclear( result );
return found; return found;
@ -855,7 +886,7 @@ bool
DBMgr::GetStoredMessage( int msgID, unsigned char* buf, size_t* buflen, DBMgr::GetStoredMessage( int msgID, unsigned char* buf, size_t* buflen,
AddrInfo::ClientToken* token ) AddrInfo::ClientToken* token )
{ {
const char* fmt = "SELECT token, msg, msglen FROM " MSGS_TABLE const char* fmt = "SELECT token, msg, msg64, msglen FROM " MSGS_TABLE
" WHERE id = %d " " WHERE id = %d "
#ifdef HAVE_STIME #ifdef HAVE_STIME
"AND stime IS NULL " "AND stime IS NULL "
@ -872,16 +903,9 @@ DBMgr::GetStoredMessage( int msgID, unsigned char* buf, size_t* buflen,
bool found = nTuples == 1; bool found = nTuples == 1;
if ( found ) { if ( found ) {
*token = atoi( PQgetvalue( result, 0, 0 ) ); *token = atoi( PQgetvalue( result, 0, 0 ) );
size_t msglen = atoi( PQgetvalue( result, 0, 2 ) ); size_t msglen = atoi( PQgetvalue( result, 0, 3 ) );
const unsigned char* from = decodeMessage( result, m_useB64, 2, 1, buf, buflen );
(const unsigned char* )PQgetvalue( result, 0, 1 ); assert( 0 == msglen || *buflen == msglen );
size_t to_length;
unsigned char* bytes = PQunescapeBytea( from, &to_length );
assert( to_length <= *buflen );
memcpy( buf, bytes, to_length );
PQfreemem( bytes );
*buflen = to_length;
assert( 0 == msglen || to_length == msglen );
} }
PQclear( result ); PQclear( result );
return found; return found;

View file

@ -128,6 +128,7 @@ class DBMgr {
void conn_key_alloc(); void conn_key_alloc();
pthread_key_t m_conn_key; pthread_key_t m_conn_key;
bool m_useB64;
}; /* DBMgr */ }; /* DBMgr */

View file

@ -72,6 +72,7 @@ id SERIAL
,stime TIMESTAMP DEFAULT NULL ,stime TIMESTAMP DEFAULT NULL
,devid INTEGER ,devid INTEGER
,msg BYTEA ,msg BYTEA
,msg64 TEXT
,msglen INTEGER ,msglen INTEGER
,UNIQUE ( connName, hid, msg ) ,UNIQUE ( connName, hid, msg )
); );