void OD_GET_COLUMN_ATTRIBUTES(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_LONGINT Param1;
	C_LONGINT Param2;
	C_LONGINT Param3;
	C_LONGINT Param4;
	
	Param1.fromParamAtIndex(pParams, 1);
	Param2.fromParamAtIndex(pParams, 2);
	
	uint32_t cursorId = Param1.getIntValue();
	uint32_t pos = Param2.getIntValue();
	
	ORACLE_SQL_CURSOR *cursor = _cursorGetAndParseAndCountColumns(cursorId, pos);
	
	OCIParam *param = 0;
	
	sword err = 0;
	
	if(cursor)
	{
		err = OCIParamGet(cursor->stmtp, OCI_HTYPE_STMT, cursor->errhp, (dvoid **)&param, pos);
		//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r26.htm
		
		if(!err)
		{
			ub2 dataType = 0;
			ub2 dataSize = 0;
			
			err = OCIAttrGet(param, OCI_DTYPE_PARAM, &dataType, 0, OCI_ATTR_DATA_TYPE, cursor->errhp);
			err = err|OCIAttrGet(param, OCI_DTYPE_PARAM, &dataSize, 0, OCI_ATTR_DATA_SIZE, cursor->errhp);
			//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r20.htm
			
			Param3.setIntValue(dataType);
			Param4.setIntValue(dataSize);	
			
			OCIDescriptorFree(param, OCI_DTYPE_PARAM);
			//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r23.htm
			
		}
		
		if(err)
			_errorInfoSet(0, cursor->errhp, cursor->sessionId, cursorId, false, PA_GetCurrentProcessNumber(), 0);	
		
	}
	
	Param3.toParamAtIndex(pParams, 3);
	Param4.toParamAtIndex(pParams, 4);	
}
void OD_Get_column_title(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_LONGINT Param1;
	C_LONGINT Param2;
	C_TEXT returnValue;
	
	Param1.fromParamAtIndex(pParams, 1);
	Param2.fromParamAtIndex(pParams, 2);
	
	uint32_t cursorId = Param1.getIntValue();
	uint32_t pos = Param2.getIntValue();
	
	ORACLE_SQL_CURSOR *cursor = _cursorGetAndParseAndCountColumns(cursorId, pos);
	
	OCIParam *param = 0;
	
	sword err = 0;
	
	if(cursor)
	{
		err = OCIParamGet(cursor->stmtp, OCI_HTYPE_STMT, cursor->errhp, (dvoid **)&param, pos);
		//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r26.htm
		
		if(!err)
		{
			text *col_name;
			ub4 col_name_len;
			
			err = OCIAttrGet(param, OCI_DTYPE_PARAM, &col_name, &col_name_len, OCI_ATTR_NAME, cursor->errhp);
			//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r20.htm			
			
			if(!err)
			{
				CUTF16String u((const PA_Unichar *)col_name, col_name_len/sizeof(PA_Unichar));
				returnValue.setUTF16String(&u);
			}
			
			OCIDescriptorFree(param, OCI_DTYPE_PARAM);
			//http://docs.oracle.com/cd/A97630_01/appdev.920/a96584/oci15r23.htm
			
		}

		if(err)
			_errorInfoSet(0, cursor->errhp, cursor->sessionId, cursorId, false, PA_GetCurrentProcessNumber(), 0);	

	}
			
	returnValue.setReturn(pResult);
}
Beispiel #3
0
static void bind_free_common(oci8_base_t *base, ub4 type)
{
    oci8_bind_t *obind = (oci8_bind_t *)base;

    if (obind->valuep != NULL) {
        ub4 idx = 0;
        void **pp = (void**)obind->valuep;

        do {
            if (pp[idx] != NULL) {
                OCIDescriptorFree(pp[idx], type);
                pp[idx] = NULL;
            }
        } while (++idx < obind->maxar_sz);
    }
    oci8_bind_free(base);
}
Beispiel #4
0
sword OCI_DescriptorFree
(
    dvoid    *descp,
    CONST ub4 type
)
{
    sword ret = OCI_SUCCESS;

    if (descp)
    {
        OCI_MUTEXED_CALL(OCILib.nb_descp--)

        ret = OCIDescriptorFree(descp, type);
    }

    return ret;
}
Beispiel #5
0
void oci8_base_free(oci8_base_t *base)
{
    while (base->children != NULL) {
        oci8_base_free(base->children);
    }
    oci8_unlink_from_parent(base);
    if (base->vptr->free != NULL)
        base->vptr->free(base);
    if (base->type >= OCI_DTYPE_FIRST) {
        OCIDescriptorFree(base->hp.ptr, base->type);
    } else if (base->type == OCI_HTYPE_BIND || base->type == OCI_HTYPE_DEFINE) {
        ; /* Do nothing. Bind handles and define handles are freed when
           * associating statement handles are freed.
           */
    } else if (base->type >= OCI_HTYPE_FIRST) {
        OCIHandleFree(base->hp.ptr, base->type);
    }
    base->type = 0;
    base->hp.ptr = NULL;
}
Beispiel #6
0
sword OCI_DescriptorArrayFree
(
    dvoid   **descp,
    CONST ub4 type,
    ub4       nb_elem
)
{
    sword ret = OCI_SUCCESS;

    if (descp)
    {

    #if OCI_VERSION_COMPILE >= OCI_11_1

        if (OCILib.version_runtime >= OCI_11_1)
        {
            ret = OCIArrayDescriptorFree(descp, type);

        }
        else

    #endif

        {
            ub4 i;

            for (i = 0; (i < nb_elem) && (OCI_SUCCESS == ret); i++)
            {
                ret = OCIDescriptorFree(descp[i], type);
            }
        }

        OCI_MUTEXED_CALL(OCILib.nb_descp -= nb_elem)
    }

    return ret;
}
Beispiel #7
0
void Env::freeDescriptor(Descriptor *descriptor,
                         DescriptorType descriptorType)
{
  OCIDescriptorFree(descriptor, descriptorType);
}
Beispiel #8
0
// Вызывается перед первым эхеком...
int ora_check_bind(database *db) {
  int typ,len,i;
  db_col *c; void *val;
  t_ora *o = db->h;
  if(db->in.count==0) return 1; // Нету переменных, OK.
  for(i=0,c=db->in.cols; i<db->in.count; i++,c++)   {
    val=(void*)c->value; c->dbvalue = c->value; // by default -)))
    switch (c->type)
    {
      case dbInt:     typ=INT_TYPE;    len=sizeof(int); break;
      case dbDouble:  typ=SQLT_FLT;  len=sizeof(double); break;
      case dbChar:    typ=STRING_TYPE; len=c->len+1; break;
      case dbDate:    typ=DATE_TYPE; // Придется декодировать...
                      len=7; val=c->dbvalue; //c->value=(void*)c->dbtype;
                      break;
      case dbBlob:    val = c->name[0]!=':'?&o->blob_read:&o->blob;
                      if (1) { int code; ub4 lobEmpty = 0;
//                             if (o->blob) { OCIDescriptorFree(o->blob, (ub4) OCI_DTYPE_LOB); o->blob=0;}
                             if (o->blob) { OCIDescriptorFree(o->blob, (ub4) OCI_DTYPE_LOB); o->blob=0;}
                      OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob,
                           (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0);
                      OCILobCreateTemporary(o->svchp,o->errhp,o->blob,
                        OCI_DEFAULT,OCI_DEFAULT,OCI_TEMP_BLOB,FALSE,OCI_DURATION_SESSION);
                            //if( code=OCILobCreateTemporary(o->svchp, o->errhp, o->blob,
                           //(ub2)0, SQLCS_IMPLICIT,
                           //OCI_TEMP_BLOB, OCI_ATTR_NOCACHE,
                           //OCI_DURATION_SESSION) )
  //{
    // (void) printf("FAILED: CreateTemporary() code=%d \n",code);
    // return 0;
  //}
                           //   code=OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob,
                                    //     (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0);
                            //  printf("Created with code=%d\n",code);
                             // code=OCIAttrSet((dvoid *) o->blob, (ub4) OCI_DTYPE_LOB,
                              //    &lobEmpty, sizeof(lobEmpty),
                               //  (ub4) OCI_ATTR_LOBEMPTY, o->errhp);
                              //if (o->blob)
                              len = 0; typ = SQLT_BLOB;
                              //printf("init oblob=%d code=%d\n",o->blob,code);
                              code = OCILobTrim(o->svchp, o->errhp, o->blob,0);
  //printf("LobTrimmed %d  code=%d!\n",o->blob,code);

                      }
                       len = 0; typ = SQLT_BLOB;
                      break;
      default:        sprintf(db->error,"VORA-bind: unknown type %d pos=%d",c->type,i);
                      return 0;
    }
  //rintf("Start bind var %s\n",c->name);
  if (!ora_ok(db->err_code = OCIBindByName(o->stmt,&o->defs[db->out.count+i],
         o->errhp, (text *) c->name, -1,
              val, len, typ,  (short*)&c->null,
             (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)))
  {
	  ora_error(db);
	  strcat(db->error," on bind ");
	  strcat(db->error,c->name);
	  return 0;
   }
  //rintf("End bind %s\n",c->name);
  }
  return 1;
}
Beispiel #9
0
/*
 * the @ps struct is modified and transferred to the new data model created in
 * this function
 */
GdaDataModel *
gda_oracle_recordset_new (GdaConnection *cnc, GdaOraclePStmt *ps, GdaSet *exec_params,
			  GdaDataModelAccessFlags flags, GType *col_types)
{
	GdaOracleRecordset *model;
        OracleConnectionData *cdata;
        gint i;
	GdaDataModelAccessFlags rflags;

	gint nb_rows = -1;

        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
        g_return_val_if_fail (ps != NULL, NULL);

	cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
	if (!cdata)
		return NULL;

	/* make sure @ps reports the correct number of columns using the API */
        if (_GDA_PSTMT (ps)->ncols < 0) {
		ub4 ncolumns;
		int result;
		
                /* get the number of columns in the result set */
                result = OCIAttrGet ((dvoid *) ps->hstmt,
                                     (ub4) OCI_HTYPE_STMT,
                                     (dvoid *) &ncolumns,
                                     (ub4 *) 0,
                                     (ub4) OCI_ATTR_PARAM_COUNT,
                                     cdata->herr);
                if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
                                             _("Could not get the number of columns in the result set")))
                        return NULL;
		
                _GDA_PSTMT (ps)->ncols = ncolumns;
	}

        /* completing @ps if not yet done */
        if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
		/* create prepared statement's columns */
		GSList *list;
		GList *ora_values = NULL;

		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
			_GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, 
									 gda_column_new ());
		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);

		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;

		if (col_types) {
			for (i = 0; ; i++) {
				if (col_types [i] > 0) {
					if (col_types [i] == G_TYPE_NONE)
						break;
					if (i >= _GDA_PSTMT (ps)->ncols) {
						g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i,
							   _GDA_PSTMT (ps)->ncols - 1);
						break;
					}
					else
						_GDA_PSTMT (ps)->types [i] = col_types [i];
				}
			}
		}
		
		/* fill GdaColumn's data and define the GdaOracleValue structures */
		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
		     i < GDA_PSTMT (ps)->ncols; 
		     i++, list = list->next) {
			GdaColumn *column;
			int result;
			GdaOracleValue *ora_value;
			gboolean use_callback = FALSE;

			ora_value = g_new0 (GdaOracleValue, 1);
			ora_values = g_list_prepend (ora_values, ora_value);

			/* parameter to get attributes */
			result = OCIParamGet (ps->hstmt,
					      OCI_HTYPE_STMT,
					      cdata->herr,
					      (dvoid **) &(ora_value->pard),
					      (ub4) i+1);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the Oracle parameter descripter in the result set"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}
			
			/* data size */
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->defined_size),
					     0,
					     (ub4) OCI_ATTR_DATA_SIZE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the parameter defined size"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}
			ora_value->defined_size++;
			
			/* data type */
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->sql_type),
					     0,
					     OCI_ATTR_DATA_TYPE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the parameter data type"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->precision),
					     0,
					     OCI_ATTR_PRECISION,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the type's precision"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->scale),
					     0,
					     OCI_ATTR_SCALE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the type's scale"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			/* column's name */
			text *name;
			ub4 name_len;
			
			column = GDA_COLUMN (list->data);
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
                                             (ub4) OCI_DTYPE_PARAM,
                                             (dvoid **) &name,
                                             (ub4 *) &name_len,
                                             (ub4) OCI_ATTR_NAME,
                                             (OCIError *) cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
                                                     _("Could not get column name in the result set"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
                                return NULL;
			}

			gchar *name_buffer;
			name_buffer = g_new (gchar, name_len + 1);
			memcpy (name_buffer, name, name_len);
                        name_buffer [name_len] = '\0';
			gda_column_set_name (column, name_buffer);
			gda_column_set_description (column, name_buffer);
			g_free (name_buffer);

			/* for data fetching  */
			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
				ora_value->sql_type = _g_type_to_oracle_sqltype (_GDA_PSTMT (ps)->types [i]);

			switch (ora_value->sql_type) {
			case SQLT_CHR: /* for G_TYPE_STRING => request SQLT_CHR */
			case SQLT_STR:
			case SQLT_VCS:
			case SQLT_RID:
			case SQLT_AVC:
			case SQLT_AFC:
				ora_value->sql_type = SQLT_CHR;
				if (ora_value->defined_size == 1)
					use_callback = TRUE;
				break;

			case SQLT_INT:
				ora_value->defined_size = sizeof (gint);
				break;

			case SQLT_FLT:
			case SQLT_BFLOAT:
				ora_value->defined_size = sizeof (gfloat);
				break;

			case SQLT_BDOUBLE:
				ora_value->defined_size = sizeof (gdouble);
				break;
								
			case SQLT_DAT: /* request OCIDate */
				ora_value->sql_type = SQLT_ODT;
				break;

			case SQLT_NUM: /* for GDA_TYPE_NUMERIC => request SQLT_CHR */
			case SQLT_VNU:
				ora_value->sql_type = SQLT_CHR;
				break;
				
			case SQLT_LBI:
			case SQLT_LVB:
			case SQLT_LVC:
			case SQLT_LNG:
			case SQLT_VBI:
			case SQLT_BIN:
				use_callback = TRUE;
				break;
			default:
				use_callback = TRUE;
				break;
			}
			
			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
				ora_value->g_type = _GDA_PSTMT (ps)->types [i];
			else
				ora_value->g_type = _oracle_sqltype_to_g_type (ora_value->sql_type, ora_value->precision, 
									       ora_value->scale);

			if (ora_value->g_type == GDA_TYPE_BLOB) {
				/* allocate a Lob locator */
				OCILobLocator *lob;
				
				result = OCIDescriptorAlloc ((dvoid *) cdata->henv, (dvoid **) &lob,
							     (ub4) gda_oracle_blob_type (ora_value->sql_type), 
							     (size_t) 0, (dvoid **) 0);
				if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
							     _("Could not allocate Lob locator"))) {
					g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
					return NULL;
				}
				ora_value->value = lob;
				ora_value->defined_size = 0;
			}
			else if (use_callback) {
				ora_value->value = NULL;
				ora_value->defined_size = 33554432; /* 32M */
			}
			else
				ora_value->value = g_malloc0 (ora_value->defined_size);
			
			ora_value->s_type = gda_g_type_to_static_type (ora_value->g_type);
			if (_GDA_PSTMT (ps)->types [i] == GDA_TYPE_NULL)
				_GDA_PSTMT (ps)->types [i] = ora_value->g_type;
			gda_column_set_g_type (column, ora_value->g_type);

