/************************************************************************
* 函数: init_sqlda()
* 作用: 为SQLDA申请空间
* 返回值: 0 正确,否则有错误
************************************************************************/
int init_sqlda(in_da, print)
struct sqlda *in_da;
int print;
{
int i, j, row_size=0, msglen=0, num_to_alloc;
struct sqlvar_struct *col_ptr;
loc_t *temp_loc;
char *type;
if (print)
printf("columns: %d. ", in_da->sqld);
/* Step 1: 获得一行数据的长度 */
for (i = 0, col_ptr = in_da->sqlvar; i < in_da->sqld; i++, col_ptr++)
{
/* msglen变量存放查询数据的所有列的长度和。*/
msglen += col_ptr->sqllen; /* get database sizes */
/* 为col_ptr->sqllen 重新赋值,该值是在C下的大小。如:在数据库中的字符串,在C中应该多一个字节空间来存放NULL的结束符。*/
col_ptr->sqllen = rtypmsize(col_ptr->sqltype, col_ptr->sqllen);
/*row_size变量存放了在C程序中的所有列的长度和。这个值是应用程序为存放一行数据所需要申请的内存空间*/
row_size += col_ptr->sqllen;
}
if (print) printf("Total row size = %d\n", row_size);
/* Step 2: 设置FetArrSize值*/
if (FetArrSize == -1) /* if FetArrSize not yet initialized */
{
if (FetBufSize == 0) /* if FetBufSize not set */
FetBufSize = 4096; /* default FetBufSize */
FetArrSize = FetBufSize/msglen;
}
num_to_alloc = (FetArrSize == 0)? 1: FetArrSize;
/* 设置sqlvar_struct结构中的数据类型为相应的C的数据类型*/
for (i = 0, col_ptr = in_da->sqlvar; i < in_da->sqld; i++, col_ptr++)
{
switch(col_ptr->sqltype)
{
case SQLCHAR:
type = "char ";
col_ptr->sqltype = CCHARTYPE;
break;
case SQLINT:
type = "int ";
col_ptr->sqltype = CINTTYPE;
break;
case SQLBYTES:
case SQLTEXT:
if (col_ptr->sqltype == SQLBYTES)
type = "blob ";
else
type = "text ";
col_ptr->sqltype = CLOCATORTYPE;
/* Step 3 :只有数据类型为TEXT 和BLOB时,才执行。
为存放TEXT 或BYTE列数据申请空间*/
temp_loc = (loc_t *)malloc(col_ptr->sqllen * num_to_alloc);
if (!temp_loc)
{
fprintf(stderr, "blob sqldata malloc failed\n");
return(-1);
}
col_ptr->sqldata = (char *)temp_loc;
/* Step 4:只有数据类型为TEXT 和BLOB时才执行。初试化loc_t结构*/
byfill(temp_loc, col_ptr->sqllen*num_to_alloc ,0);
for (j = 0; j< num_to_alloc; j++, temp_loc++)
{
temp_loc->loc_loctype = LOCMEMORY;
temp_loc->loc_bufsize = BLOBSIZE;
temp_loc->loc_buffer = (char *)malloc(BLOBSIZE);
if (!temp_loc->loc_buffer)
{
fprintf(stderr, "loc_buffer malloc failed\n");
return(-1);
}
temp_loc->loc_oflags = 0; /* clear flag */
} /* end for */
break;
default: /* 其他数据类型*/
fprintf(stderr, "not yet handled(%d)!\n", col_ptr->sqltype);
return(-1);
} /* switch */
/* Step 5: 为指示符变量申请空间*/
col_ptr->sqlind = (short *) malloc(sizeof(short) * num_to_alloc);
if (!col_ptr->sqlind)
{
printf("indicator malloc failed\n");
return -1;
}
/* Step 6 :为存放 非 TEXT 和BLOB的数据类型的sqldata申请空间.注意的是,申请的地址是(char *),在输出数据时,要按照相应的数据类型做转换。*/
if (col_ptr->sqltype != CLOCATORTYPE)
{
col_ptr->sqldata = (char *) malloc(col_ptr->sqllen * num_to_alloc);
if (!col_ptr->sqldata)
{
printf("sqldata malloc failed\n");
return -1;
}
}
if (print)
printf("column %3d, type = %s(%3d), len=%d\n", i+1, type,
col_ptr->sqltype, col_ptr->sqllen);
} /* end for */
return msglen;
}