00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "ocilib_internal.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 boolean OCI_TypeInfoClose(OCI_TypeInfo *typinf)
00046 {
00047 ub2 i;
00048
00049 OCI_CHECK(typinf == NULL, FALSE);
00050
00051 for (i=0; i < typinf->nb_cols; i++)
00052 {
00053 OCI_FREE(typinf->cols[i].name);
00054 }
00055
00056 OCI_FREE(typinf->cols);
00057 OCI_FREE(typinf->name);
00058 OCI_FREE(typinf->schema);
00059
00060 return TRUE;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 OCI_TypeInfo * OCI_API OCI_TypeInfoGet(OCI_Connection *con, const mtext *name,
00072 unsigned int type)
00073 {
00074 OCI_TypeInfo *typinf = NULL;
00075 OCI_Item *item = NULL;
00076 OCIDescribe *dschp = NULL;
00077 OCIParam *parmh1 = NULL;
00078 OCIParam *parmh2 = NULL;
00079 mtext *str = NULL;
00080 int etype = OCI_DESC_COLUMN;
00081 int ptype = 0;
00082 ub1 item_type = 0;
00083 ub4 attr_type = 0;
00084 ub4 num_type = 0;
00085 boolean res = TRUE;
00086 boolean found = FALSE;
00087 ub2 i;
00088
00089 mtext obj_schema[OCI_SIZE_OBJ_NAME+1];
00090 mtext obj_name[OCI_SIZE_OBJ_NAME+1];
00091
00092 OCI_CHECK_INITIALIZED(NULL);
00093
00094 OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00095 OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
00096
00097 if (type == OCI_TIF_TABLE)
00098 item_type = OCI_PTYPE_TABLE;
00099 else if (type == OCI_TIF_VIEW)
00100 item_type = OCI_PTYPE_VIEW;
00101 else if (type == OCI_TIF_TYPE)
00102 item_type = OCI_PTYPE_TYPE;
00103 else
00104 return NULL;
00105
00106 obj_schema[0] = 0;
00107 obj_name[0] = 0;
00108
00109
00110
00111 for (str = (mtext *) name; *str != 0; str++)
00112 {
00113 if (*str == MT('.'))
00114 {
00115 mtsncat(obj_schema, name, str-name);
00116 mtsncat(obj_name, ++str, OCI_SIZE_OBJ_NAME);
00117 break;
00118 }
00119 }
00120
00121
00122
00123 if (obj_name[0] == 0)
00124 {
00125 mtsncat(obj_name, name, OCI_SIZE_OBJ_NAME);
00126 }
00127
00128
00129
00130 for (str = obj_name; *str != 0; str++)
00131 *str = (mtext) mttoupper(*str);
00132
00133
00134
00135 for (str = obj_schema; *str != 0; str++)
00136 *str = (mtext) mttoupper(*str);
00137
00138
00139
00140 item = con->tinfs->head;
00141
00142
00143
00144 while (item != NULL)
00145 {
00146 typinf = (OCI_TypeInfo *) item->data;
00147
00148 if ((typinf != NULL) && (typinf->type == type))
00149 {
00150 if ((mtscasecmp(typinf->name, obj_name ) == 0) &&
00151 (mtscasecmp(typinf->schema, obj_schema) == 0))
00152 {
00153 found = TRUE;
00154 break;
00155 }
00156 }
00157
00158 item = item->next;
00159 }
00160
00161
00162
00163 if (found == FALSE)
00164 {
00165 item = OCI_ListAppend(con->tinfs, sizeof(OCI_TypeInfo));
00166
00167 res = (item != NULL);
00168
00169 if (res == TRUE)
00170 {
00171 typinf = (OCI_TypeInfo *) item->data;
00172
00173 typinf->type = type;
00174 typinf->con = con;
00175 typinf->name = mtsdup(obj_name);
00176 typinf->schema = mtsdup(obj_schema);
00177
00178 res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env,
00179 (dvoid **) (void *) &dschp,
00180 OCI_HTYPE_DESCRIBE, 0,
00181 (dvoid **) NULL));
00182 }
00183
00184 if (res == TRUE)
00185 {
00186 if (type == OCI_TIF_TYPE)
00187 {
00188 void *ostr1 = NULL;
00189 void *ostr2 = NULL;
00190 int osize1 = -1;
00191 int osize2 = -1;
00192
00193 attr_type = OCI_ATTR_LIST_TYPE_ATTRS;
00194 num_type = OCI_ATTR_NUM_TYPE_ATTRS;
00195 ptype = OCI_DESC_TYPE;
00196
00197 ostr1 = OCI_GetInputMetaString(typinf->schema, &osize1);
00198 ostr2 = OCI_GetInputMetaString(typinf->name, &osize2);
00199
00200 OCI_CALL2
00201 (
00202 res, con,
00203
00204 OCITypeByName(OCILib.env, con->err, con->cxt,
00205 (text *) ostr1, (ub4) osize1,
00206 (text *) ostr2, (ub4) osize2,
00207 (text *) NULL, (ub4) 0,
00208 OCI_DURATION_SESSION, OCI_TYPEGET_ALL,
00209 &typinf->tdo)
00210 )
00211
00212 OCI_CALL2
00213 (
00214 res, con,
00215
00216 OCIDescribeAny(con->cxt, con->err, (void *) typinf->tdo,
00217 0, OCI_OTYPE_PTR, OCI_DEFAULT,
00218 OCI_PTYPE_TYPE, dschp)
00219 )
00220
00221 OCI_ReleaseMetaString(ostr1);
00222 OCI_ReleaseMetaString(ostr2);
00223 }
00224 else
00225 {
00226 mtext buffer[(OCI_SIZE_OBJ_NAME*2) + 2];
00227
00228 size_t size = sizeof(buffer)/sizeof(mtext);
00229 void *ostr1 = NULL;
00230 int osize1 = -1;
00231
00232 attr_type = OCI_ATTR_LIST_COLUMNS;
00233 num_type = OCI_ATTR_NUM_COLS;
00234 ptype = OCI_DESC_TABLE;
00235 str = buffer;
00236
00237 str[0] = 0;
00238
00239 if ((typinf->schema != NULL) && (typinf->schema[0] != 0))
00240 {
00241 str = mtsncat(buffer, typinf->schema, size);
00242 size -= mtslen(typinf->schema);
00243 str = mtsncat(str, MT("."), size);
00244 size -= 1;
00245 }
00246
00247 mtsncat(str, typinf->name, size);
00248
00249 ostr1 = OCI_GetInputMetaString(str, &osize1);
00250
00251 OCI_CALL2
00252 (
00253 res, con,
00254
00255 OCIDescribeAny(con->cxt, con->err, (dvoid *) ostr1,
00256 (ub4) osize1, OCI_OTYPE_NAME,
00257 OCI_DEFAULT, item_type, dschp)
00258 )
00259
00260 OCI_ReleaseMetaString(ostr1);
00261 }
00262
00263 OCI_CALL2
00264 (
00265 res, con,
00266
00267 OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh1,
00268 NULL, OCI_ATTR_PARAM, con->err)
00269 )
00270
00271
00272
00273 if (type == OCI_TIF_TYPE)
00274 {
00275 OCI_CALL2
00276 (
00277 res, con,
00278
00279 OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->tcode,
00280 NULL, OCI_ATTR_TYPECODE, con->err)
00281 )
00282
00283 }
00284
00285 if (typinf->tcode == SQLT_NCO)
00286 {
00287 typinf->nb_cols = 1;
00288
00289 ptype = OCI_DESC_COLLECTION;
00290 etype = OCI_DESC_TYPE;
00291 parmh2 = parmh1;
00292
00293 OCI_CALL2
00294 (
00295 res, con,
00296
00297 OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->ccode,
00298 NULL, OCI_ATTR_COLLECTION_TYPECODE, con->err)
00299 )
00300 }
00301 else
00302 {
00303 OCI_CALL2
00304 (
00305 res, con,
00306
00307 OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &parmh2,
00308 NULL, attr_type, con->err)
00309 )
00310
00311 OCI_CALL2
00312 (
00313 res, con,
00314
00315 OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->nb_cols,
00316 NULL, num_type, con->err)
00317 )
00318 }
00319
00320
00321
00322 if (typinf->nb_cols > 0)
00323 {
00324 typinf->cols = (OCI_Column *) OCI_MemAlloc(OCI_IPC_COLUMN,
00325 sizeof(*typinf->cols),
00326 typinf->nb_cols,
00327 TRUE);
00328
00329
00330
00331 if (typinf->cols != NULL)
00332 {
00333 for (i = 0; i < typinf->nb_cols; i++)
00334 {
00335 res = res && OCI_ColumnDescribe(&typinf->cols[i], con,
00336 NULL, parmh2, i + 1, ptype);
00337
00338 res = res && OCI_ColumnMap(&typinf->cols[i], NULL);
00339
00340 if (res == FALSE)
00341 break;
00342 }
00343 }
00344 else
00345 res = FALSE;
00346 }
00347
00348
00349
00350 if (dschp != NULL)
00351 OCI_HandleFree(dschp, OCI_HTYPE_DESCRIBE);
00352 }
00353 }
00354
00355
00356
00357 if (res == FALSE)
00358 {
00359 OCI_TypeInfoFree(typinf);
00360 typinf = NULL;
00361 }
00362
00363 OCI_RESULT(res);
00364
00365
00366
00367 if (typinf != NULL)
00368 typinf->refcount++;
00369
00370 return typinf;
00371 }
00372
00373
00374
00375
00376
00377 boolean OCI_API OCI_TypeInfoFree(OCI_TypeInfo *typinf)
00378 {
00379 boolean res = TRUE;
00380
00381 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
00382
00383 typinf->refcount--;
00384
00385 if (typinf->refcount == 0)
00386 {
00387 OCI_ListRemove(typinf->con->tinfs, typinf);
00388
00389 res = OCI_TypeInfoClose(typinf);
00390
00391 OCI_FREE(typinf);
00392 }
00393
00394 OCI_RESULT(res);
00395
00396 return res;
00397 }
00398
00399
00400
00401
00402
00403 unsigned int OCI_API OCI_TypeInfoGetType(OCI_TypeInfo *typinf)
00404 {
00405 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, OCI_UNKNOWN);
00406
00407 OCI_RESULT(TRUE);
00408
00409 return typinf->type;
00410 }
00411
00412
00413
00414
00415
00416 unsigned int OCI_API OCI_TypeInfoGetColumnCount(OCI_TypeInfo *typinf)
00417 {
00418 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, 0);
00419
00420 OCI_RESULT(TRUE);
00421
00422 return typinf->nb_cols;
00423 }
00424
00425
00426
00427
00428
00429 OCI_Column * OCI_API OCI_TypeInfoGetColumn(OCI_TypeInfo *typinf, unsigned int index)
00430 {
00431 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00432 OCI_CHECK_BOUND(typinf->con, index, 1, typinf->nb_cols, NULL);
00433
00434 OCI_RESULT(TRUE);
00435
00436 return &(typinf->cols[index-1]);
00437 }
00438
00439
00440
00441
00442
00443 const mtext * OCI_API OCI_TypeInfoGetName(OCI_TypeInfo *typinf)
00444 {
00445 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00446
00447 OCI_RESULT(TRUE);
00448
00449 return typinf->name;
00450 }