#ifdef GDA_DEBUG_NO
			g_print ("**COL type is %d, GType is %s, ORA defined size is %d%s\n",
				 ora_value->sql_type,
				 g_type_name (ora_value->g_type),
				 ora_value->defined_size - 1,
				 use_callback ? " using callback": "");
#endif

			ora_value->hdef = (OCIDefine *) 0;
			ora_value->indicator = 0;
			result = OCIDefineByPos ((OCIStmt *) ps->hstmt,
						 (OCIDefine **) &(ora_value->hdef),
						 (OCIError *) cdata->herr,
						 (ub4) i + 1,
						 ora_value->value,
						 ora_value->defined_size,
						 ora_value->sql_type,
						 (dvoid *) &(ora_value->indicator),
						 &(ora_value->rlen),
						 &(ora_value->rcode),
						 (ub4) (use_callback ? OCI_DYNAMIC_FETCH : OCI_DEFAULT));
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not define by position"))) {
				OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			if (use_callback) {
				result = OCIDefineDynamic ((OCIDefine *) (ora_value->hdef),
							   (OCIError *) (cdata->herr),
							   (dvoid*) (ora_value),
							   (OCICallbackDefine) ora_def_callback);
				if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
							     _("Could not define by position"))) {
					OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
					g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
					return NULL;
				}
			}

			ora_value->use_callback = use_callback;
		}

		ps->ora_values = g_list_reverse (ora_values);
        }

	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD
         * is requested, then we need RANDOM mode */
        if (flags & GDA_DATA_MODEL_ACCESS_RANDOM)
                rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
        else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD)
                rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
        else
                rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;

	ub4 prefetch;
	prefetch = (ub4) (100);
	OCIAttrSet (ps->hstmt, OCI_HTYPE_STMT,
		    &prefetch, 0,
		    OCI_ATTR_PREFETCH_ROWS, cdata->herr);

	/* create data model */
        model = g_object_new (GDA_TYPE_ORACLE_RECORDSET, 
			      "connection", cnc,
			      "prepared-stmt", ps, 
			      "model-usage", rflags, 
			      "exec-params", exec_params, NULL);
	GDA_DATA_SELECT (model)->advertized_nrows = nb_rows;
	
        return GDA_DATA_MODEL (model);
}
Beispiel #10
0
 void Blob::ociDescriptorFree()
 {
   log_debug("OCIDescriptorFree(" << lob << ", OCI_DTYPE_LOB)");
   OCIDescriptorFree(lob, OCI_DTYPE_LOB);
 }
