static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea ) { PGconn * pConn = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pConn; SDDDATA * pSDDData; PGresult * pResult; ExecStatusType status; PHB_ITEM pItemEof, pItem; HB_USHORT uiFields, uiCount; HB_BOOL bError; DBFIELDINFO pFieldInfo; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; pResult = PQexec( pConn, pArea->szQuery ); if( ! pResult ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_LOWMEMORY, "Query failed", NULL, 0 ); /* Low memory, etc */ return HB_FAILURE; } status = PQresultStatus( pResult ); if( status != PGRES_TUPLES_OK && status != PGRES_COMMAND_OK ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_INVALIDQUERY, PQresultErrorMessage( pResult ), pArea->szQuery, ( HB_ERRCODE ) status ); PQclear( pResult ); return HB_FAILURE; } pSDDData->pResult = pResult; uiFields = ( HB_USHORT ) PQnfields( pResult ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); pItem = hb_itemNew( NULL ); bError = HB_FALSE; for( uiCount = 0; uiCount < uiFields; uiCount++ ) { pFieldInfo.atomName = PQfname( pResult, ( int ) uiCount ); pFieldInfo.uiDec = 0; switch( PQftype( pResult, ( int ) uiCount ) ) { case BPCHAROID: case VARCHAROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4; break; case TEXTOID: pFieldInfo.uiType = HB_FT_MEMO; pFieldInfo.uiLen = 10; break; case NUMERICOID: pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = ( PQfmod( pResult, uiCount ) - 4 ) >> 16; pFieldInfo.uiDec = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF; break; case INT2OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 6; break; case INT4OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 11; break; case INT8OID: case OIDOID: pFieldInfo.uiType = HB_FT_LONG; pFieldInfo.uiLen = 20; break; case FLOAT4OID: case FLOAT8OID: case CASHOID: /* TODO: ??? */ pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = 16; pFieldInfo.uiDec = 2; /* TODO: hb_set.SET_DECIMALS ??? */ break; case BOOLOID: pFieldInfo.uiType = HB_FT_LOGICAL; pFieldInfo.uiLen = 1; break; case DATEOID: pFieldInfo.uiType = HB_FT_DATE; pFieldInfo.uiLen = 8; break; case INETOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 29; break; case CIDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 32; break; case MACADDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 17; break; case BITOID: case VARBITOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfsize( pResult, uiCount ); break; case TIMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 12; break; case TIMESTAMPOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 23; break; case TIMETZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 15; break; case TIMESTAMPTZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 26; break; case NAMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 63; break; case BYTEAOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 0; break; default: pFieldInfo.uiType = 0; pFieldInfo.uiLen = 0; bError = HB_TRUE; break; } /* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", pFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */ if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; hb_itemPutCL( pItem, pStr, pFieldInfo.uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: hb_itemPutC( pItem, NULL ); hb_itemSetCMemo( pItem ); break; case HB_FT_INTEGER: hb_itemPutNI( pItem, 0 ); break; case HB_FT_LONG: hb_itemPutNL( pItem, 0 ); break; case HB_FT_DOUBLE: hb_itemPutND( pItem, 0.0 ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, HB_FALSE ); break; case HB_FT_DATE: hb_itemPutDS( pItem, NULL ); break; default: hb_itemClear( pItem ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiCount + 1, pItem ); /* if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER ) pFieldInfo.uiType = HB_IT_LONG; */ if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } if( bError ) break; } hb_itemRelease( pItem ); if( bError ) { hb_itemClear( pItemEof ); hb_itemRelease( pItemEof ); hb_errRT_PostgreSQLDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, 0 ); return HB_FAILURE; } pArea->ulRecCount = ( HB_ULONG ) PQntuples( pResult ); pArea->pRow = ( void ** ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); memset( pArea->pRowFlags, 0, ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); *pArea->pRow = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pArea->fFetched = HB_TRUE; return HB_SUCCESS; }
static HB_ERRCODE pgsqlGetValue( SQLBASEAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem ) { SDDDATA * pSDDData = ( SDDDATA * ) pArea->pSDDData; LPFIELD pField; char * pValue; HB_BOOL bError; PHB_ITEM pError; HB_SIZE ulLen; bError = HB_FALSE; uiIndex--; pField = pArea->area.lpFields + uiIndex; if( PQgetisnull( pSDDData->pResult, pArea->ulRecNo - 1, uiIndex ) ) return HB_SUCCESS; pValue = PQgetvalue( pSDDData->pResult, pArea->ulRecNo - 1, uiIndex ); ulLen = ( HB_SIZE ) PQgetlength( pSDDData->pResult, pArea->ulRecNo - 1, uiIndex ); /* printf( "fieldget recno:%d index:%d value:%s len:%d\n", pArea->ulRecNo, uiIndex, pValue, ulLen ); */ switch( pField->uiType ) { case HB_FT_STRING: hb_itemPutCL( pItem, pValue, ulLen ); break; case HB_FT_MEMO: hb_itemPutCL( pItem, pValue, ulLen ); hb_itemSetCMemo( pItem ); break; case HB_FT_INTEGER: case HB_FT_LONG: case HB_FT_DOUBLE: if( pField->uiDec ) hb_itemPutNDLen( pItem, atof( pValue ), ( int ) pField->uiLen - ( ( int ) pField->uiDec + 1 ), ( int ) pField->uiDec ); else if( pField->uiLen > 9 ) hb_itemPutNDLen( pItem, atof( pValue ), ( int ) pField->uiLen, ( int ) pField->uiDec ); else hb_itemPutNLLen( pItem, atol( pValue ), ( int ) pField->uiLen ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, pValue[ 0 ] == 'T' || pValue[ 0 ] == 'Y' ); break; case HB_FT_DATE: { char szDate[ 9 ]; szDate[ 0 ] = pValue[ 0 ]; szDate[ 1 ] = pValue[ 1 ]; szDate[ 2 ] = pValue[ 2 ]; szDate[ 3 ] = pValue[ 3 ]; szDate[ 4 ] = pValue[ 5 ]; szDate[ 5 ] = pValue[ 6 ]; szDate[ 6 ] = pValue[ 8 ]; szDate[ 7 ] = pValue[ 9 ]; szDate[ 8 ] = '\0'; hb_itemPutDS( pItem, szDate ); break; } default: bError = HB_TRUE; break; } if( bError ) { pError = hb_errNew(); hb_errPutGenCode( pError, EG_DATATYPE ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_DATATYPE ) ); hb_errPutSubCode( pError, EDBF_DATATYPE ); SELF_ERROR( ( AREAP ) pArea, pError ); hb_itemRelease( pError ); return HB_FAILURE; } return HB_SUCCESS; }
static HB_ERRCODE mysqlGetValue( SQLBASEAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem ) { SDDDATA * pSDDData = ( SDDDATA * ) pArea->pSDDData; LPFIELD pField; char * pValue; char szBuffer[ 64 ]; HB_BOOL bError; PHB_ITEM pError; HB_SIZE ulLen; bError = HB_FALSE; uiIndex--; pField = pArea->area.lpFields + uiIndex; pValue = pSDDData->pNatRecord[ uiIndex ]; ulLen = pSDDData->pNatLength[ uiIndex ]; /* NULL => NIL (?) */ if( ! pValue ) { hb_itemClear( pItem ); return HB_SUCCESS; } switch( pField->uiType ) { case HB_FT_STRING: { #if 0 char * pStr; /* Expand strings to field length */ pStr = ( char * ) hb_xgrab( pField->uiLen + 1 ); if( pValue ) memcpy( pStr, pValue, ulLen ); if( ( HB_SIZE ) pField->uiLen > ulLen ) memset( pStr + ulLen, ' ', pField->uiLen - ulLen ); pStr[ pField->uiLen ] = '\0'; hb_itemPutCRaw( pItem, pStr, pField->uiLen ); #else /* Do not expand strings */ if( pValue ) hb_itemPutCL( pItem, pValue, ulLen ); else hb_itemPutC( pItem, NULL ); #endif break; } case HB_FT_MEMO: if( pValue ) hb_itemPutCL( pItem, pValue, ulLen ); else hb_itemPutC( pItem, NULL ); hb_itemSetCMemo( pItem ); break; case HB_FT_INTEGER: case HB_FT_LONG: case HB_FT_DOUBLE: if( pValue ) { hb_strncpy( szBuffer, pValue, sizeof( szBuffer ) - 1 ); if( pField->uiDec ) { hb_itemPutNDLen( pItem, atof( szBuffer ), ( int ) pField->uiLen - ( ( int ) pField->uiDec + 1 ), ( int ) pField->uiDec ); } else hb_itemPutNLLen( pItem, atol( szBuffer ), ( int ) pField->uiLen ); } else { if( pField->uiDec ) hb_itemPutNDLen( pItem, 0.0, ( int ) pField->uiLen - ( ( int ) pField->uiDec + 1 ), ( int ) pField->uiDec ); else hb_itemPutNLLen( pItem, 0, ( int ) pField->uiLen ); } break; case HB_FT_DATE: { char szDate[ 9 ]; szDate[ 0 ] = pValue[ 0 ]; szDate[ 1 ] = pValue[ 1 ]; szDate[ 2 ] = pValue[ 2 ]; szDate[ 3 ] = pValue[ 3 ]; szDate[ 4 ] = pValue[ 5 ]; szDate[ 5 ] = pValue[ 6 ]; szDate[ 6 ] = pValue[ 8 ]; szDate[ 7 ] = pValue[ 9 ]; szDate[ 8 ] = '\0'; hb_itemPutDS( pItem, szDate ); break; } case HB_FT_TIMESTAMP: { char szTimeStamp[ 15 ]; szTimeStamp[ 0 ] = pValue[ 0 ]; szTimeStamp[ 1 ] = pValue[ 1 ]; szTimeStamp[ 2 ] = pValue[ 2 ]; szTimeStamp[ 3 ] = pValue[ 3 ]; szTimeStamp[ 4 ] = pValue[ 5 ]; szTimeStamp[ 5 ] = pValue[ 6 ]; szTimeStamp[ 6 ] = pValue[ 8 ]; szTimeStamp[ 7 ] = pValue[ 9 ]; szTimeStamp[ 8 ] = pValue[ 11 ]; szTimeStamp[ 9 ] = pValue[ 12 ]; szTimeStamp[ 10 ] = pValue[ 14 ]; szTimeStamp[ 11 ] = pValue[ 15 ]; szTimeStamp[ 12 ] = pValue[ 17 ]; szTimeStamp[ 13 ] = pValue[ 18 ]; szTimeStamp[ 14 ] = '\0'; hb_itemPutTS( pItem, szTimeStamp ); break; } case HB_FT_TIME: { char szTimeStamp[ 15 ]; szTimeStamp[ 0 ] = '0'; szTimeStamp[ 1 ] = '0'; szTimeStamp[ 2 ] = '0'; szTimeStamp[ 3 ] = '0'; szTimeStamp[ 4 ] = '0'; szTimeStamp[ 5 ] = '0'; szTimeStamp[ 6 ] = '0'; szTimeStamp[ 7 ] = '0'; szTimeStamp[ 8 ] = pValue[ 0 ]; szTimeStamp[ 9 ] = pValue[ 1 ]; szTimeStamp[ 10 ] = pValue[ 3 ]; szTimeStamp[ 11 ] = pValue[ 4 ]; szTimeStamp[ 12 ] = pValue[ 6 ]; szTimeStamp[ 13 ] = pValue[ 7 ]; szTimeStamp[ 14 ] = '\0'; hb_itemPutTS( pItem, szTimeStamp ); break; } default: bError = HB_TRUE; break; } if( bError ) { pError = hb_errNew(); hb_errPutGenCode( pError, EG_DATATYPE ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_DATATYPE ) ); hb_errPutSubCode( pError, EDBF_DATATYPE ); SELF_ERROR( ( AREAP ) pArea, pError ); hb_itemRelease( pError ); return HB_FAILURE; } return HB_SUCCESS; }