#include < stdio.h >
#include < stdlib.h >
#include "decimals.h"
#include "inter.h"
#include "tick.h"
#include "exlib.h"
extern L_BYTE* MakeCHARValue(int, int, L_BYTE*); // Генерирует значение
#define MAX_BUF_LEN 2048
L_BYTE *fillCharBuffer(L_WORD Len, L_WORD typ, L_BYTE *outAdr, L_WORD *outSize)
{
L_WORD curLen = Len;
L_BYTE curValue[64] = {0}; // Буфер под самое длинное значение
L_BYTE *pcurValue = MakeCHARValue(typ, Len, curValue);
if (pcurValue == NULL) // Указывает, что это NULL-значение
{
curLen = -1; // При NULL-значении пишем только длину, равную -1
memcpy(outAdr, &curLen, sizeof(curLen));
outAdr += sizeof(curLen);
*outSize += sizeof(curLen);
return outAdr;
}
if (typ == DT_VARCHAR || typ == DT_VARBYTE || typ == DT_NVARCHAR)
{
if (typ == DT_NVARCHAR)
curLen = wcslen((wchar_t *)pcurValue) * sizeof(wchar_t);
else
curLen = strlen((const char*)pcurValue);
}
if (typ == DT_REAL || typ == DT_DECIMAL || typ == DT_DATE ||
typ == DT_BOOL || typ == DT_EXTFILE)
curLen = strlen((const char*)pcurValue);
memcpy(outAdr, &curLen, sizeof(curLen));
outAdr += sizeof(curLen);
*outSize += sizeof(curLen);
memcpy(outAdr, pcurValue, curLen);
outAdr += curLen;
*outSize += curLen;
return outAdr;
} // fillCharBuffer
int main()
{
TCBL CBLconnect = {0};
L_CHAR Name_Pass[] = "SYSTEM/MANAGER8";
L_CHAR Node[] = " ";
L_WORD Priority = 0;
L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_BINARY;
L_LONG Err = NORMAL;
L_CHAR Query[] = "select * from test;";
L_LONG i;
L_WORD curSize = sizeof(L_WORD);
L_BYTE Buf[MAX_BUF_LEN];
L_WORD recCnt = 2; // Число записей в одной порции пакета
L_WORD ColumnCount; // Число столбцов в выборке данных
GETA_OUT* ansDesc = NULL; // Описатель столбцов выборки данных
L_BYTE PackBuf[MAX_BUF_LEN] = {0}; // Буфер для размещения добавляемой порции пакета
L_BYTE *CurAdr = PackBuf + sizeof(recCnt);
*((L_WORD *)PackBuf) = recCnt; // Первым пишем число записей в порции пакета
Err = LinterOPEN(&CBLconnect, Name_Pass, Node, Priority, PrzExe);
if (Err != NORMAL)
PrintError(&CBLconnect); /* Если ошибка, то всегда exit(1)! */
printf("Connect to RDBMS Linter\n");
// Создадим таблицу с использованием всех типов данных СУБД ЛИНТЕР:
Err = LinterNotSelect(
&CBLconnect,
"create or replace table TEST(INT_COLUMN int,"
"SMALLINT_COLUMN smallint,"
"BIGINT_COLUMN bigint,"
"CHAR_COLUMN char(5),"
"VARCHAR_COLUMN varchar(10),"
"BYTE_COLUMN byte(4),"
"VARBYTE_COLUMN varbyte(5),"
"NCHAR_COLUMN nchar(5),"
"NCHAR_VARYING_COLUMN nchar varying(10),"
"DATE_COLUMN date,"
"REAL_COLUMN real,"
"DOUBLE_COLUMN Double,"
"DEC_COLUMN decimal,"
"BOOL_COLUMN boolean,"
"EXTFILE_COLUMN extfile);");
if (Err != NORMAL)
PrintError(&CBLconnect);
Err = LinterSLCT(&CBLconnect, PrzExe, Query, Buf, sizeof(Buf), NULL);
Err = LinterAnsColNum(&CBLconnect, &ColumnCount);
if (Err != NORMAL)
PrintError(&CBLconnect);
ansDesc = (GETA_OUT*)calloc(ColumnCount, sizeof(GETA_OUT));
if (ansDesc == NULL)
{
printf("Error: not memory\n"); exit(1);
}
// Получаем полные описания столбцов, но нам потребуется только тип и длина:
Err = LinterGETA(&CBLconnect, 0, ansDesc, ColumnCount*sizeof(GETA_OUT));
if (Err != NORMAL)
PrintError(&CBLconnect);
for (i = 0; i < ColumnCount; i++)
CurAdr = fillCharBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr, &curSize);
for (i = 0; i < ColumnCount; i++)
CurAdr = fillCharBuffer(ansDesc[i].Length, ansDesc[i].Type, CurAdr, &curSize);
printf("PUTM AS CHAR");
Err = LinterNotSelect(
&CBLconnect,
"start append into TEST char(INT_COLUMN, SMALLINT_COLUMN, BIGINT_COLUMN, "
"CHAR_COLUMN, VARCHAR_COLUMN, "
"BYTE_COLUMN, VARBYTE_COLUMN, "
"NCHAR_COLUMN, NCHAR_VARYING_COLUMN, "
"DATE_COLUMN, "
"REAL_COLUMN, DOUBLE_COLUMN, DEC_COLUMN, "
"BOOL_COLUMN, "
"EXTFILE_COLUMN);");
if (Err != NORMAL)
PrintError(&CBLconnect);
Err = LinterPUTM(&CBLconnect, PackBuf, curSize);
if (Err != NORMAL)
PrintError(&CBLconnect);
if (LinterNotSelect(&CBLconnect, "end append into TEST;") != NORMAL)
PrintError(&CBLconnect);
printf(" - OK\n");
free(ansDesc);
Err = LinterCLOS(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
return 0;
} // Main