Beispiel #11
0
static int o_read_database_query (o_database_t *db, /* {{{ */
    udb_query_t *q, udb_query_preparation_area_t *prep_area)
{
  char **column_names;
  char **column_values;
  size_t column_num;

  OCIStmt *oci_statement;

  /* List of `OCIDefine' pointers. These defines map columns to the buffer
   * space declared above. */
  OCIDefine **oci_defines;

  int status;
  size_t i;

  oci_statement = udb_query_get_user_data (q);

  /* Prepare the statement */
  if (oci_statement == NULL) /* {{{ */
  {
    const char *statement;

    statement = udb_query_get_statement (q);
    assert (statement != NULL);

    status = OCIHandleAlloc (oci_env, (void *) &oci_statement,
        OCI_HTYPE_STMT, /* user_data_size = */ 0, /* user_data = */ NULL);
    if (status != OCI_SUCCESS)
    {
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIHandleAlloc", oci_error);
      oci_statement = NULL;
      return (-1);
    }

    status = OCIStmtPrepare (oci_statement, oci_error,
        (text *) statement, (ub4) strlen (statement),
        /* language = */ OCI_NTV_SYNTAX,
        /* mode     = */ OCI_DEFAULT);
    if (status != OCI_SUCCESS)
    {
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIStmtPrepare", oci_error);
      OCIHandleFree (oci_statement, OCI_HTYPE_STMT);
      oci_statement = NULL;
      return (-1);
    }
    udb_query_set_user_data (q, oci_statement);

    DEBUG ("oracle plugin: o_read_database_query (%s, %s): "
        "Successfully allocated statement handle.",
        db->name, udb_query_get_name (q));
  } /* }}} */

  assert (oci_statement != NULL);

  /* Execute the statement */
  status = OCIStmtExecute (db->oci_service_context, /* {{{ */
      oci_statement,
      oci_error,
      /* iters = */ 0,
      /* rowoff = */ 0,
      /* snap_in = */ NULL, /* snap_out = */ NULL,
      /* mode = */ OCI_DEFAULT);
  if (status != OCI_SUCCESS)
  {
    o_report_error ("o_read_database_query", db->name, udb_query_get_name (q),
        "OCIStmtExecute", oci_error);
    return (-1);
  } /* }}} */

  /* Acquire the number of columns returned. */
  do /* {{{ */
  {
    ub4 param_counter = 0;
    status = OCIAttrGet (oci_statement, OCI_HTYPE_STMT, /* {{{ */
        &param_counter, /* size pointer = */ NULL,
        OCI_ATTR_PARAM_COUNT, oci_error);
    if (status != OCI_SUCCESS)
    {
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIAttrGet", oci_error);
      return (-1);
    } /* }}} */

    column_num = (size_t) param_counter;
  } while (0); /* }}} */

  /* Allocate the following buffers:
   *
   *  +---------------+-----------------------------------+
   *  ! Name          ! Size                              !
   *  +---------------+-----------------------------------+
   *  ! column_names  ! column_num x DATA_MAX_NAME_LEN    !
   *  ! column_values ! column_num x DATA_MAX_NAME_LEN    !
   *  ! oci_defines   ! column_num x sizeof (OCIDefine *) !
   *  +---------------+-----------------------------------+
   *
   * {{{ */
#define NUMBER_BUFFER_SIZE 64

#define FREE_ALL \
  if (column_names != NULL) { \
    sfree (column_names[0]); \
    sfree (column_names); \
  } \
  if (column_values != NULL) { \
    sfree (column_values[0]); \
    sfree (column_values); \
  } \
  sfree (oci_defines)

#define ALLOC_OR_FAIL(ptr, ptr_size) \
  do { \
    size_t alloc_size = (size_t) ((ptr_size)); \
    (ptr) = calloc (1, alloc_size); \
    if ((ptr) == NULL) { \
      FREE_ALL; \
      ERROR ("oracle plugin: o_read_database_query: calloc failed."); \
      return (-1); \
    } \
  } while (0)

  /* Initialize everything to NULL so the above works. */
  column_names  = NULL;
  column_values = NULL;
  oci_defines   = NULL;

  ALLOC_OR_FAIL (column_names, column_num * sizeof (char *));
  ALLOC_OR_FAIL (column_names[0], column_num * DATA_MAX_NAME_LEN
      * sizeof (char));
  for (i = 1; i < column_num; i++)
    column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;

  ALLOC_OR_FAIL (column_values, column_num * sizeof (char *));
  ALLOC_OR_FAIL (column_values[0], column_num * DATA_MAX_NAME_LEN
      * sizeof (char));
  for (i = 1; i < column_num; i++)
    column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;

  ALLOC_OR_FAIL (oci_defines, column_num * sizeof (OCIDefine *));
  /* }}} End of buffer allocations. */

  /* ``Define'' the returned data, i. e. bind the columns to the buffers
   * allocated above. */
  for (i = 0; i < column_num; i++) /* {{{ */
  {
    char *column_name;
    ub4 column_name_length;
    OCIParam *oci_param;

    oci_param = NULL;

    status = OCIParamGet (oci_statement, OCI_HTYPE_STMT, oci_error,
        (void *) &oci_param, (ub4) (i + 1));
    if (status != OCI_SUCCESS)
    {
      /* This is probably alright */
      DEBUG ("oracle plugin: o_read_database_query: status = %#x (= %i);",
          status, status);
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIParamGet", oci_error);
      status = OCI_SUCCESS;
      break;
    }

    column_name = NULL;
    column_name_length = 0;
    status = OCIAttrGet (oci_param, OCI_DTYPE_PARAM,
        &column_name, &column_name_length, OCI_ATTR_NAME, oci_error);
    if (status != OCI_SUCCESS)
    {
      OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM);
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIAttrGet (OCI_ATTR_NAME)", oci_error);
      continue;
    }

    OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM);
    oci_param = NULL;

    /* Copy the name to column_names. Warning: The ``string'' returned by OCI
     * may not be null terminated! */
    memset (column_names[i], 0, DATA_MAX_NAME_LEN);
    if (column_name_length >= DATA_MAX_NAME_LEN)
      column_name_length = DATA_MAX_NAME_LEN - 1;
    memcpy (column_names[i], column_name, column_name_length);
    column_names[i][column_name_length] = 0;

    DEBUG ("oracle plugin: o_read_database_query: column_names[%zu] = %s; "
        "column_name_length = %"PRIu32";",
        i, column_names[i], (uint32_t) column_name_length);

    status = OCIDefineByPos (oci_statement,
        &oci_defines[i], oci_error, (ub4) (i + 1),
        column_values[i], DATA_MAX_NAME_LEN, SQLT_STR,
        NULL, NULL, NULL, OCI_DEFAULT);
    if (status != OCI_SUCCESS)
    {
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIDefineByPos", oci_error);
      continue;
    }
  } /* for (j = 1; j <= param_counter; j++) */
  /* }}} End of the ``define'' stuff. */

  status = udb_query_prepare_result (q, prep_area,
      (db->host != NULL) ? db->host : hostname_g,
      /* plugin = */ "oracle", db->name, column_names, column_num,
      /* interval = */ 0);
  if (status != 0)
  {
    ERROR ("oracle plugin: o_read_database_query (%s, %s): "
        "udb_query_prepare_result failed.",
        db->name, udb_query_get_name (q));
    FREE_ALL;
    return (-1);
  }

  /* Fetch and handle all the rows that matched the query. */
  while (42) /* {{{ */
  {
    status = OCIStmtFetch2 (oci_statement, oci_error,
        /* nrows = */ 1, /* orientation = */ OCI_FETCH_NEXT,
        /* fetch offset = */ 0, /* mode = */ OCI_DEFAULT);
    if (status == OCI_NO_DATA)
    {
      status = OCI_SUCCESS;
      break;
    }
    else if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO))
    {
      o_report_error ("o_read_database_query", db->name,
          udb_query_get_name (q), "OCIStmtFetch2", oci_error);
      break;
    }

    status = udb_query_handle_result (q, prep_area, column_values);
    if (status != 0)
    {
      WARNING ("oracle plugin: o_read_database_query (%s, %s): "
          "udb_query_handle_result failed.",
          db->name, udb_query_get_name (q));
    }
  } /* }}} while (42) */

  /* DEBUG ("oracle plugin: o_read_database_query: This statement succeeded: %s", q->statement); */
  FREE_ALL;

  return (0);
