Subject Re: [firebird-tools] Re: Best 3rd party product for firebird full
Author Philippe Makowski
Philippe Makowski [2007-12-21 16:34] :
> Yes, for what I know a Firebird port exist and should be (soon ?) delivered
>
> Pierre, can you tell us more about Sphynx and Firebid ?
>
So here the reply from Pierre :
Hi guys,

I have started to port SphinxSearch for Firebird but I still have
problems with blobs API so my patchset is not fully useable. It requires
some more works to be achieved. Maybe can someone help me with the
Firebird API ? I need a simple function that can return the contents of
a blob as a char *, PostgreSQL code works like this :

const char * CSphSource_PgSQL::SqlColumn ( int iIndex )
{
if ( !m_pPgResult )
return NULL;

return PQgetvalue ( m_pPgResult, m_iPgRow, iIndex );
}

I used the code from API examples to achieve the same with Firebird :

const char * CSphSource_Firebird::SqlColumn ( int iIndex )
{
if ( !m_tFbStmtHandle )
return NULL;

XSQLVAR *var = (XSQLVAR *) &m_tFbSQLDA->sqlvar[iIndex];

short dtype;
char data[1024], *p;
char blob_s[20], date_s[25];
PARAMVARY *vary2;
struct tm times;
ISC_QUAD bid;

dtype = var->sqltype & ~1;
p = data;

/* Null handling. If the column is nullable and null */
if ((var->sqltype & 1) && (*var->sqlind < 0))
{
return NULL;
}
else
{
switch (dtype)
{
case SQL_TEXT:
sprintf(p, "%.*s ", var->sqllen, var->sqldata);
break;
case SQL_VARYING:
vary2 = (PARAMVARY*) var->sqldata;
vary2->vary_string[vary2->vary_length] = '\0';
sprintf(p, "%-*s ", var->sqllen, vary2->vary_string);
break;
case SQL_SHORT:
case SQL_LONG:
case SQL_INT64:
{
ISC_INT64 value;
short field_width;
short dscale;
switch (dtype)
{
case SQL_SHORT:
value = (ISC_INT64) *(short *) var->sqldata;
field_width = 6;
break;
case SQL_LONG:
value = (ISC_INT64) *(int *) var->sqldata;
field_width = 11;
break;
case SQL_INT64:
value = (ISC_INT64) *(ISC_INT64 *) var->sqldata;
field_width = 21;
break;
}
dscale = var->sqlscale;
if (dscale < 0)
{
ISC_INT64 tens;
short i;

tens = 1;
for (i = 0; i > dscale; i--)
tens *= 10;

if (value >= 0)
sprintf (p, "%*" ISC_INT64_FORMAT "d.%0*"
ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
(ISC_INT64) value / tens,
-dscale,
(ISC_INT64) value % tens);
else if ((value / tens) != 0)
sprintf (p, "%*" ISC_INT64_FORMAT "d.%0*"
ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
(ISC_INT64) (value / tens),
-dscale,
(ISC_INT64) -(value % tens));
else
sprintf (p, "%*s.%0*" ISC_INT64_FORMAT "d",
field_width - 1 + dscale,
"-0",
-dscale,
(ISC_INT64) -(value % tens));
}
else if (dscale)
sprintf (p, "%*" ISC_INT64_FORMAT "d%0*d",
field_width,
(ISC_INT64) value,
dscale, 0);
else
sprintf (p, "%*" ISC_INT64_FORMAT "d%",
field_width,
(ISC_INT64) value);
}
break;

case SQL_FLOAT:
sprintf(p, "%15g ", *(float *) (var->sqldata));
break;

case SQL_DOUBLE:
sprintf(p, "%24f ", *(double *) (var->sqldata));
break;

case SQL_TIMESTAMP:
isc_decode_timestamp((ISC_TIMESTAMP *)var->sqldata, ×);
sprintf(date_s, "%04d-%02d-%02d %02d:%02d:%02d.%04d",
times.tm_year + 1900,
times.tm_mon+1,
times.tm_mday,
times.tm_hour,
times.tm_min,
times.tm_sec,
((ISC_TIMESTAMP *)var->sqldata)->timestamp_time %
10000);
sprintf(p, "%*s ", 24, date_s);
break;

case SQL_TYPE_DATE:
isc_decode_sql_date((ISC_DATE *)var->sqldata, ×);
sprintf(date_s, "%04d-%02d-%02d",
times.tm_year + 1900,
times.tm_mon+1,
times.tm_mday);
sprintf(p, "%*s ", 10, date_s);
break;

case SQL_TYPE_TIME:
isc_decode_sql_time((ISC_TIME *)var->sqldata, ×);
sprintf(date_s, "%02d:%02d:%02d.%04d",
times.tm_hour,
times.tm_min,
times.tm_sec,
(*((ISC_TIME *)var->sqldata)) % 10000);
sprintf(p, "%*s ", 13, date_s);
break;

case SQL_BLOB:
case SQL_ARRAY:
/* Print the blob id on blobs or arrays */
bid = *(ISC_QUAD *) var->sqldata;
sprintf(blob_s, "%08x:%08x", bid.gds_quad_high,
bid.gds_quad_low);
sprintf(p, "%17s ", blob_s);
break;

default:
break;
}
}

return p;
}

And as you can see at the very bottom of the function, I don't read nor
blobs or arrays, just return their ID.... maybe insufficient for a full
text search engine ;-)

Regards,

--
Pierre Y.