Приложение 5. Пример разбора спецификации выборки данных
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "decimals.h"
#include "inter.h"
#include "tick.h"
#ifdef WIN32
#include <float.h>
#define isnan(f) _isnan(f)
#define isinf(f) (!_finite(f))
#endif
#include "exlib.h"
void PrintError(TCBL*pCBL);
void PrintResult(L_BYTE*Buf, L_BYTE*VarBuf);
void Print_value(L_CHAR*text, P_TYPE Type, L_BYTE*Buf);
char Query_Create_Table[]="create or replace table TEST (C1 char(10),"
"C2 int,C3 real,C4 date,C5 decimal,C6 byte(10),C7 smallint,C8 double,"
"C9 bigint,C10 varchar(10),C11 varbyte(10),C12 boolean,C13 nchar(10),"
"C14 nchar varying(10), C15 BLOB, C16 extfile);";
char Query_Create_TabNan[]="create or replace table TESTnan ("
"C1 int,C2 real,C3 double);";
char Query_Insert_Table1[]="insert into test values ('azzabyybcc',12,-12.345670,"
"to_date('1998-12-01','YYYY-MM-DD'), 12.34,"
"hex('FFFEFDFCFBFAF9F8F7F6'),30000,30.01,182834584,"
"'azzabyybcc',hex('FFFEFDFCFBFAF9F8F7F6'),"
"true,n'абвгдеж',n'abcdefg', NULL, extfile('1.txt'));";
char Query_Insert_Table[]="insert into test values "
"(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL);";
char Query_InsNaN_Table[]="insert into test(c3,c8) "
"values ( cast HEXTORAW('0000807F00000000') as real,"
"cast HEXTORAW('000000000000F07F0000000000000000') as double);";
char Query_InsNaN1_Table[]="insert into test(c3,c8) "
"values ( cast HEXTORAW('000080FF00000000') as real,"
"cast HEXTORAW('000000000000F0FF0000000000000000') as DOUBLE);";
char Query_InsNaN2_Table[]="insert into test(c3,c8) "
"values ( cast HEXTORAW('0000C0FF00000000') as real,"
"cast HEXTORAW('000000000000F8FF0000000000000000') as DOUBLE);";
void PrintResult(L_BYTE*Buf,L_BYTE*VarBuf)
{
L_WORD *pCntArg;
P_TYPE Type;
L_WORD i;
L_CHAR str[100];
L_BYTE *ptr;
L_BYTE *ptr1;
L_BYTE *ptr2;
pCntArg = (L_WORD *) Buf;
ptr1 = Buf+sizeof(L_WORD);
ptr = ptr1+*pCntArg*sizeof(P_TYPE);
VarBuf += 2*sizeof(WORD);
for (i = 0; i < *pCntArg; ++i)
{
if ((L_WORD)VarBuf[i])
sprintf(str, "field %d:<NULL>\n", i + 1);
else
sprintf(str, "field %d:\n", i + 1);
Type = *(P_TYPE*)ptr1;
ptr2 = ptr;
if ( Type.ntyp == DT_VARCHAR ||
Type.ntyp == DT_VARBYTE ||
Type.ntyp == DT_NVARCHAR )
ptr2 += 2;
Print_value(str, Type, ptr2);
ptr += Type.length;
if ( Type.ntyp == DT_VARCHAR ||
Type.ntyp == DT_VARBYTE ||
Type.ntyp == DT_NVARCHAR )
ptr += 2;
ptr1 += sizeof(P_TYPE);
}
}
void Print_value(L_CHAR*text, P_TYPE Type, L_BYTE*ptr)
{
L_WORD i;
L_CHAR StrBuf[4000];
L_WORD SmallBuf;
L_LONG IntBuf;
L_REAL RealBuf;
L_DOUBLE DblBuf;
L_DECIMAL DecBuf;
L_DOUBLE NumBuf;
printf(text);
printf("typ = %d, len = %d ", (L_WORD)Type.ntyp, (L_WORD)Type.length);
switch (Type.ntyp)
{
case DT_CHAR:
case DT_VARCHAR:
memcpy(StrBuf, ptr, Type.length);
StrBuf[Type.length] = 0;
printf("value = '%s'",StrBuf);
break;
case DT_INTEGER:
if (Type.length == sizeof(L_WORD))
{
memcpy(&SmallBuf, ptr, sizeof(L_WORD));
printf("value = %d", SmallBuf);
}
else
{
memcpy(&IntBuf, ptr, sizeof(L_LONG));
printf("value = %ld", IntBuf);
}
break;
case DT_REAL:
if (Type.length == sizeof(L_REAL))
{
memcpy(&RealBuf, ptr, sizeof(L_REAL));
if (isnan(RealBuf))
printf("value = %4s", RealBuf > 0 ? "nan" : "-nan");
else
if (isinf(RealBuf))
printf("value = %4s", RealBuf > 0 ? "inf" : "-inf");
else
printf("value = %g", RealBuf);
}
else
{
memcpy(&DblBuf, ptr, sizeof(L_DOUBLE));
if (isnan(DblBuf))
printf("value = %4s", DblBuf > 0 ? "nan" : "-nan");
else
if (isinf(DblBuf))
printf("value = %4s", DblBuf > 0 ? "inf" : "-inf");
else
printf("value = %g", DblBuf);
}
break;
case DT_DATE:
memcpy(DecBuf, ptr, sizeof(L_DECIMAL));
TICKTOSTRF(DecBuf, "value = dd.mm.yyyy:hh:mi:ss", StrBuf);
printf(StrBuf);
break;
case DT_DECIMAL:
memcpy(DecBuf, ptr, sizeof(L_DECIMAL));
DecToDbl(DecBuf, &NumBuf);
printf("value = %g", NumBuf);
break;
case DT_BYTE:
case DT_VARBYTE:
case DT_NCHAR:
case DT_NVARCHAR:
printf("value = ' ");
for (i = 0; i < Type.length; ++i)
printf("%2x ", (L_WORD) ptr[i]);
printf(" ' ");
break;
case DT_BLOB:
printf("@:BLOB:@");
break;
case DT_EXTFILE:
printf("@:EXTFILE:@");
break;
case DT_BOOL:
{
byte qqq = 0;
memcpy(&qqq, ptr, 1);
if (qqq)
printf("value = <TRUE> ");
else
printf("value = <FALSE> ");
}
break;
}
printf("\n");
}
void main()
{
TCBL CBLconnect;
L_CHAR Name_Pass[] = "SYSTEM/MANAGER8";
L_CHAR Node[] = " ";
L_WORD Priority = 0;
L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_SPEC;
L_LONG Err;
L_CHAR Query[] = "select * from test;";
L_CHAR QueryNaN[] = "select c3,c8 from test where c3 is nan or c8 is nan;";
L_BYTE Buf[4096];
L_BYTE VarBuf[20];
Err=LinterOPEN(&CBLconnect, Name_Pass, Node,Priority, PrzExe);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("Connect to RDBMS Linter\n");
Err= LinterNotSelect(&CBLconnect, Query_Create_Table);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err= LinterNotSelect(&CBLconnect, Query_Insert_Table);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err= LinterNotSelect(&CBLconnect, Query_Insert_Table1);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err=LinterSLCT(&CBLconnect, PrzExe, Query, Buf,sizeof(Buf), VarBuf);
if (Err != NORMAL)
PrintError(&CBLconnect);
else
{
printf("First Selected Row:\n");
PrintResult(Buf,VarBuf);
}
Err=LinterGETL(&CBLconnect, Buf,sizeof(Buf), VarBuf);
if (Err != NORMAL)
PrintError(&CBLconnect);
else
{
printf("\nLast Selected Row:\n");
PrintResult(Buf,VarBuf);
}
Err= LinterNotSelect(&CBLconnect, Query_InsNaN_Table);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err= LinterNotSelect(&CBLconnect, Query_InsNaN1_Table);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err= LinterNotSelect(&CBLconnect, Query_InsNaN2_Table);
if (Err != NORMAL)
PrintError(&CBLconnect);
Err=LinterSLCT(&CBLconnect, PrzExe, QueryNaN, Buf,sizeof(Buf), VarBuf);
if (Err != NORMAL)
PrintError(&CBLconnect);
else
{
printf("\nFirst Selected NaN values:\n");
PrintResult(Buf,VarBuf);
}
Err=LinterGETN(&CBLconnect, Buf,sizeof(Buf), VarBuf);
if (Err != NORMAL)
PrintError(&CBLconnect);
else
{
printf("Next Selected NaN values:\n");
PrintResult(Buf,VarBuf);
}
Err=LinterGETL(&CBLconnect, Buf,sizeof(Buf), VarBuf);
if (Err != NORMAL)
PrintError(&CBLconnect);
else
{
printf("Last Selected NaN values:\n");
PrintResult(Buf,VarBuf);
}
printf("End Example\n");
}
Результаты выполнения примера.
Connect to RDBMS Linter First Selected Row: field 1:<NULL> typ = 1, len = 10 value = ' ' field 2:<NULL> typ = 2, len = 4 value = 0 field 3:<NULL> typ = 3, len = 4 value = 0 field 4:<NULL> typ = 4, len = 16 VALUE = 00.00.0000:00:00:00 field 5:<NULL> typ = 5, len = 16 value = 0 field 6:<NULL> typ = 6, len = 10 value = ' 0 0 0 0 0 0 0 0 0 0 ' field 7:<NULL> typ = 2, len = 2 value = 0 field 8:<NULL> typ = 3, len = 8 value = 0 field 9:<NULL> typ = 2, len = 8 value = 0 field 10:<NULL> typ = 8, len = 10 value = '' field 11:<NULL> typ = 9, len = 10 value = ' 0 0 0 0 0 0 0 0 0 0 ' field 12:<NULL> typ = 10, len = 1 value = <FALSE> field 13:<NULL> typ = 11, len = 20 value = ' 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 ' field 14:<NULL> typ = 12, len = 20 value = ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' field 15: typ = 7, len = 24 @:BLOB:@ field 16:<NULL> typ = 13, len = 522 @:EXTFILE:@ Last Selected Row: field 1: typ = 1, len = 10 value = 'azzabyybcc' field 2: typ = 2, len = 4 value = 12 field 3: typ = 3, len = 4 value = -12.3457 field 4: typ = 4, len = 16 VALUE = 01.12.1998:00:00:00 field 5: typ = 5, len = 16 value = 12.34 field 6: typ = 6, len = 10 value = ' ff fe fd fc fb fa f9 f8 f7 f6 ' field 7: typ = 2, len = 2 value = 30000 field 8: typ = 3, len = 8 value = 30.01 field 9: typ = 2, len = 8 value = 182834584 field 10: typ = 8, len = 10 value = 'azzabyybcc' field 11: typ = 9, len = 10 value = ' ff fe fd fc fb fa f9 f8 f7 f6 ' field 12: typ = 10, len = 1 value = <TRUE> field 13: typ = 11, len = 20 value = ' 30 4 31 4 32 4 33 4 34 4 35 4 36 4 20 0 20 0 20 0 ' field 14: typ = 12, len = 20 value = ' 61 0 62 0 63 0 64 0 65 0 66 0 67 0 0 0 0 0 0 0 ' field 15: typ = 7, len = 24 @:BLOB:@ field 16: typ = 13, len = 522 @:EXTFILE:@ First Selected NaN values: field 1: typ = 3, len = 4 value = inf field 2: typ = 3, len = 8 value = inf Next Selected NaN values: field 1: typ = 3, len = 4 value = -inf field 2: typ = 3, len = 8 value = -inf Last Selected NaN values: field 1: typ = 3, len = 4 value = -nan field 2: typ = 3, len = 8 value = -nan End Example