#undef FREE_ALL
#undef ALLOC_OR_FAIL
} /* }}} int o_read_database_query */
Beispiel #12
0
static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) /* {{{ */
{
	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;

	/* we're only interested in parameters for prepared SQL right now */
	if (param->is_param) {
		pdo_oci_bound_param *P;
		sb4 value_sz = -1;

		P = (pdo_oci_bound_param*)param->driver_data;

		switch (event_type) {
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
			case PDO_PARAM_EVT_NORMALIZE:
				/* Do nothing */
				break;

			case PDO_PARAM_EVT_FREE:
				P = param->driver_data;
				if (P) {
					efree(P);
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
				P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
				param->driver_data = P;

				/* figure out what we're doing */
				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_STMT:
						return 0;

					case PDO_PARAM_LOB:
						/* P->thing is now an OCILobLocator * */
						P->oci_type = SQLT_BLOB;
						value_sz = sizeof(OCILobLocator*);
						break;

					case PDO_PARAM_STR:
					default:
						P->oci_type = SQLT_CHR;
						value_sz = param->max_value_len;
						if (param->max_value_len == 0) {
							value_sz = 1332; /* maximum size before value is interpreted as a LONG value */
						}

				}

				if (param->name) {
					STMT_CALL(OCIBindByName, (S->stmt,
							&P->bind, S->err, (text*)param->name,
							param->namelen, 0, value_sz, P->oci_type,
							&P->indicator, 0, &P->retcode, 0, 0,
							OCI_DATA_AT_EXEC));
				} else {
					STMT_CALL(OCIBindByPos, (S->stmt,
							&P->bind, S->err, param->paramno+1,
							0, value_sz, P->oci_type,
							&P->indicator, 0, &P->retcode, 0, 0,
							OCI_DATA_AT_EXEC));
				}

				STMT_CALL(OCIBindDynamic, (P->bind,
							S->err,
							param, oci_bind_input_cb,
							param, oci_bind_output_cb));

				return 1;

			case PDO_PARAM_EVT_EXEC_PRE:
				P->indicator = 0;
				P->used_for_output = 0;
				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
					ub4 empty = 0;
					STMT_CALL(OCIDescriptorAlloc, (S->H->env, &P->thing, OCI_DTYPE_LOB, 0, NULL));
					STMT_CALL(OCIAttrSet, (P->thing, OCI_DTYPE_LOB, &empty, 0, OCI_ATTR_LOBEMPTY, S->err));
					S->have_blobs = 1;
				}
				return 1;

			case PDO_PARAM_EVT_EXEC_POST:
				/* fixup stuff set in motion in oci_bind_output_cb */
				if (P->used_for_output) {
					if (P->indicator == -1) {
						/* set up a NULL value */
						if (Z_TYPE_P(param->parameter) == IS_STRING
#if ZEND_EXTENSION_API_NO < 220040718
								&& Z_STRVAL_P(param->parameter) != empty_string
#endif
						   ) {
							/* OCI likes to stick non-terminated strings in things */
							*Z_STRVAL_P(param->parameter) = '\0';
						}
						zval_dtor(param->parameter);
						ZVAL_NULL(param->parameter);
					} else if (Z_TYPE_P(param->parameter) == IS_STRING
#if ZEND_EXTENSION_API_NO < 220040718
							&& Z_STRVAL_P(param->parameter) != empty_string
#endif
							) {
						Z_STRLEN_P(param->parameter) = P->actual_len;
						Z_STRVAL_P(param->parameter) = erealloc(Z_STRVAL_P(param->parameter), P->actual_len+1);
						Z_STRVAL_P(param->parameter)[P->actual_len] = '\0';
					}
				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
					php_stream *stm;

					if (Z_TYPE_P(param->parameter) == IS_NULL) {
						/* if the param is NULL, then we assume that they
						 * wanted to bind a lob locator into it from the query
						 * */

						stm = oci_create_lob_stream(stmt, (OCILobLocator*)P->thing);
						if (stm) {
							OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
							php_stream_to_zval(stm, param->parameter);
							P->thing = NULL;
						}
					} else {
						/* we're a LOB being used for insert; transfer the data now */
						size_t n;
						ub4 amt, offset = 1;
						char *consume;

						php_stream_from_zval_no_verify(stm, &param->parameter);
						if (stm) {
							OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
							do {
								char buf[8192];
								n = php_stream_read(stm, buf, sizeof(buf));
								if ((int)n <= 0) {
									break;
								}
								consume = buf;
								do {
									amt = n;
									OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
											&amt, offset, consume, n,
											OCI_ONE_PIECE,
											NULL, NULL, 0, SQLCS_IMPLICIT);
									offset += amt;
									n -= amt;
									consume += amt;
								} while (n);
							} while (1);
							OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
							OCILobFlushBuffer(S->H->svc, S->err, (OCILobLocator*)P->thing, 0);
						} else if (Z_TYPE_P(param->parameter) == IS_STRING) {
							/* stick the string into the LOB */
							consume = Z_STRVAL_P(param->parameter);
							n = Z_STRLEN_P(param->parameter);
							if (n) {
								OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
								while (n) {
									amt = n;
									OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
											&amt, offset, consume, n,
											OCI_ONE_PIECE,
											NULL, NULL, 0, SQLCS_IMPLICIT);
									consume += amt;
									n -= amt;
								}
								OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
							}
						}
						OCIDescriptorFree(P->thing, OCI_DTYPE_LOB);
						P->thing = NULL;
					}
				}

				return 1;
		}
	}

	return 1;
} /* }}} */
Beispiel #13
0
static int oci_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
{
	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
	HashTable *BC = stmt->bound_columns;
	HashTable *BP = stmt->bound_params;

	int i;

	if (S->stmt) {
		/* cancel server side resources for the statement if we didn't
		 * fetch it all */
		OCIStmtFetch(S->stmt, S->err, 0, OCI_FETCH_NEXT, OCI_DEFAULT);

		/* free the handle */
		OCIHandleFree(S->stmt, OCI_HTYPE_STMT);
		S->stmt = NULL;
	}
	if (S->err) {
		OCIHandleFree(S->err, OCI_HTYPE_ERROR);
		S->err = NULL;
	}

	/* need to ensure these go away now */
	if (BC) {
		zend_hash_destroy(BC);
		FREE_HASHTABLE(stmt->bound_columns);
		stmt->bound_columns = NULL;
	}

	if (BP) {
		zend_hash_destroy(BP);
		FREE_HASHTABLE(stmt->bound_params);
		stmt->bound_params = NULL;
	}

	if (S->einfo.errmsg) {
		pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
		S->einfo.errmsg = NULL;
	}

	if (S->cols) {
		for (i = 0; i < stmt->column_count; i++) {
			if (S->cols[i].data) {
				switch (S->cols[i].dtype) {
					case SQLT_BLOB:
					case SQLT_CLOB:
						OCIDescriptorFree(S->cols[i].data, OCI_DTYPE_LOB);
						break;
					default:
						efree(S->cols[i].data);
				}
			}
		}
		efree(S->cols);
		S->cols = NULL;
	}
	efree(S);

	stmt->driver_data = NULL;

	return 1;
} /* }}} */
OracleConnection::ObjectType OracleConnection::ReadSPDescriptionFromDB( const String &command, Anything &desc )
{
	StartTrace(OracleConnection.ReadSPDescriptionFromDB);

	String strErr( "ReadSPDescriptionFromDB: " );

	MemChecker aCheckerLocal( "OracleConnection.ReadSPDescriptionFromDB", getEnvironment().getAllocator() );
	MemChecker aCheckerGlobal( "OracleConnection.ReadSPDescriptionFromDB", coast::storage::Global());

	sword attrStat;
	DscHandleType aDschp;
	if ( checkError( ( attrStat = OCIHandleAlloc( getEnvironment().EnvHandle(), aDschp.getVoidAddr(),
								  OCI_HTYPE_DESCRIBE, 0, 0 ) ) ) ) {
		throw OracleException( *this, attrStat );
	}
	Trace("after HandleAlloc, local allocator:" << reinterpret_cast<long>(getEnvironment().getAllocator()));
	Trace("after HandleAlloc, global allocator:" << reinterpret_cast<long>(coast::storage::Global()));

	OCIParam *parmh( 0 );
	ObjectType aStmtType = DescribeObjectByName(command, aDschp, parmh);
	if ( aStmtType == TYPE_SYN ) {
		Trace("as we identified a synonym, we need to collect the scheme name and the referenced object name to ask for description");
		text *name(0);
		ub4 namelen(0);
		String strSchemaName;
		attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen, OCI_ATTR_SCHEMA_NAME, ErrorHandle() );
		if ( checkError( ( attrStat ) ) ) {
			throw OracleException( *this, attrStat );
		}
		strSchemaName.Append(String( (char *) name, namelen ));
		Trace("SchemaName: " << strSchemaName);

		attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen, OCI_ATTR_NAME, ErrorHandle() );
		if ( checkError( ( attrStat ) ) ) {
			throw OracleException( *this, attrStat );
		}
		if ( strSchemaName.Length() ) {
			strSchemaName.Append('.');
		}
		strSchemaName.Append(String( (char *) name, namelen ));

		Trace("trying to get descriptions for " << strSchemaName);
		aStmtType = DescribeObjectByName(strSchemaName, aDschp, parmh);
	}
	bool bIsFunction = ( aStmtType == TYPE_FUNC );

	Trace("get the number of arguments and the arg list for stored " << (bIsFunction ? "function" : "procedure"))
	OCIParam *arglst( 0 );
	ub2 numargs = 0;
	if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &arglst, (ub4 *) 0,
								  OCI_ATTR_LIST_ARGUMENTS, ErrorHandle() ) ) ) ) {
		throw OracleException( *this, attrStat );
	}
	if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arglst, OCI_DTYPE_PARAM, (dvoid *) &numargs, (ub4 *) 0,
								  OCI_ATTR_NUM_PARAMS, ErrorHandle() ) ) ) ) {
		throw OracleException( *this, attrStat );
	}
	Trace(String("number of arguments: ") << numargs);

	OCIParam *arg( 0 );
	text *name;
	ub4 namelen;
	ub2 dtype;
	OCITypeParamMode iomode;
	ub4 data_len;

	// For a procedure, we begin with i = 1; for a function, we begin with i = 0.
	int start = 0;
	int end = numargs;
	if ( !bIsFunction ) {
		++start;
		++end;
	}

	for ( int i = start; i < end; ++i ) {
		if ( checkError( ( attrStat = OCIParamGet( (dvoid *) arglst, OCI_DTYPE_PARAM, ErrorHandle(), (dvoid **) &arg,
									  (ub4) i ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
		namelen = 0;
		name = 0;
		data_len = 0;

		if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &dtype, (ub4 *) 0,
									  OCI_ATTR_DATA_TYPE, ErrorHandle() ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
		Trace("Data type: " << dtype)

		if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen,
									  OCI_ATTR_NAME, ErrorHandle() ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
		String strName( (char *) name, namelen );
		// the first param of a function is the return param
		if ( bIsFunction && i == start ) {
			strName = command;
			Trace("Name: " << strName)
		}

		// 0 = IN (OCI_TYPEPARAM_IN), 1 = OUT (OCI_TYPEPARAM_OUT), 2 = IN/OUT (OCI_TYPEPARAM_INOUT)
		if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &iomode, (ub4 *) 0,
									  OCI_ATTR_IOMODE, ErrorHandle() ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
		Trace("IO type: " << iomode)

		if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &data_len, (ub4 *) 0,
									  OCI_ATTR_DATA_SIZE, ErrorHandle() ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
		Trace("Size: " << (int)data_len)

		Anything param( desc.GetAllocator() );
		param["Name"] = strName;
		param["Type"] = dtype;
		param["Length"] = (int) data_len;
		param["IoMode"] = iomode;
		param["Idx"] = (long) ( bIsFunction ? i + 1 : i );
		desc.Append( param );
		if ( checkError( ( attrStat = OCIDescriptorFree( arg, OCI_DTYPE_PARAM ) ) ) ) {
			throw OracleException( *this, attrStat );
		}
	}
Beispiel #15
0
GSQLCursorState 
oracle_cursor_open (GSQLCursor *cursor)
{
	GSQL_TRACE_FUNC;

	GSQLEOracleCursor	*spec_cursor;
	GSQLEOracleSession	*spec_session;
	GSQLEOracleVariable *spec_var;
	GSQLVariable		*var;
	gint var_count;
	sword ret;
	OCIParam *param;
	unsigned char op[2000];
	gint i;
	gchar buffer[GSQL_MESSAGE_LEN];
    
	g_return_val_if_fail (GSQL_IS_CURSOR (cursor), GSQL_CURSOR_STATE_ERROR);
	
	spec_session = (GSQLEOracleSession *) cursor->session->spec;
	spec_cursor = g_malloc0 (sizeof (GSQLEOracleCursor));	
	cursor->spec = spec_cursor;
	
	ret = OCIHandleAlloc ((dvoid *)(spec_session->envhp), 
					   (dvoid **)&(spec_cursor->errhp),
						OCI_HTYPE_ERROR, 0, (dvoid **) 0);
	if (ret == OCI_ERROR)
	{

		GSQL_DEBUG("oracle_cursor_open: OCIHandleAlloc (allocate an error handle)... failed");
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	}

	if ((!oracle_sql_prepare (cursor, cursor->sql)) || 
		(!oracle_sql_exec (cursor)))
	{
		
		OCIHandleFree ((dvoid *)spec_cursor->errhp, OCI_HTYPE_ERROR);
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	ret = OCIAttrGet (spec_cursor->statement, OCI_HTYPE_STMT, (dvoid*) &(var_count), 0,
						OCI_ATTR_PARAM_COUNT, spec_cursor->errhp);
	
	if (oracle_check_error (cursor, ret))
	{
		
		OCIHandleFree ((dvoid *)spec_cursor->errhp, OCI_HTYPE_ERROR);
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	};
		
	
	for (i = 0; i < var_count; i++)
	{

		ret = OCIParamGet (spec_cursor->statement, OCI_HTYPE_STMT,
						spec_cursor->errhp, (void**) &param, i+1);
                
 		if (oracle_check_error (cursor, ret))
		{
			 g_free (spec_cursor);
			 return GSQL_CURSOR_STATE_ERROR;
		};

		var = gsql_variable_new ();
		oracle_variable_init (cursor, var, param, i+1);
		cursor->var_list = g_list_append (cursor->var_list, var);
		OCIDescriptorFree (param, OCI_DTYPE_PARAM);

	}
	
	
	
	return GSQL_CURSOR_STATE_OPEN;
}
Beispiel #16
0
GSQLCursorState 
oracle_cursor_open_bind_by_name (GSQLCursor *cursor, GList *args)
{
	GSQL_TRACE_FUNC;

	GSQLEOracleCursor	*spec_cursor;
	GSQLEOracleSession	*spec_session;
	GSQLEOracleVariable *spec_var;
	GSQLVariable		*var;
	GList *vlist = args;
	GList *vlist_value;
	GType vtype;
	guint  n, var_count=0;
	sword ret;
	OCIParam *param;
	static OCIBind *bindhp = 0;
	unsigned char op[2000];
	gint i;
	gchar *holder;
	gchar buffer[GSQL_MESSAGE_LEN];
    
	g_return_val_if_fail (GSQL_IS_CURSOR (cursor), GSQL_CURSOR_STATE_ERROR);
	
	spec_session = (GSQLEOracleSession *) cursor->session->spec;
	spec_cursor = g_malloc0 (sizeof (GSQLEOracleCursor));	
	cursor->spec = spec_cursor;
	
	ret = OCIHandleAlloc ((dvoid *)(spec_session->envhp), 
					   (dvoid **)&(spec_cursor->errhp),
						OCI_HTYPE_ERROR, 0, (dvoid **) 0);
	
	if (ret == OCI_ERROR)
	{

		GSQL_DEBUG("oracle_cursor_open: OCIHandleAlloc (allocate an error handle)... failed");
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	}

	if (!oracle_sql_prepare (cursor, cursor->sql))
	{
		
		OCIHandleFree ((dvoid *)spec_cursor->errhp, OCI_HTYPE_ERROR);
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	n = 0;
	
	while (vlist)
	{
		vtype = (GType) vlist->data;
		
		/* bind by name means first item are name of bind point - it is always are string (gchar *) */
		if (vtype != G_TYPE_STRING)
		{
			GSQL_DEBUG ("Wrong GSQL_CURSOR_BIND_BY_NAME usage");
			return GSQL_CURSOR_STATE_ERROR;
		}
		
		vlist = g_list_next (vlist);
		holder = g_strdup ( (gchar *) vlist->data);
		
		vlist = g_list_next (vlist);
		vtype = (GType) vlist->data;
		vlist = g_list_next (vlist);
		
		switch (vtype)
		{
			case G_TYPE_STRING:
			case G_TYPE_POINTER:
			
				ret = OCIBindByName (spec_cursor->statement, &bindhp, spec_cursor->errhp,
							(CONST text *) holder,-1,
							(dvoid *) vlist->data, (sb4)strlen(vlist->data)+1, (ub2) SQLT_STR,
							(dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0,
							(ub4) OCI_DEFAULT);
				GSQL_DEBUG ("Bind by name: [\'%s\' = %s] [ret = %d]", holder, vlist->data, ret);
				if (oracle_check_error (cursor, ret))
				{
					GSQL_DEBUG ("bind error");
				}
				
				break;
			
			case G_TYPE_INT:
			case G_TYPE_UINT:
				GSQL_FIXME;
				
				break;
			
			case G_TYPE_UINT64:
			case G_TYPE_INT64:
				GSQL_FIXME;
			
				break;
			
			case G_TYPE_DOUBLE:
				GSQL_FIXME;
				
				break;
				
		}
		
		g_free (holder);
		
		vlist = g_list_next (vlist);
		n++;
	}

	
	if (!oracle_sql_exec (cursor))
	{
		
		OCIHandleFree ((dvoid *)spec_cursor->errhp, OCI_HTYPE_ERROR);
		cursor->spec = NULL;
		g_free (spec_cursor);
		
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	ret = OCIAttrGet (spec_cursor->statement, OCI_HTYPE_STMT, (dvoid*) &(var_count), 0,
						OCI_ATTR_PARAM_COUNT, spec_cursor->errhp);
	
	if (oracle_check_error (cursor, ret))
	{
		
		OCIHandleFree ((dvoid *)spec_cursor->errhp, OCI_HTYPE_ERROR);
		cursor->spec = NULL;
		g_free (spec_cursor);
		return GSQL_CURSOR_STATE_ERROR;
	}
			
	for (i = 0; i < var_count; i++)
	{

		ret = OCIParamGet (spec_cursor->statement, OCI_HTYPE_STMT,
						spec_cursor->errhp, (void**) &param, i+1);
                
 		if (oracle_check_error (cursor, ret))
		{
			 g_free (spec_cursor);
			 return GSQL_CURSOR_STATE_ERROR;
		};

		var = gsql_variable_new ();
		oracle_variable_init (cursor, var, param, i+1);
		cursor->var_list = g_list_append (cursor->var_list, var);
		OCIDescriptorFree (param, OCI_DTYPE_PARAM);

	}
		
	return GSQL_CURSOR_STATE_OPEN;

}
Beispiel #17
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_db_vselect                                                   *
 *                                                                            *
 * Purpose: execute a select statement                                        *
 *                                                                            *
 * Return value: data, NULL (on error) or (DB_RESULT)ZBX_DB_DOWN              *
 *                                                                            *
 ******************************************************************************/
DB_RESULT	zbx_db_vselect(const char *fmt, va_list args)
{
	char		*sql = NULL;
	DB_RESULT	result = NULL;
	double		sec = 0;

#if defined(HAVE_IBM_DB2)
	int		i;
	SQLRETURN	ret = SQL_SUCCESS;
#elif defined(HAVE_ORACLE)
	sword		err = OCI_SUCCESS;
	ub4		counter;
#elif defined(HAVE_POSTGRESQL)
	char		*error = NULL;
#elif defined(HAVE_SQLITE3)
	int		ret = FAIL;
	char		*error = NULL;
#endif

	if (0 != CONFIG_LOG_SLOW_QUERIES)
		sec = zbx_time();

	sql = zbx_dvsprintf(sql, fmt, args);

	if (1 == txn_error)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "ignoring query [txnlev:%d] [%s] within failed transaction", txn_level, sql);
		goto clean;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "query [txnlev:%d] [%s]", txn_level, sql);

#if defined(HAVE_IBM_DB2)
	result = zbx_malloc(result, sizeof(ZBX_IBM_DB2_RESULT));
	memset(result, 0, sizeof(ZBX_IBM_DB2_RESULT));

	/* allocate a statement handle */
	if (SUCCEED != zbx_ibm_db2_success(ret = SQLAllocHandle(SQL_HANDLE_STMT, ibm_db2.hdbc, &result->hstmt)))
		goto error;

	/* directly execute the statement */
	if (SUCCEED != zbx_ibm_db2_success(ret = SQLExecDirect(result->hstmt, (SQLCHAR *)sql, SQL_NTS)))
		goto error;

	/* identify the number of output columns */
	if (SUCCEED != zbx_ibm_db2_success(ret = SQLNumResultCols(result->hstmt, &result->ncolumn)))
		goto error;

	if (0 == result->ncolumn)
		goto error;

	result->nalloc = 0;
	result->values = zbx_malloc(result->values, sizeof(char *) * result->ncolumn);
	result->values_cli = zbx_malloc(result->values_cli, sizeof(char *) * result->ncolumn);
	result->values_len = zbx_malloc(result->values_len, sizeof(SQLINTEGER) * result->ncolumn);

	for (i = 0; i < result->ncolumn; i++)
	{
		/* get the display size for a column */
		if (SUCCEED != zbx_ibm_db2_success(ret = SQLColAttribute(result->hstmt, (SQLSMALLINT)(i + 1),
				SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &result->values_len[i])))
		{
			goto error;
		}

		result->values_len[i] += 1; /* '\0'; */

		/* allocate memory to bind a column */
		result->values_cli[i] = zbx_malloc(NULL, result->values_len[i]);
		result->nalloc++;

		/* bind columns to program variables, converting all types to CHAR */
		if (SUCCEED != zbx_ibm_db2_success(ret = SQLBindCol(result->hstmt, (SQLSMALLINT)(i + 1),
				SQL_C_CHAR, result->values_cli[i], result->values_len[i], &result->values_len[i])))
		{
			goto error;
		}
	}
error:
	if (SUCCEED != zbx_ibm_db2_success(ret) || 0 == result->ncolumn)
	{
		zbx_ibm_db2_log_errors(SQL_HANDLE_DBC, ibm_db2.hdbc);
		zbx_ibm_db2_log_errors(SQL_HANDLE_STMT, result->hstmt);

		IBM_DB2free_result(result);

		result = (SQL_CD_TRUE == IBM_DB2server_status() ? NULL : (DB_RESULT)ZBX_DB_DOWN);
	}
#elif defined(HAVE_MYSQL)
	if (NULL == conn)
	{
		zabbix_errlog(ERR_Z3003);
		result = NULL;
	}
	else
	{
		if (0 != mysql_query(conn, sql))
		{
			zabbix_errlog(ERR_Z3005, mysql_errno(conn), mysql_error(conn), sql);
			switch (mysql_errno(conn))
			{
				case CR_CONN_HOST_ERROR:
				case CR_SERVER_GONE_ERROR:
				case CR_CONNECTION_ERROR:
				case CR_SERVER_LOST:
				case ER_SERVER_SHUTDOWN:
				case ER_ACCESS_DENIED_ERROR: /* wrong user or password */
				case ER_ILLEGAL_GRANT_FOR_TABLE: /* user without any privileges */
				case ER_TABLEACCESS_DENIED_ERROR:/* user without some privilege */
				case ER_UNKNOWN_ERROR:
					result = (DB_RESULT)ZBX_DB_DOWN;
					break;
				default:
					result = NULL;
					break;
			}
		}
		else
			result = mysql_store_result(conn);
	}
#elif defined(HAVE_ORACLE)
	result = zbx_malloc(NULL, sizeof(ZBX_OCI_DB_RESULT));
	memset(result, 0, sizeof(ZBX_OCI_DB_RESULT));

	err = OCIHandleAlloc((dvoid *)oracle.envhp, (dvoid **)&result->stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);

	if (OCI_SUCCESS == err)
	{
		err = OCIStmtPrepare(result->stmthp, oracle.errhp, (text *)sql, (ub4)strlen((char *)sql),
				(ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
	}

	if (OCI_SUCCESS == err)
	{
		err = OCIStmtExecute(oracle.svchp, result->stmthp, oracle.errhp, (ub4)0, (ub4)0,
				(CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_COMMIT_ON_SUCCESS);
	}

	if (OCI_SUCCESS == err)
	{
		/* get the number of columns in the query */
		err = OCIAttrGet((void *)result->stmthp, OCI_HTYPE_STMT, (void *)&result->ncolumn,
				  (ub4 *)0, OCI_ATTR_PARAM_COUNT, oracle.errhp);
	}

	if (OCI_SUCCESS != err)
		goto error;

	assert(0 < result->ncolumn);

	result->values = zbx_malloc(NULL, result->ncolumn * sizeof(char *));
	memset(result->values, 0, result->ncolumn * sizeof(char *));

	for (counter = 1; OCI_SUCCESS == err && counter <= result->ncolumn; counter++)
	{
		OCIParam	*parmdp = NULL;
		OCIDefine	*defnp = NULL;
		ub4		char_semantics;
		ub2		col_width;

		/* request a parameter descriptor in the select-list */
		err = OCIParamGet((void *)result->stmthp, OCI_HTYPE_STMT, oracle.errhp, (void **)&parmdp, (ub4)counter);

		if (OCI_SUCCESS == err)
		{
			/* retrieve the length semantics for the column */
			char_semantics = 0;
			err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&char_semantics, (ub4 *)0,
					(ub4)OCI_ATTR_CHAR_USED, (OCIError *)oracle.errhp);
		}

		if (OCI_SUCCESS == err)
		{
			col_width = 0;
			if (char_semantics)
			{
				/* retrieve the column width in characters */
				err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&col_width, (ub4 *)0,
						(ub4)OCI_ATTR_CHAR_SIZE, (OCIError *)oracle.errhp);
			}
			else
			{
				/* retrieve the column width in bytes */
				err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&col_width, (ub4 *)0,
						(ub4)OCI_ATTR_DATA_SIZE, (OCIError *)oracle.errhp);
			}
		}
		col_width++;

		result->values[counter - 1] = zbx_malloc(NULL, col_width);
		memset(result->values[counter - 1], 0, col_width);

		if (OCI_SUCCESS == err)
		{
			/* represent any data as characters */
			err = OCIDefineByPos(result->stmthp, &defnp, oracle.errhp, counter,
					(dvoid *)result->values[counter - 1], col_width, SQLT_STR,
					(dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT);
		}

		/* free cell descriptor */
		OCIDescriptorFree(parmdp, OCI_DTYPE_PARAM);
		parmdp = NULL;
	}

error:
	if (OCI_SUCCESS != err)
	{
		zabbix_errlog(ERR_Z3005, err, zbx_oci_error(err), sql);

		OCI_DBfree_result(result);

		result = (OCI_SERVER_NORMAL == OCI_DBserver_status() ? NULL : (DB_RESULT)ZBX_DB_DOWN);
	}
#elif defined(HAVE_POSTGRESQL)
	result = zbx_malloc(NULL, sizeof(ZBX_PG_DB_RESULT));
	result->pg_result = PQexec(conn, sql);
	result->values = NULL;
	result->cursor = 0;
	result->row_num = 0;

	if (NULL == result->pg_result)
		zabbix_errlog(ERR_Z3005, 0, "result is NULL", sql);

	if (PGRES_TUPLES_OK != PQresultStatus(result->pg_result))
	{
		error = zbx_dsprintf(error, "%s:%s",
				PQresStatus(PQresultStatus(result->pg_result)),
				PQresultErrorMessage(result->pg_result));
		zabbix_errlog(ERR_Z3005, 0, error, sql);
		zbx_free(error);

		PG_DBfree_result(result);
		result = (CONNECTION_OK == PQstatus(conn) ? NULL : (DB_RESULT)ZBX_DB_DOWN);
	}
	else	/* init rownum */
		result->row_num = PQntuples(result->pg_result);
#elif defined(HAVE_SQLITE3)
	if (0 == txn_level && PHP_MUTEX_OK != php_sem_acquire(&sqlite_access))
	{
		zabbix_log(LOG_LEVEL_CRIT, "ERROR: cannot create lock on SQLite3 database");
		exit(FAIL);
	}

	result = zbx_malloc(NULL, sizeof(ZBX_SQ_DB_RESULT));
	result->curow = 0;

lbl_get_table:
	if (SQLITE_OK != (ret = sqlite3_get_table(conn,sql, &result->data, &result->nrow, &result->ncolumn, &error)))
	{
		if (SQLITE_BUSY == ret)
			goto lbl_get_table;

		zabbix_errlog(ERR_Z3005, 0, error, sql);
		sqlite3_free(error);

		SQ_DBfree_result(result);

		switch (ret)
		{
			case SQLITE_ERROR:	/* SQL error or missing database; assuming SQL error, because if we
						   are this far into execution, zbx_db_connect() was successful */
			case SQLITE_NOMEM:	/* a malloc() failed */
			case SQLITE_MISMATCH:	/* data type mismatch */
				result = NULL;
				break;
			default:
				result = (DB_RESULT)ZBX_DB_DOWN;
				break;
		}
	}

	if (0 == txn_level)
		php_sem_release(&sqlite_access);
#endif	/* HAVE_SQLITE3 */

	if (0 != CONFIG_LOG_SLOW_QUERIES)
	{
		sec = zbx_time() - sec;
		if (sec > (double)CONFIG_LOG_SLOW_QUERIES / 1000.0)
			zabbix_log(LOG_LEVEL_WARNING, "slow query: " ZBX_FS_DBL " sec, \"%s\"", sec, sql);
	}

	if (NULL == result && 0 < txn_level)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "query [%s] failed, setting transaction as failed", sql);
		txn_error = 1;
	}
clean:
	zbx_free(sql);

	return result;
}
Beispiel #18
0
INTF_RET oci_exec_sql(const void *conn_handle, unsigned long & stmt_handle, const unsigned char * query_str, int query_str_len, inp_t *params_head, void * column_list)
{
    function_success = SUCCESS;

#if DEBUG < DBG_5
    fprintf(fp_log, "Executing \"%.*s;\"\n", query_str_len, query_str);
#endif

    OCISvcCtx *svchp = (OCISvcCtx *)conn_handle;
    OCIStmt *stmthp	= NULL;
    stmt_handle = 0;

    /* Get a prepared statement handle */
    checkerr(errhp, OCIStmtPrepare2(svchp,
                                    &stmthp,					/* returned statement handle */
                                    errhp,						/* error handle */
                                    (OraText *) query_str,		/* the statement text */
                                    query_str_len,				/* length of the text */
                                    NULL, 0,					/* tagging parameters: optional */
                                    OCI_NTV_SYNTAX, OCI_DEFAULT));
    if(function_success != SUCCESS) return function_success;

    /* Bind variables */
    ub2 type = SQLT_INT;
    int idx = 1;
    for(inp_t *param = params_head; param != NULL; param = param->next) {
        switch (param->dty) {
        case NUMBER:
            type = SQLT_INT;
            break;
        case STRING:
            type = SQLT_STR;
            break;
        }
        param->bndp = NULL;
        checkerr(errhp, OCIBindByPos(stmthp, (OCIBind **)&(param->bndp), errhp, idx,
                                     (dvoid *) param->valuep, (sword) param->value_sz, type,
                                     (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT));
        if(function_success != SUCCESS) return function_success;
        idx++;
    }

    ub4 stmt_typ = OCI_STMT_SELECT;
    ub4 itrs = 0;
    checkerr(errhp, OCIAttrGet((dvoid*) stmthp, (ub4) OCI_HTYPE_STMT,
                               (dvoid*) &stmt_typ, (ub4 *)NULL, (ub4)OCI_ATTR_STMT_TYPE, errhp));
    if(function_success != SUCCESS) return function_success;
    if(stmt_typ != OCI_STMT_SELECT)
        itrs = 1;

    /* execute the statement and commit */
    checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, itrs, 0,
                                   (OCISnapshot *)NULL, (OCISnapshot *)NULL,
                                   OCI_COMMIT_ON_SUCCESS));
    if(function_success != SUCCESS) return function_success;

    if(stmt_typ == OCI_STMT_SELECT) {
        OCIParam	*mypard;
        num_cols	= 1;
        sb4         parm_status;

        /* Request a parameter descriptor for position 1 in the select-list */
        parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, (dvoid **)&mypard,
                                  (ub4) num_cols);
        checkerr(errhp, parm_status);
        if(function_success != SUCCESS) return function_success;

        /* Loop only if a descriptor was successfully retrieved for
         * current position, starting at 1
         */
        text *col_name;
        ub4 len = 0;
        char * data_type = NULL;
        if (columns != NULL)
            free(columns);
        columns = NULL;
        while (parm_status == OCI_SUCCESS) {
            columns = (column_info *)realloc(columns, num_cols * sizeof(column_info));
            column_info * cur_clm = &(columns[num_cols-1]);

            /* Retrieve the data type attribute */
            len = 0;
            checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM,
                                       (dvoid*) &len, (ub4 *)0, (ub4)OCI_ATTR_DATA_TYPE,
                                       errhp));
            if(function_success != SUCCESS) return function_success;
            cur_clm->dtype = len;

            switch (len) {
            case SQLT_NUM:
            case SQLT_VNU:
            case SQLT_LNG:
                data_type = (char*)"number";
                break;
            case SQLT_AVC:
            case SQLT_AFC:
            case SQLT_CHR:
            case SQLT_STR:
            case SQLT_VCS:
                data_type = (char*)"string";
                break;
            case SQLT_INT:
            case SQLT_UIN:
                data_type = (char*)"integer";
                break;
            case SQLT_DAT:
                data_type = (char*)"date";
                break;
            case SQLT_FLT:
                data_type = (char*)"double";
                break;
            default:
                data_type = (char*)"undefined";
                break;
            }

            /* Retrieve the data size attribute */
            len = 0;
            checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM,
                                       (dvoid*) &len, (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE,
                                       errhp));
            if(function_success != SUCCESS) return function_success;
            cur_clm->dlen = len;

            /* Retrieve the column name attribute */
            len = 0;
            checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM,
                                       (dvoid**) &col_name, (ub4 *) &len, (ub4) OCI_ATTR_NAME,
                                       errhp));
            if(function_success != SUCCESS) return function_success;
            char * column_name = new char[len+1];
            sprintf_s(column_name, len+1, "%.*s", len, col_name);
            append_coldef_to_list(column_name, data_type, cur_clm->dlen, column_list);
            delete column_name;
            col_name = NULL;

            /* Increment counter and get next descriptor, if there is one */
            if(OCI_SUCCESS != OCIDescriptorFree(mypard, OCI_DTYPE_PARAM))
                return FAILURE;
            num_cols++;
            parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, (dvoid **)&mypard,
                                      (ub4) num_cols);
        }
        --num_cols;

        if(function_success != SUCCESS)
            return function_success;
        REMOTE_LOG("Port: Returning Columns");
        stmt_handle = (unsigned long)stmthp;
    } else {
        if(stmthp != NULL) {
            checkerr(errhp, OCIStmtRelease(stmthp, errhp, NULL, 0, OCI_DEFAULT));
            if(function_success != SUCCESS) return function_success;
        }
        REMOTE_LOG("Port: Executed non-select statement!");
    }

    return function_success;
}
Beispiel #19
0
 void Datetime::ociDescriptorFree()
 {
   log_debug("OCIDescriptorFree(" << datetime << ", OCI_DTYPE_TIMESTAMP)");
   OCIDescriptorFree(datetime, OCI_DTYPE_TIMESTAMP);
 }
Beispiel #20
0
/* ruby 1.9 */
sword oci8_call_without_gvl(oci8_svcctx_t *svcctx, void *(*func)(void *), void *data)
{
    OCIError *errhp = oci8_errhp;

    if (!NIL_P(svcctx->executing_thread)) {
        rb_raise(rb_eRuntimeError /* FIXME */, "executing in another thread");
    }

    if (!svcctx->suppress_free_temp_lobs) {
        oci8_temp_lob_t *lob = svcctx->temp_lobs;
        while (lob != NULL) {
            oci8_temp_lob_t *lob_next = lob->next;

            if (svcctx->non_blocking) {
                free_temp_lob_arg_t arg;
                sword rv;

                arg.svcctx = svcctx;
                arg.svchp = svcctx->base.hp.svc;
                arg.errhp = errhp;
                arg.lob = lob->lob;

                svcctx->executing_thread = rb_thread_current();
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
                rv = (sword)(VALUE)rb_thread_call_without_gvl(free_temp_lob, &arg, oci8_unblock_func, svcctx);
#else
                rv = (sword)rb_thread_blocking_region((VALUE(*)(void*))free_temp_lob, &arg, oci8_unblock_func, svcctx);
#endif
                if (rv == OCI_ERROR) {
                    if (oci8_get_error_code(errhp) == 1013) {
                        rb_raise(eOCIBreak, "Canceled by user request.");
                    }
                }
            } else {
                OCILobFreeTemporary(svcctx->base.hp.svc, errhp, lob->lob);
            }
            OCIDescriptorFree(lob->lob, OCI_DTYPE_LOB);

            xfree(lob);
            svcctx->temp_lobs = lob = lob_next;
        }
    }

    if (svcctx->non_blocking) {
        sword rv;

        svcctx->executing_thread = rb_thread_current();
        /* Note: executing_thread is cleard at the end of the blocking function. */
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
        rv = (sword)(VALUE)rb_thread_call_without_gvl(func, data, oci8_unblock_func, svcctx);
#else
        rv = (sword)rb_thread_blocking_region((VALUE(*)(void*))func, data, oci8_unblock_func, svcctx);
#endif
        if (rv == OCI_ERROR) {
            if (oci8_get_error_code(errhp) == 1013) {
                rb_raise(eOCIBreak, "Canceled by user request.");
            }
        }
        return rv;
    } else {
        return (sword)(VALUE)func(data);
    }
}
Beispiel #21
0
void DownloadFileWithCompression(struct ORACLEALLINONE *oraAllInOne, char* pDirectory,
                                 int compressionLevel, char* pRemoteFile, char* pLocalFile,
                                 int isKeepPartial, int isResume)
{
	FILE *fp;
	sword ociResult;
	ub4 vCompressionLevel;
	ub8 vSkipBytes;
	char blobBuffer[ORA_BLOB_BUFFER_SIZE];
	oraub8 vSize;
	int zRet;
	z_stream zStrm;
	unsigned char zOut[ORA_BLOB_BUFFER_SIZE];
#ifndef _WIN32
	int showProgress;
	char progressLine[MAX_FMT_SIZE];
#endif
	int isStdUsed;
	off_t cnt;
	off_t sourceSize;
        struct stat fileStat;

	struct BINDVARIABLE oraBindsDownload[] =
	{
		{ 0, SQLT_STR,  ":directory",         pDirectory,         ORA_IDENTIFIER_SIZE + 1   },
		{ 0, SQLT_INT,  ":compression_level", &vCompressionLevel, sizeof(vCompressionLevel) },
		{ 0, SQLT_STR,  ":filename",          pRemoteFile,        MAX_FMT_SIZE              },
		{ 0, SQLT_BLOB, ":blob",              &oraAllInOne->blob, sizeof(oraAllInOne->blob) },
		{ 0, SQLT_INT,  ":skipbytes",         &vSkipBytes,        sizeof(vSkipBytes)        },
		{ 0 }
	};

	struct ORACLESTATEMENT oraStmtDownload = {
#include "downloadcompr.text"
,
		0, oraBindsDownload, NO_ORACLE_DEFINES };

	vCompressionLevel = compressionLevel;
	isStdUsed = !strcmp(pLocalFile, "-");
	if (isStdUsed)
	{
		isResume = 0;
		isKeepPartial = 1;
	}

	SetSessionAction(oraAllInOne, "GZIP_AND_DOWNLOAD: GZIP");
	if (OCIDescriptorAlloc(oraAllInOne->envhp, (void**)&oraAllInOne->blob, OCI_DTYPE_LOB, 0, 0))
	{
		ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to allocate BLOB\n");
	}

	cnt = 0;
	vSkipBytes = 0;
	if (isResume)
	{
		if (!stat(pLocalFile, &fileStat))
			vSkipBytes = cnt = fileStat.st_size;
		if (!cnt)
			isResume = 0;
	}

#ifndef _WIN32
	showProgress = 1;
	if (!isatty(STDOUT_FILENO) || isStdUsed)
		showProgress = 0;

	if (showProgress)
		start_longops_meter(oraAllInOne, 0, 1);
#endif

	PrepareStmtAndBind(oraAllInOne, &oraStmtDownload);
	ociResult = ExecuteStmt(oraAllInOne);
#ifndef _WIN32
	if (showProgress)
		stop_longops_meter();
#endif

	if (ociResult)
		ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Failed to compress file in oracle directory\n");

#ifndef _WIN32
	if (showProgress)
	{
		if (OCILobGetLength2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, (oraub8*)&sourceSize))
			ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error getting BLOB length\n");
		strcpy(progressLine, "TRANSFER & GUNZIP: ");
		strncat(progressLine, basename(pLocalFile), MAX_FMT_SIZE - 1 - strlen(progressLine));
		start_progress_meter(progressLine, sourceSize, &cnt);
	}
#endif

	SetSessionAction(oraAllInOne, "GZIP_AND_DOWNLOAD: DOWNLOAD");
	if (!isStdUsed && (fp = fopen(pLocalFile, isResume ? "ab" : "wb")) == NULL)
	{
		ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error opening a local file for writing\n");
	}
	if (isStdUsed)
		fp = stdout;

	zStrm.zalloc = Z_NULL;
	zStrm.zfree = Z_NULL;
	zStrm.opaque = Z_NULL;
	zStrm.avail_in = 0;
	zStrm.next_in = Z_NULL;
	zRet = inflateInit2(&zStrm, 16+MAX_WBITS);
	if (zRet != Z_OK)
	{
		if (!isStdUsed)
			fclose(fp);
		ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB initialization failed\n");
	}

	vSize = 0;
	ociResult = OCILobRead2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE, OCI_FIRST_PIECE, 0, 0, 0, 0);
	while (ociResult == OCI_NEED_DATA || ociResult == OCI_SUCCESS)
	{
		cnt += vSize;
		zStrm.avail_in = vSize;
		zStrm.next_in = blobBuffer;
		do
		{
			zStrm.avail_out = ORA_BLOB_BUFFER_SIZE;
			zStrm.next_out = zOut;
			zRet = inflate(&zStrm, Z_NO_FLUSH);
			switch (zRet)
			{
            case Z_STREAM_ERROR:
			case Z_NEED_DICT:
			case Z_DATA_ERROR:
			case Z_MEM_ERROR:
				(void)inflateEnd(&zStrm);
				if (!isStdUsed)
					fclose(fp);
				ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB inflate failed: %d, size %d\n", zRet, vSize);
			}

			fwrite(zOut, sizeof(unsigned char), ORA_BLOB_BUFFER_SIZE - zStrm.avail_out, fp);
			if (ferror(fp))
			{
				(void)inflateEnd(&zStrm);
				if (!isStdUsed)
					fclose(fp);
				ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_OS, "Error writing to a local file\n");
				if (!isKeepPartial)
				{
					if (unlink(pLocalFile))
						ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Could not remove partial file %s\n", pLocalFile);
				}
				ExitWithError(oraAllInOne, RET_FS, ERROR_NONE, 0);
			}
		}
		while (zStrm.avail_out == 0);

		if (ociResult == OCI_SUCCESS)
			break;
		ociResult = OCILobRead2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE, OCI_NEXT_PIECE, 0, 0, 0, 0);
	}

#ifndef _WIN32
	if (showProgress)
		stop_progress_meter();
#endif
	inflateEnd(&zStrm);
	if (!isStdUsed)
		fclose(fp);

	if (ociResult != OCI_SUCCESS)
	{
		ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error reading BLOB\n");
	}

	ReleaseStmt(oraAllInOne);
	SetSessionAction(oraAllInOne, 0);

	OCILobFreeTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob);

	if (OCIDescriptorFree(oraAllInOne->blob, OCI_DTYPE_LOB))
	{
		ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to free BLOB\n");
	}
	oraAllInOne->blob = 0;
}

void UploadFileWithCompression(struct ORACLEALLINONE *oraAllInOne, char* pDirectory,
                               int compressionLevel, char* pRemoteFile, char* pLocalFile,
                               int isKeepPartial, int isResume)
{
	FILE *fp;
	sword ociResult;
	char blobBuffer[ORA_BLOB_BUFFER_SIZE];
	oraub8 vSize;
	ub8 vSkippedBytes;
	char vOpenMode[3];
	ub1 piece;
	int zRet, zFlush;
	z_stream zStrm;
	unsigned char zIn[ORA_BLOB_BUFFER_SIZE];
#ifndef _WIN32
	int showProgress;
	char progressLine[MAX_FMT_SIZE];
#endif
	int isStdUsed;
	off_t cnt;
	off_t sourceSize;
	struct stat fileStat;
	int isError;
	struct ORACLEFILEATTR oracleFileAttr;

	struct BINDVARIABLE oraBindsUpload[] =
	{
		{ 0, SQLT_STR,  ":directory", pDirectory,         ORA_IDENTIFIER_SIZE + 1   },
		{ 0, SQLT_STR,  ":filename",  pRemoteFile,        MAX_FMT_SIZE              },
		{ 0, SQLT_STR,  ":openmode",  vOpenMode,          sizeof(vOpenMode)         },
		{ 0, SQLT_INT,  ":file_size", &sourceSize,        sizeof(sourceSize)        },
		{ 0, SQLT_INT,  ":skipped",   &vSkippedBytes,     sizeof(vSkippedBytes)     },
		{ 0, SQLT_BLOB, ":blob",      &oraAllInOne->blob, sizeof(oraAllInOne->blob) },
		{ 0 }
	};

	struct ORACLESTATEMENT oraStmtUpload = {
#include "uploadcompr.text"
,
		0, oraBindsUpload, NO_ORACLE_DEFINES };

	isStdUsed = !strcmp(pLocalFile, "-");
	if (isStdUsed)
		isResume = 0;

	SetSessionAction(oraAllInOne, "UPLOAD_AND_GUNZIP: UPLOAD");
	if (OCIDescriptorAlloc(oraAllInOne->envhp, (void**)&oraAllInOne->blob, OCI_DTYPE_LOB, 0, 0))
	{
		ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to allocate BLOB\n");
	}

	if (OCILobCreateTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, OCI_DEFAULT, 0, OCI_TEMP_BLOB, TRUE/*cache*/, OCI_DURATION_SESSION))
	{
		ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Failed to create temporary BLOB\n");
	}

	piece = OCI_FIRST_PIECE;

#ifndef _WIN32
	showProgress = 1;
	if (!isatty(STDOUT_FILENO) || isStdUsed)
		showProgress = 0;
#endif

	cnt = vSkippedBytes = 0;
	if (isResume)
	{
		GetOracleFileAttr(oraAllInOne, pDirectory, pRemoteFile, &oracleFileAttr);
		if (oracleFileAttr.bExists)
			cnt = vSkippedBytes = oracleFileAttr.length;
		if (!cnt)
			isResume = 0;
	}

#ifndef _WIN32
	if (showProgress)
	{
		stat(pLocalFile, &fileStat);
		sourceSize = fileStat.st_size;
		strcpy(progressLine, "GZIP & TRANSFER: ");
		strncat(progressLine, basename(pLocalFile), MAX_FMT_SIZE - 1 - strlen(progressLine));
		start_progress_meter(progressLine, sourceSize, &cnt);
	}
#endif

	if (!isStdUsed && (fp = fopen(pLocalFile, "rb")) == NULL)
	{
		ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error opening a local file for reading\n");
	}
	if (isStdUsed)
		fp = stdin;

	if (cnt > 0)
	{
		if (fseek(fp, cnt, SEEK_SET))
		{
			fclose(fp);
			ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error setting reading position in a local file\n");
		}
	}

	zStrm.zalloc = Z_NULL;
	zStrm.zfree = Z_NULL;
	zStrm.opaque = Z_NULL;

	zRet = deflateInit2(&zStrm, compressionLevel ? compressionLevel : Z_DEFAULT_COMPRESSION, Z_DEFLATED, 16+MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
	if (zRet != Z_OK)
	{
		if (!isStdUsed)
			fclose(fp);
		ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB initialization failed\n");
	}

	while (!feof(fp))
	{
		zStrm.avail_in = fread(zIn, sizeof(unsigned char), sizeof(zIn), fp);
		cnt += zStrm.avail_in;
		if (ferror(fp))
		{
			(void)deflateEnd(&zStrm);
			if (!isStdUsed)
				fclose(fp);
			ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error reading from a local file\n");
		}

		zFlush = feof(fp) ? Z_FINISH : Z_NO_FLUSH;
		zStrm.next_in = zIn;

		do
		{
			zStrm.avail_out = ORA_BLOB_BUFFER_SIZE;
			zStrm.next_out = blobBuffer;
			zRet = deflate(&zStrm, zFlush);
			if (zRet != Z_OK && zRet != Z_STREAM_END && zRet != Z_BUF_ERROR)
			{
				(void)deflateEnd(&zStrm);
				if (!isStdUsed)
					fclose(fp);
				ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB deflate failed: %d, size %d\n", zRet, zStrm.avail_in);
			}

			if (zRet == Z_STREAM_END)
				piece = (piece == OCI_FIRST_PIECE) ? OCI_ONE_PIECE : OCI_LAST_PIECE;

			vSize = (piece == OCI_ONE_PIECE) ? ORA_BLOB_BUFFER_SIZE - zStrm.avail_out : 0;
			if (zStrm.avail_out == ORA_BLOB_BUFFER_SIZE)
				continue;
			ociResult = OCILobWrite2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE - zStrm.avail_out, piece, 0, 0, 0, 0);
			if (ociResult != OCI_NEED_DATA && ociResult)
			{
				(void)deflateEnd(&zStrm);
				if (!isStdUsed)
					fclose(fp);
				ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error writing to BLOB\n");
			}
			if (piece == OCI_FIRST_PIECE)
				piece = OCI_NEXT_PIECE;
		}
		while (zStrm.avail_out == 0);
	}

#ifndef _WIN32
	if (showProgress)
		stop_progress_meter();
#endif
	deflateEnd(&zStrm);
	if (!isStdUsed)
		fclose(fp);

	isError = 0;
        strcpy(vOpenMode, isResume ? "ab" : "wb");
	SetSessionAction(oraAllInOne, "UPLOAD_AND_GUNZIP: GUNZIP");

#ifndef _WIN32
	if (showProgress)
		start_longops_meter(oraAllInOne, 0, 1);
#endif

	PrepareStmtAndBind(oraAllInOne, &oraStmtUpload);
	ociResult = ExecuteStmt(oraAllInOne);
#ifndef _WIN32
	if (showProgress)
		stop_longops_meter();
#endif
	if (ociResult)
	{
		ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_OCI, "Failed to decompress file in oracle directory\n");
		isError = 1;
	}
	else
		ReleaseStmt(oraAllInOne);
	SetSessionAction(oraAllInOne, 0);

	OCILobFreeTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob);

	if (OCIDescriptorFree(oraAllInOne->blob, OCI_DTYPE_LOB))
	{
		if (!isError)
			ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_NONE, "Failed to free BLOB\n");
		isError = 1;
	}
	oraAllInOne->blob = 0;

	if (isError)
	{
		if (!isKeepPartial)
			Rm(oraAllInOne, pDirectory, pRemoteFile);
		ExitWithError(oraAllInOne, RET_ORA, ERROR_NONE, 0);
	}
}
Beispiel #22
0
SqlRid::~SqlRid()
{
	sword res = OCICALL(OCIDescriptorFree(_rid, OCI_DTYPE_ROWID));
	oci_check_error(__TROTL_HERE__, _env, res);
};