Example #1
0
/*
 * Send an SQL query to the server
 */
static int db_oracle_submit_query(const db_con_t* _h, const str* _s)
{
	OCIBind* bind[MAX_BIND_HANDLES];
	OCIDate odt[sizeof(bind)/sizeof(bind[0])];
	str tmps;
	sword status;
	int pass;
	ora_con_t* con = CON_ORA(_h);
	query_data_t* pqd = con->pqdata;
	size_t hc = pqd->_n + pqd->_nw;
	OCIStmt *stmthp;

	if (hc >= sizeof(bind)/sizeof(bind[0])) {
		LM_ERR("too many bound. Rebuild with MAX_BIND_HANDLES >= %u\n",
			(unsigned)hc);
		return -1;
	}

	if (!pqd->_rs) {
		/*
		 * This method is at ~25% faster as set OCI_COMMIT_ON_SUCCESS
		 * in StmtExecute
		 */
		tmps.len = snprintf(st_buf, sizeof(st_buf),
			"begin %.*s; commit write batch nowait; end;",
			_s->len, _s->s);
		if ((unsigned)tmps.len >= sizeof(st_buf))
			return sql_buf_small();
		tmps.s = st_buf;
		_s = &tmps;
	}

	pass = 1;
	if (!con->connected) {
		status = db_oracle_reconnect(con);
		if (status != OCI_SUCCESS) {
			LM_ERR("can't restore connection: %s\n", db_oracle_error(con, status));
			return -2;
		}
		LM_INFO("connection restored\n");
		--pass;
	}
repeat:
	stmthp = NULL;
	status = OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&stmthp,
		    OCI_HTYPE_STMT, 0, NULL);
	if (status != OCI_SUCCESS)
		goto ora_err;
	status = OCIStmtPrepare(stmthp, con->errhp, (text*)_s->s, _s->len,
		OCI_NTV_SYNTAX, OCI_DEFAULT);
	if (status != OCI_SUCCESS)
		goto ora_err;

	if (hc) {
		bmap_t bmap;
		size_t pos = 1;
		int i;

		memset(bind, 0, hc*sizeof(bind[0]));
		for (i = 0; i < pqd->_n; i++) {
			if (db_oracle_val2bind(&bmap, &pqd->_v[i], &odt[pos]) < 0)
				goto bind_err;
			status = OCIBindByPos(stmthp, &bind[pos], con->errhp,
				pos, bmap.addr, bmap.size, bmap.type,
				NULL, NULL, NULL, 0, NULL, OCI_DEFAULT);
			if (status != OCI_SUCCESS)
				goto ora_err;
			++pos;
		}
		for (i = 0; i < pqd->_nw; i++) {
			if (db_oracle_val2bind(&bmap, &pqd->_w[i], &odt[pos]) < 0) {
bind_err:
				OCIHandleFree(stmthp, OCI_HTYPE_STMT);
				LM_ERR("can't map values\n");
				return -3;
			}
			status = OCIBindByPos(stmthp, &bind[pos], con->errhp,
				pos, bmap.addr, bmap.size, bmap.type,
				NULL, NULL, NULL, 0, NULL, OCI_DEFAULT);
			if (status != OCI_SUCCESS)
				goto ora_err;
			++pos;
		}
	}

	// timelimited operation
	status = begin_timelimit(con, 0);
	if (status != OCI_SUCCESS) goto ora_err;
	do status = OCIStmtExecute(con->svchp, stmthp, con->errhp,
		!pqd->_rs, 0, NULL, NULL,
		pqd->_rs ? OCI_STMT_SCROLLABLE_READONLY : OCI_DEFAULT);
	while (wait_timelimit(con, status));
	if (done_timelimit(con, status)) goto stop_exec;
	switch (status)	{
	case OCI_SUCCESS_WITH_INFO:
		LM_WARN("driver: %s\n", db_oracle_errorinfo(con));
		//PASS THRU
	case OCI_SUCCESS:
		if (pqd->_rs)
			*pqd->_rs = stmthp;
		else
			OCIHandleFree(stmthp, OCI_HTYPE_STMT);
		return 0;
	default:
	    pass = -pass;
	    break;
	}

ora_err:
	LM_ERR("driver: %s\n", db_oracle_error(con, status));
stop_exec:
	if (stmthp)
		OCIHandleFree(stmthp, OCI_HTYPE_STMT);
	if (pass == -1 && !con->connected) {
		/* Attemtp to reconnect */
		if (db_oracle_reconnect(con) == OCI_SUCCESS) {
			LM_NOTICE("attempt repeat after reconnect\n");
			pass = 0;
			goto repeat;
		}
		LM_ERR("connection loss\n");
	}
	return -4;
}
Example #2
0
bool COracleRecordset::Init(COracleConnection *parent, OCIStmt *hStmt, bool select)
{
	sb4 status;
	int is_string_data=0;
	m_bEof = false;
	m_parent = parent;
	m_hStmt = hStmt;

	if (select)
	{
	CServerIo::trace(3,"COracleRecordset::Init -  OCIStmtExecute(Describe_Only,select=%d)",select?0:1);
	status=OCIStmtExecute(parent->m_hSvcCtx, hStmt, parent->m_hErr, select?0:1, 0, NULL, NULL, OCI_DESCRIBE_ONLY);
	} else {
	CServerIo::trace(3,"COracleRecordset::Init -  OCIStmtExecute(%s,select=%d)",parent->m_bAutoCommit?"OCI_COMMIT_ON_SUCCESS":"OCI_DEFAULT",select?0:1);
	status=OCIStmtExecute(parent->m_hSvcCtx, hStmt, parent->m_hErr, select?0:1, 0, NULL, NULL, parent->m_bAutoCommit?OCI_COMMIT_ON_SUCCESS:OCI_DEFAULT);
	}
	CServerIo::trace(3,"COracleRecordset::Init -  CheckError(%d)",(int)status);
	if(!parent->CheckError(parent->m_hErr,status))
		return false;

	CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_PARAM_COUNT)");
	status=OCIAttrGet(hStmt, OCI_HTYPE_STMT, &m_num_fields, 0, OCI_ATTR_PARAM_COUNT, parent->m_hErr);
	CServerIo::trace(3,"COracleRecordset::Init -  CheckError(%d) m_num_fields=%d",(int)status,(int)m_num_fields);
	if(!parent->CheckError(parent->m_hErr,status))
		return false;

	CServerIo::trace(3,"COracleRecordset::Init -  resize");
	m_sqlfields.resize(m_num_fields);
	CServerIo::trace(3,"COracleRecordset::Init -  for loop");
	for(size_t n=0; n<m_num_fields; n++)
	{
		OCIParam *hParam;
		wchar_t szCol[128];
		ub4 ubCol = sizeof(szCol);
		unsigned char *szaColPtr;
		ub4 ubaCol = 0;

		CServerIo::trace(3,"COracleRecordset::Init -  for loop %d",(int)n);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIParamGet(OCI_HTYPE_STMT) n==%d",n+1);
		OCIParamGet(hStmt, OCI_HTYPE_STMT, parent->m_hErr, (void**)&hParam, n+1);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_DATA_TYPE)");
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].type, NULL, OCI_ATTR_DATA_TYPE, parent->m_hErr);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_TYPECODE)");
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].typecode, NULL, OCI_ATTR_TYPECODE, parent->m_hErr);
		switch (m_sqlfields[n].type) {
		case OCI_TYPECODE_REF:
			CServerIo::trace(3,"  - TYPECODE REF");
			break;
		case OCI_TYPECODE_DATE:
			CServerIo::trace(3,"  - TYPECODE DATE");
			break;
		case OCI_TYPECODE_REAL:
			CServerIo::trace(3,"  - TYPECODE REAL");
			break;
		case OCI_TYPECODE_DOUBLE:
			CServerIo::trace(3,"  - TYPECODE DOUBLE");
			break;
		case OCI_TYPECODE_FLOAT:
			CServerIo::trace(3,"  - TYPECODE FLOAT");
			break;
		case OCI_TYPECODE_NUMBER:
			CServerIo::trace(3,"  - TYPECODE NUMBER");
			break;
		case OCI_TYPECODE_DECIMAL:
			CServerIo::trace(3,"  - TYPECODE DECIMAL");
			break;
		case OCI_TYPECODE_OCTET:
			CServerIo::trace(3,"  - TYPECODE OCTET");
			break;
		case OCI_TYPECODE_INTEGER:
			CServerIo::trace(3,"  - TYPECODE INTEGER");
			break;
		case OCI_TYPECODE_SMALLINT:
			CServerIo::trace(3,"  - TYPECODE SMALLINT");
			break;
		case OCI_TYPECODE_RAW:
			CServerIo::trace(3,"  - TYPECODE RAW");
			break;
		case OCI_TYPECODE_VARCHAR2:
			CServerIo::trace(3,"  - TYPECODE VARCHAR2");
			break;
		case OCI_TYPECODE_VARCHAR:
			CServerIo::trace(3,"  - TYPECODE VARCHAR");
			break;
		case OCI_TYPECODE_CHAR:
			CServerIo::trace(3,"  - TYPECODE CHAR");
			break;
		case OCI_TYPECODE_VARRAY:
			CServerIo::trace(3,"  - TYPECODE VARRAY");
			break;
		case OCI_TYPECODE_TABLE:
			CServerIo::trace(3,"  - TYPECODE TABLE");
			break;
		case OCI_TYPECODE_CLOB:
			CServerIo::trace(3,"  - TYPECODE CLOB");
			break;
		case OCI_TYPECODE_BLOB:
			CServerIo::trace(3,"  - TYPECODE BLOB");
			break;
		case OCI_TYPECODE_BFILE:
			CServerIo::trace(3,"  - TYPECODE BFILE");
			break;
		case OCI_TYPECODE_OBJECT:
			CServerIo::trace(3,"  - TYPECODE OBJECT");
			break;
		case OCI_TYPECODE_NAMEDCOLLECTION:
			CServerIo::trace(3,"  - TYPECODE NAMED COLL.");
			break;
		default:
			CServerIo::trace(3,"  - TYPECODE unknown");
		}
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_NAME)");
		szaColPtr=NULL;
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, (void**)&szaColPtr, &ubaCol, OCI_ATTR_NAME, parent->m_hErr);
		if (szaColPtr!=NULL)
		CServerIo::trace(3,"  - ATTR_NAME %s (%d).",szaColPtr,(int)ubaCol);
		else
		CServerIo::trace(3,"  - ATTR_NAME NULL (%d).",(int)ubaCol);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_PRECISION)");
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].precision, NULL, OCI_ATTR_PRECISION, parent->m_hErr);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_SCALE)");
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].scale, NULL, OCI_ATTR_SCALE, parent->m_hErr);
		CServerIo::trace(3,"COracleRecordset::Init -  OCIAttrGet(OCI_ATTR_DATA_SIZE)");
		OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].size, NULL, OCI_ATTR_DATA_SIZE, parent->m_hErr);
		CServerIo::trace(3,"  - ATTR_DATA_SIZE %d.",(int)m_sqlfields[n].size);

		m_sqlfields[n].field = n;
		m_sqlfields[n].hStmt = m_hStmt;
		m_sqlfields[n].name = cvs::wide((char *)szaColPtr);

		switch(m_sqlfields[n].type)
		{
		case OCI_TYPECODE_REAL:
		case OCI_TYPECODE_FLOAT:
		case OCI_TYPECODE_DOUBLE:
			CServerIo::trace(3," ::Init -  OCI_TYPECODE_REAL");
			m_sqlfields[n].fldtype=SQLT_FLT;
			m_sqlfields[n].fldlen=sizeof(double);
			break;
		case OCI_TYPECODE_OCTET:
		case OCI_TYPECODE_INTEGER:
		case OCI_TYPECODE_SMALLINT:
			CServerIo::trace(3," ::Init -  OCI_TYPECODE_OCTET");
			m_sqlfields[n].fldtype=SQLT_INT;
			m_sqlfields[n].fldlen=sizeof(int);
			break;
		case OCI_TYPECODE_NUMBER:
			CServerIo::trace(3," ::Init -  OCI_TYPECODE_NUMBER");
			if(m_sqlfields[n].precision)
			{
				m_sqlfields[n].fldtype=SQLT_FLT;
				m_sqlfields[n].fldlen=sizeof(double);
			}
			else
			{
				m_sqlfields[n].fldtype=SQLT_INT;
				m_sqlfields[n].fldlen=sizeof(int);
			}
			break;
		case OCI_TYPECODE_VARCHAR2:
		case OCI_TYPECODE_VARCHAR:
		case OCI_TYPECODE_CHAR:
		case OCI_TYPECODE_CLOB:
		case OCI_TYPECODE_BLOB:
		case OCI_TYPECODE_DATE:
			CServerIo::trace(3," ::Init -  OCI_TYPECODE_VARCHAR2");
			m_sqlfields[n].fldtype=SQLT_STR;
			m_sqlfields[n].fldlen=m_sqlfields[n].size+1;
			is_string_data=1;
			break;
		case OCI_TYPECODE_REF:
		case OCI_TYPECODE_RAW:
		case OCI_TYPECODE_VARRAY:
		case OCI_TYPECODE_TABLE:
		case OCI_TYPECODE_BFILE:
		case OCI_TYPECODE_OBJECT:
		case OCI_TYPECODE_NAMEDCOLLECTION:
		default:
			CServerIo::trace(3," ::Init -  Unsuppoered datatype");
			//CServerIo::error("Field type %d unsupported for field %s\n",m_sqlfields[n].type,(const char *)cvs::narrow(szCol));
			CServerIo::error("Field type %d unsupported for field %s\n",m_sqlfields[n].type,szaColPtr);
			return false;
		}

		CServerIo::trace(3," ::Init -  end of datatype");
		if(m_sqlfields[n].fldlen)
		{
			OCIDefine *hDef = NULL;
			CServerIo::trace(3," ::Init -  m_sqlfields[n].fldlen=%d",(int)m_sqlfields[n].fldlen);

			if ((m_sqlfields[n].fldtype==SQLT_STR) ||
			    (is_string_data))
			{
			// the result of the OCI DefineByPos is a buffer of 
			// characters.  We could leave just that but
			// this (incorrectly?) assumes the OCI client is
			// going to present this data as UTF8.  In truth
			// it is based on the bind OCI_HTYPE_BIND attribute 
			// OCI_ATTR_CHARSET_ID
			CServerIo::trace(3," ::Init -  OCIAttrGet(OCI_ATTR_CHARSET_ID)");
			OCIAttrGet(hParam, OCI_DTYPE_PARAM, &m_sqlfields[n].csid, NULL, OCI_ATTR_CHARSET_ID, parent->m_hErr);
			if (m_sqlfields[n].csid == OCI_UCS2ID)
				CServerIo::trace(3," ::Init -  UCS2 Charset");
			if (m_sqlfields[n].csid == 2000 /* OCI_UTF16ID */)
				CServerIo::trace(3," ::Init -  UTF16 Charset");
			else
				CServerIo::trace(3," ::Init -  Charset %d (not UCS2)",(int)m_sqlfields[n].csid);
			/* The only valid handle types for setting charset are:
			  Bind Handle 
			  Define Handle
			  Direct Path Loading Handle
			  Direct Path Column Parameter
			  */
			/*
			CServerIo::trace(3,"COracleRecordset::Init -  OCIParamGet(OCI_DTYPE_PARM)");
			OCIParamGet(hParam, OCI_DTYPE_PARM, parent->m_hErr, (void **)&hColDesc, 1);
			  
			CServerIo::trace(3," ::Init - Force Direct Path Loading Handle to UCS2 Charset");
			m_sqlfields[n].csid=OCI_UCS2ID;
			status=OCIAttrSet((void *)hColDesc, OCI_DTYPE_PARAM,(void *)&m_sqlfields[n].csid,0,OCI_ATTR_CHARSET_ID,parent->m_hErr);
			CServerIo::trace(3," ::Init - Force Direct Path Loading Handle to UCS2 Charset (%d)",(int)status);
			if(!parent->CheckError(parent->m_hErr,status)
				CServerIo::trace(1,"Unable to set UCS2 character set \"%s\".",parent->ErrorString());
			OCIDescriptorFree((dvoid *)hColDesc, OCI_DTYPE_PARAM));
			*/
			}
			
			m_sqlfields[n].data = malloc((m_sqlfields[n].fldlen+2)+(is_string_data)?m_sqlfields[n].fldlen+2:0);
			memset(m_sqlfields[n].data,0,m_sqlfields[n].fldlen+(is_string_data)?m_sqlfields[n].fldlen+2:0);
			CServerIo::trace(3," ::Init -  OCIDefineByPos()");
			m_sqlfields[n].datalen[0]=0 /*m_sqlfields[n].fldlen*/ ;
			status=OCIDefineByPos(m_hStmt,&hDef,parent->m_hErr,n+1,(void **)m_sqlfields[n].data,m_sqlfields[n].fldlen,m_sqlfields[n].fldtype,0,(unsigned short *)&m_sqlfields[n].datalen,0,OCI_DEFAULT);
			CServerIo::trace(3," ::Init -  OCIDefineByPos()=%d,%d",status,(int)m_sqlfields[n].datalen[0]);
			if(!parent->CheckError(parent->m_hErr,status))
			{
				CServerIo::trace(1,"Unable to bind column %s due to error \"%s\".",(const char*)szaColPtr,parent->ErrorString());
				return false;
			}
			if (is_string_data)
			{
			  if (m_sqlfields[n].csid<OCI_UCS2ID)
			  {
			    m_sqlfields[n].csid=OCI_UCS2ID;
			    CServerIo::trace(3," ::Init - Define Handle to UCS2 Charset");
			    status=OCIAttrSet((void *)hDef, OCI_HTYPE_DEFINE,(void *)&m_sqlfields[n].csid,0,OCI_ATTR_CHARSET_ID,parent->m_hErr);
			    CServerIo::trace(3," ::Init - Define Handle to UCS2 Charset (%d)",(int)status);
			    if(!parent->CheckError(parent->m_hErr,status))
				CServerIo::trace(1,"Unable to set UCS2 character set \"%s\".",parent->ErrorString());
			  }
			}
			/*
			szaColPtr=NULL; ubaCol=0;
			OCIAttrGet(hParam,  OCI_HTYPE_DEFINE, (void**)&szaColPtr, &ubaCol, OCI_ATTR_NAME, parent->m_hErr);
			if (szaColPtr!=NULL)
			{
			CServerIo::trace(3,"  - ATTR_NAME (Define Handle) %s (%d).",szaColPtr,(int)ubaCol);
			m_sqlfields[n].name = cvs::wide((char *)szaColPtr);
			}
			else
			CServerIo::trace(3,"  - ATTR_NAME (Define Handle) NULL (%d).",(int)ubaCol);
			*/

			CServerIo::trace(3," ::Init -  complete");
		}
	}

	if (select)
	{
	CServerIo::trace(3,"COracleRecordset::Init -  OCIStmtExecute(%s,select=%d)",parent->m_bAutoCommit?"OCI_COMMIT_ON_SUCCESS":"OCI_DEFAULT",select?0:1);
	status=OCIStmtExecute(parent->m_hSvcCtx, hStmt, parent->m_hErr, select?0:1, 0, NULL, NULL, parent->m_bAutoCommit?OCI_COMMIT_ON_SUCCESS:OCI_DEFAULT);
	CServerIo::trace(3,"COracleRecordset::Init -  CheckError(%d)",(int)status);
	if(!parent->CheckError(parent->m_hErr,status))
		return false;
	}

	if(m_num_fields)
	{
		CServerIo::trace(3," ::Init -  m_num_fields=%d",(int)(m_num_fields));
		if(!Next() && !m_bEof)
			return false;
	}

	CServerIo::trace(3," ::Init -  return");
	return true;
}
Example #3
0
/*
 * Add a new status change to the database
 * Params:
 *  session	- user session name
 *  uid		- uid of person changing status
 *  status	- type of new status (away|back|...)
 *  descr	- new description
 *  change_time - time of status change (no. of seconds since 1st Jan 1970)
 *  quiet	- print error messages or not
 * Returns 0 on success.
 */
int oralog_db_new_status(char *session, char *uid, char *status, char *descr, time_t change_time, int quiet)
{
	OCIStmt	  *hp_stmt = NULL;     /* SQL statement handle */
	OCIBind	  *bind[5] = { NULL }; /* Needed for C-var to SQL-var binding */	
	sword	  retstat  = 0;        /* Return value of function */
	int	  errors   = 0;        /* Error counter */
	uword	  invalid  = 0;        /* for DateCheck() */
	OCIDate   oci_date;	       /* for 'change_time' - oracle internal representation */
	struct tm *tm_chtime = NULL;   /* for 'change_time' - standard C representation */
	
	int	  print_errors = (quiet) ? 0 : 1; /* if nonzero then print errors into status window */
	OCIError  *hp_error   = NULL;		  /* oci error handle */
	
	/* SQL statement to execute */
	text	*sqlstmt = (text *) "INSERT INTO status_changes VALUES( status_changes_seq.nextval, :session_uid, :changes_uid, :status, :descr, :change_time)";


	pthread_mutex_lock(&oralog_oper_lock);

	if (!oralog_is_connected()) {
		debug("[logsoracle] can't log status - not connected\n");
		
		pthread_mutex_unlock(&oralog_oper_lock);
		return 1;
	}


	check_string_len(session);
	check_string_len(uid);
	check_string_len(status);
	check_string_len(descr);


	/* Create local handles (OCIBind's are created automaticly) */
	OCIHandleAlloc( (dvoid *)hp_env, (dvoid **)&hp_stmt, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
	OCIHandleAlloc( (dvoid *)hp_env, (dvoid **)&hp_error, OCI_HTYPE_ERROR, 0, (dvoid **) 0);

	/* Create DATE */
	tm_chtime = localtime(&change_time);
	
	memset(&oci_date, 0, sizeof(OCIDate));
	OCIDateSetTime( &oci_date, (ub1)tm_chtime->tm_hour, (ub1)tm_chtime->tm_min, (ub1)tm_chtime->tm_sec ); 
	OCIDateSetDate( &oci_date, (sb2)tm_chtime->tm_year+1900, (ub1)tm_chtime->tm_mon+1, (ub1)tm_chtime->tm_mday );


	/* check if provided 'change_time' was mapped correctly  */
	retstat = OCIDateCheck(hp_error, &oci_date, &invalid);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
			

	/* prepare SQL statement */	
	debug("[logsoracle] preparing new status statement\n");
	retstat = OCIStmtPrepare(hp_stmt, hp_error, (text *)sqlstmt, (ub4)ora_strlen((char *)sqlstmt), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;


	/* bind variables */
	debug("[logsoracle] binding..\n");

	retstat = OCIBindByName(hp_stmt, &bind[0], hp_error, (text *) ":session_uid", -1, (dvoid *)session,
				ora_strlen(session)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;	

				
	retstat = OCIBindByName(hp_stmt, &bind[1], hp_error, (text *) ":changes_uid",
				-1, (dvoid *) uid,
				ora_strlen(uid)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;				


	retstat = OCIBindByName(hp_stmt, &bind[2], hp_error, (text *) ":status",
				-1, (dvoid *) status,
				ora_strlen(status)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;

				
	retstat = OCIBindByName(hp_stmt, &bind[3], hp_error, (text *) ":descr",
				-1, (dvoid *) descr,
				ora_strlen(descr)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;


	/* Oracle type DATE can be easily bind by using OCIDate struct and SQLT_ODT datatype */					   
	retstat = OCIBindByName(hp_stmt, &bind[4], hp_error, (text *) ":change_time",
				-1, (dvoid *) &oci_date,
				(sword) sizeof(OCIDate), SQLT_ODT, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
						


	/* Statement ready - execute */
	debug("[logsoracle] executing\n");
	retstat = OCIStmtExecute(hp_service, hp_stmt, hp_error, (ub4) 1, (ub4) 0,
				(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;


	/* Commit transaction */
	if(!errors) {
		debug("[logsoracle] commit\n");
		OCITransCommit(hp_service, hp_error, (ub4) 0);
	}
	else {
		debug("[logsoracle] errors present - aborting transaction\n");
		OCITransRollback(hp_service, hp_error, (ub4) OCI_DEFAULT);
	}
					
	/* Cleanup (bind handles should be removed as a part of statement) */	
	if(hp_stmt)
	    OCIHandleFree(hp_stmt, OCI_HTYPE_STMT);	
	if(hp_error)
	    OCIHandleFree(hp_error, OCI_HTYPE_ERROR);
	
	pthread_mutex_unlock(&oralog_oper_lock);
	return 0;
}
Example #4
0
/*
 * Add a new message to the database.
 *  session    - session name
 *  sender_uid -
 *  rcpts      -
 *  content    -
 *  recv_time  - time of arrival
 *  quiet      - print error messages?
 * Returns 0 on success
 */
int oralog_db_new_msg(char *session, char *sender_uid, char **rcpts, char *content, time_t recv_time, int quiet)
{
	int i;

	/* There will be at least 2 INSERTs - 1 into 'messages' table and 1 (at least)
	   into the 'recipients' table. */
	text	*sqlstmt_msg  = (text *)"INSERT INTO messages VALUES(messages_seq.nextval, :session_uid, :sender_uid, :content, :recv_time) RETURNING id INTO :msg_id";
	text	*sqlstmt_rcp  = (text *)"INSERT INTO recipients VALUES(recipients_seq.nextval, :recipient_uid, :msg_id)";

	/* Statement & bind handles */
	OCIStmt *hp_stmt_msg = NULL;
	OCIStmt *hp_stmt_rcp = NULL;
	OCIBind *bind_msg[5] = { NULL };
	OCIBind *bind_rcp[2] = { NULL };

	/* Control vars */
	sword	 retstat  = 0;
	int	 errors   = 0;
	int	 print_errors = (quiet) ? 0 : 1;
	OCIError *hp_error = NULL;

	/* Date handling */
	uword	  invalid = 0;
	OCIDate   oci_recvtime;
	struct tm *tm_recvtime = NULL;		
	
	/* ID of inserted message will be put here */
	OCINumber msg_id;
	int	  init_val = 0;	/* this variable is needed for initialization only */
	

	pthread_mutex_lock(&oralog_oper_lock);
	
	if (!oralog_is_connected()) {
		debug("[logsoracle] can't log msg - not connected\n");
		
		pthread_mutex_unlock(&oralog_oper_lock);
		return 1;
	}


	check_string_len(session);
	check_string_len(sender_uid);
	check_string_len(content);

	/* Create local handles (OCIBind's are created automaticly) */
	OCIHandleAlloc( (dvoid *)hp_env, (dvoid **)&hp_stmt_msg, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
	OCIHandleAlloc( (dvoid *)hp_env, (dvoid **)&hp_stmt_rcp, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
	OCIHandleAlloc( (dvoid *)hp_env, (dvoid **)&hp_error, OCI_HTYPE_ERROR, 0, (dvoid **) 0);	
	
	/* Create DATE in Oracle format */
	tm_recvtime = localtime(&recv_time);
		
	memset(&oci_recvtime, 0, sizeof(OCIDate));
	OCIDateSetTime( &oci_recvtime, (ub1)tm_recvtime->tm_hour, (ub1)tm_recvtime->tm_min, (ub1)tm_recvtime->tm_sec );
	OCIDateSetDate( &oci_recvtime, (sb2)tm_recvtime->tm_year+1900, (ub1)tm_recvtime->tm_mon+1, (ub1)tm_recvtime->tm_mday );

	/* check if provided 'recv_time' was mapped correctly  */
	retstat = OCIDateCheck(hp_error, &oci_recvtime, &invalid);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;

	/* prepare SQL statements */
	debug("[logsoracle] preparing new messages insert statement\n");
	retstat = OCIStmtPrepare(hp_stmt_msg, hp_error, (text *)sqlstmt_msg, (ub4)ora_strlen((char *)sqlstmt_msg), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;	 

	debug("[logsoracle] preparing new recipients insert statement\n");
	retstat = OCIStmtPrepare(hp_stmt_rcp, hp_error, (text *)sqlstmt_rcp, (ub4)ora_strlen((char *)sqlstmt_rcp), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
 

	/* bind the placeholders */
	debug("[logsoracle] binding messages insert..\n");
	   
	retstat = OCIBindByName(hp_stmt_msg, &bind_msg[0], hp_error, (text *) ":session_uid", -1, (dvoid *)session,
				ora_strlen(session)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;

	retstat = OCIBindByName(hp_stmt_msg, &bind_msg[1], hp_error, (text *) ":sender_uid", -1, (dvoid *)sender_uid,
				ora_strlen(sender_uid)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;									    

	retstat = OCIBindByName(hp_stmt_msg, &bind_msg[2], hp_error, (text *) ":content", -1, (dvoid *)content,
				ora_strlen(content)+1, SQLT_STR, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
	 
	retstat = OCIBindByName(hp_stmt_msg, &bind_msg[3], hp_error, (text *) ":recv_time",
				-1, (dvoid *) &oci_recvtime,
				(sword) sizeof(OCIDate), SQLT_ODT, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;	 
	

	/* Create a new OCINumber - will be under msg_id */
	retstat = OCINumberFromInt(hp_error, &init_val, sizeof(init_val), OCI_NUMBER_SIGNED, &msg_id);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
		
	
	/* bind the OCINumber */
	retstat = OCIBindByName(hp_stmt_msg, &bind_msg[4], hp_error, (text *) ":msg_id",
				-1, (dvoid *) &msg_id,
				(sword) sizeof(msg_id), SQLT_VNU, (dvoid *) 0,
				(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;
															 

	/* Statement ready - execute */
	debug("[logsoracle] executing insert on messages\n");
	retstat = OCIStmtExecute(hp_service, hp_stmt_msg, hp_error, (ub4) 1, (ub4) 0,
				(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;

	/* You can check recieved message ID like this:
	retstat = OCINumberToInt(hp_error, &msg_id, sizeof(int), OCI_NUMBER_SIGNED, &tmpval);
	if(oralog_is_error(hp_error, retstat, print_errors))
	 errors++;	
	debug("[logsoracle] recieved message id: %d\n", tmpval);
	*/
	
	/* Insert into recipients table */
	if(rcpts) {
	    for(i=0; rcpts[i] != NULL; i++) {
		
		check_string_len(rcpts[i]);
		
		debug("[logsoracle] binding recipients\n");
		retstat = OCIBindByName(hp_stmt_rcp, &bind_rcp[0], hp_error, (text *) ":recipient_uid", -1, (dvoid *)rcpts[i],
					ora_strlen(rcpts[i])+1, SQLT_STR, (dvoid *) 0,
					(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
		if(oralog_is_error(hp_error, retstat, print_errors))
		 errors++;	    
	    
	    
		retstat = OCIBindByName(hp_stmt_rcp, &bind_rcp[1], hp_error, (text *) ":msg_id",
					-1, (dvoid *) &msg_id,
					(sword) sizeof(msg_id), SQLT_VNU, (dvoid *) 0,
					(ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
		if(oralog_is_error(hp_error, retstat, print_errors))
		 errors++;
		
		debug("[logsoracle] executing insert on recipients\n");
		retstat = OCIStmtExecute(hp_service, hp_stmt_rcp, hp_error, (ub4) 1, (ub4) 0,
					(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
		if(oralog_is_error(hp_error, retstat, print_errors))
		 errors++;
	    }
	}
				    

	/* Commit transaction */
	if(!errors) {
	    debug("[logsoracle] commit\n");
	    OCITransCommit(hp_service, hp_error, (ub4) 0);
	}
	else {
	    debug("[logsoracle] errors present - aborting transaction\n");
	    OCITransRollback(hp_service, hp_error, (ub4) OCI_DEFAULT);
	}


	/* Cleanup (bind handles should be removed as a part of statement) */
	if(hp_stmt_msg)
	    OCIHandleFree(hp_stmt_msg, OCI_HTYPE_STMT);
	if(hp_stmt_rcp)
	    OCIHandleFree(hp_stmt_rcp, OCI_HTYPE_STMT);
	if(hp_error)
	    OCIHandleFree(hp_error, OCI_HTYPE_ERROR);

	pthread_mutex_unlock(&oralog_oper_lock);
	return 0;
}
Example #5
0
/*
 * Execute SQL statement. For non-select statements only.
 */
int	zbx_db_vexecute(const char *fmt, va_list args)
{
	char	*sql = NULL;
	int	ret = ZBX_DB_OK;
	double	sec = 0;

#if defined(HAVE_IBM_DB2)
	SQLHANDLE	hstmt = 0;
	SQLRETURN	ret1;
	SQLLEN		row1;
	SQLLEN		rows = 0;
#elif defined(HAVE_MYSQL)
	int		status;
#elif defined(HAVE_ORACLE)
	OCIStmt		*stmthp = NULL;
	sword		err = OCI_SUCCESS;
#elif defined(HAVE_POSTGRESQL)
	PGresult	*result;
	char		*error = NULL;
#elif defined(HAVE_SQLITE3)
	int		err;
	char		*error = NULL;
#endif

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

	sql = zbx_dvsprintf(sql, fmt, args);

	if (0 == txn_init && 0 == txn_level)
		zabbix_log(LOG_LEVEL_DEBUG, "query without transaction detected");

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

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

#if defined(HAVE_IBM_DB2)
	/* allocate a statement handle */
	if (SUCCEED != zbx_ibm_db2_success(SQLAllocHandle(SQL_HANDLE_STMT, ibm_db2.hdbc, &hstmt)))
		ret = ZBX_DB_DOWN;

	/* directly execute the statement; returns SQL_NO_DATA_FOUND when no rows were affected */
  	if (ZBX_DB_OK == ret && SUCCEED != zbx_ibm_db2_success_ext(SQLExecDirect(hstmt, (SQLCHAR *)sql, SQL_NTS)))
		ret = ZBX_DB_DOWN;

	/* get number of affected rows */
	if (ZBX_DB_OK == ret && SUCCEED != zbx_ibm_db2_success(SQLRowCount(hstmt, &rows)))
		ret = ZBX_DB_DOWN;

	/* process other SQL statements in the batch */
	while (ZBX_DB_OK == ret && SUCCEED == zbx_ibm_db2_success(ret1 = SQLMoreResults(hstmt)))
	{
		if (SUCCEED != zbx_ibm_db2_success(SQLRowCount(hstmt, &row1)))
			ret = ZBX_DB_DOWN;
		else
			rows += row1;
	}

	if (ZBX_DB_OK == ret && SQL_NO_DATA_FOUND != ret1)
		ret = ZBX_DB_DOWN;

	if (ZBX_DB_OK != ret)
	{
		zbx_ibm_db2_log_errors(SQL_HANDLE_DBC, ibm_db2.hdbc);
		zbx_ibm_db2_log_errors(SQL_HANDLE_STMT, hstmt);

		ret = (SQL_CD_TRUE == IBM_DB2server_status() ? ZBX_DB_FAIL : ZBX_DB_DOWN);
	}
	else if (0 <= rows)
	{
		ret = (int)rows;
	}

	if (hstmt)
		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
#elif defined(HAVE_MYSQL)
	if (NULL == conn)
	{
		zabbix_errlog(ERR_Z3003);
		ret = ZBX_DB_FAIL;
	}
	else
	{
		if (0 != (status = 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:
					ret = ZBX_DB_DOWN;
					break;
				default:
					ret = ZBX_DB_FAIL;
					break;
			}
		}
		else
		{
			do
			{
				if (0 != mysql_field_count(conn))
				{
					zabbix_log(LOG_LEVEL_DEBUG, "cannot retrieve result set");
					break;
				}
				else
					ret += (int)mysql_affected_rows(conn);

				/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
				if (0 < (status = mysql_next_result(conn)))
					zabbix_errlog(ERR_Z3005, mysql_errno(conn), mysql_error(conn), sql);
			}
			while (0 == status);
		}
	}
#elif defined(HAVE_ORACLE)
	err = OCIHandleAlloc((dvoid *)oracle.envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);

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

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

		if (OCI_SUCCESS == err)
		{
			ub4	nrows = 0;

			err = OCIAttrGet((void *)stmthp, OCI_HTYPE_STMT, (ub4 *)&nrows,
					  (ub4 *)0, OCI_ATTR_ROW_COUNT, oracle.errhp);

			ret = nrows;
		}
	}

	if (OCI_SUCCESS != err)
	{
		zabbix_errlog(ERR_Z3005, err, zbx_oci_error(err), sql);
		ret = (OCI_SERVER_NORMAL == OCI_DBserver_status() ? ZBX_DB_FAIL : ZBX_DB_DOWN);
	}

	if (NULL != stmthp)
	{
		(void)OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT);
		stmthp = NULL;
	}
#elif defined(HAVE_POSTGRESQL)
	result = PQexec(conn,sql);

	if (NULL == result)
	{
		zabbix_errlog(ERR_Z3005, 0, "result is NULL", sql);
		ret = (CONNECTION_OK == PQstatus(conn) ? ZBX_DB_FAIL : ZBX_DB_DOWN);
	}
	else if (PGRES_COMMAND_OK != PQresultStatus(result))
	{
		error = zbx_dsprintf(error, "%s:%s",
				PQresStatus(PQresultStatus(result)),
				PQresultErrorMessage(result));
		zabbix_errlog(ERR_Z3005, 0, error, sql);
		zbx_free(error);

		ret = (CONNECTION_OK == PQstatus(conn) ? ZBX_DB_FAIL : ZBX_DB_DOWN);
	}

	if (ZBX_DB_OK == ret)
		ret = atoi(PQcmdTuples(result));

	PQclear(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);
	}

lbl_exec:
	if (SQLITE_OK != (err = sqlite3_exec(conn, sql, NULL, 0, &error)))
	{
		if (SQLITE_BUSY == err)
			goto lbl_exec;

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

		switch (err)
		{
			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_TOOBIG:	/* String or BLOB exceeds size limit */
			case SQLITE_CONSTRAINT:	/* Abort due to constraint violation */
			case SQLITE_MISMATCH:	/* Data type mismatch */
				ret = ZBX_DB_FAIL;
				break;
			default:
				ret = ZBX_DB_DOWN;
				break;
		}
	}

	if (ZBX_DB_OK == ret)
		ret = sqlite3_changes(conn);

	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 (ZBX_DB_FAIL == ret && 0 < txn_level)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "query [%s] failed, setting transaction as failed", sql);
		txn_error = 1;
	}
clean:
	zbx_free(sql);

	return ret;
}
Example #6
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;
}
Example #7
0
static int oracle_select(void *theconn, const Octstr *sql, List *binds, List **res)
{
    List *row;
    OCIStmt *stmt;
    OCIParam *dparam;
    sword status;
    ub4 columns;
    ub4 i;
    struct data_s {
        text *data;
        ub2 size;
        sb2 ind;
        ub2 type;
    };
    struct data_s *data;
    struct ora_conn *conn = (struct ora_conn*) theconn;
    int binds_len = (binds ? gwlist_len(binds) : 0);

    *res = NULL;

    /* allocate statement handle */
    status = OCIHandleAlloc(conn->envp, (dvoid**)&stmt, OCI_HTYPE_STMT, 0,0);
    if (OCI_SUCCESS != status) {
        oracle_checkerr(conn->errhp, status);
        return -1;
    }
    /* prepare statement */
    status = OCIStmtPrepare(stmt, conn->errhp, (unsigned char*)octstr_get_cstr(sql),
                            octstr_len(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
    if (OCI_SUCCESS != status) {
        oracle_checkerr(conn->errhp, status);
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }

    /* bind variables */
    for (i = 0; i < binds_len; i++) {
        OCIBind *bndhp = NULL;
        Octstr *bind = gwlist_get(binds, i);
        status = OCIBindByPos(stmt, &bndhp,
                              conn->errhp, (i+1), (dvoid *) octstr_get_cstr(bind),
                              (sword) octstr_len(bind)+1, SQLT_STR, (dvoid *) 0, (ub2 *)0,
                              (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT);
        if (OCI_SUCCESS != status) {
            oracle_checkerr(conn->errhp, status);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }
    }
    /* execute our statement */
    status = OCIStmtExecute(conn->svchp, stmt, conn->errhp, 0, 0, NULL, NULL,
                            OCI_DEFAULT);
    if (OCI_SUCCESS != status && OCI_NO_DATA != status) {
        oracle_checkerr(conn->errhp, status);
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }
    /* receive column count */
    status = OCIAttrGet(stmt, OCI_HTYPE_STMT, &columns, 0, OCI_ATTR_PARAM_COUNT,
                        conn->errhp);
    if (status != OCI_SUCCESS) {
        oracle_checkerr(conn->errhp, status);
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }

    debug("dbpool.oracle",0,"SQL has %d columns", columns);

    /* allocate array of pointers */
    debug("dbpool.oracle",0,"alloc size=%ld",sizeof(text*)*columns);
    data = gw_malloc(sizeof(struct data_s)*columns);

    debug("dbpool.oracle",0,"retrieve data_size");
    /* retrieve data size for every column and allocate it */
    for (i=0 ; i < columns; i++) {
        OCIDefine *defh;

        status = OCIParamGet(stmt, OCI_HTYPE_STMT, conn->errhp,
                             (dvoid**) &dparam, i+1);
        if (status != OCI_SUCCESS) {
            oracle_checkerr(conn->errhp, status);
            columns = i;
            for (i = 0; i < columns; i++)
                gw_free(data[i].data);
            gw_free(data);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }

        status = OCIAttrGet(dparam, OCI_DTYPE_PARAM, (dvoid*) &data[i].size,
                            0, OCI_ATTR_DATA_SIZE, conn->errhp);
        if (status != OCI_SUCCESS) {
            oracle_checkerr(conn->errhp, status);
            columns = i;
            for (i = 0; i < columns; i++)
                gw_free(data[i].data);
            gw_free(data);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }

        status = OCIAttrGet(dparam, OCI_DTYPE_PARAM, (dvoid*) &data[i].type,
                            0, OCI_ATTR_DATA_TYPE, conn->errhp);
        if (status != OCI_SUCCESS) {
            oracle_checkerr(conn->errhp, status);
            columns = i;
            for (i = 0; i < columns; i++)
                gw_free(data[i].data);
            gw_free(data);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }

        /* convert all data types to C-Strings except DATE */
        if (data[i].type != SQLT_DAT) {
            data[i].size++; /* terminating zero */
            data[i].type = SQLT_STR;
        }

        debug("dbpool.oracle",0,"alloc size=%d", data[i].size);
        data[i].data = gw_malloc(data[i].size);

        /* bind allocated values to statement handle */
        status = OCIDefineByPos(stmt, &defh, conn->errhp, i+1, data[i].data,
                                data[i].size, data[i].type, &data[i].ind,
                                0, 0, OCI_DEFAULT);
        if (status != OCI_SUCCESS) {
            oracle_checkerr(conn->errhp, status);
            columns = i;
            for (i = 0; i <= columns; i++)
                gw_free(data[i].data);
            gw_free(data);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }
    }

    *res = gwlist_create();
    /* fetch data */
    while ((status = OCIStmtFetch(stmt, conn->errhp, 1,
                                  OCI_FETCH_NEXT, OCI_DEFAULT)) == OCI_SUCCESS ||
            status == OCI_SUCCESS_WITH_INFO) {

        row = gwlist_create();
        for (i = 0; i < columns; i++) {
            if (data[i].data == NULL || data[i].ind == -1) {
                gwlist_insert(row, i, octstr_create(""));
            } else {
                gwlist_insert(row, i, octstr_create_from_data((const char*)data[i].data, data[i].size));
            }
            /* debug("dbpool.oracle",0,"inserted value = '%s'",
                     octstr_get_cstr(gwlist_get(row,i))); */
        }
        gwlist_append(*res, row);
    }

    /* ignore OCI_NO_DATA error */
    if (status != OCI_NO_DATA) {
        List *row;
        oracle_checkerr(conn->errhp, status);
        for (i = 0; i < columns; i++)
            gw_free(data[i].data);
        gw_free(data);
        while ((row = gwlist_extract_first(*res)) != NULL)
            gwlist_destroy(row, octstr_destroy_item);
        gwlist_destroy(*res, NULL);
        *res = NULL;
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }

    for (i = 0; i < columns; i++)
        gw_free(data[i].data);

    gw_free(data);
    OCIHandleFree(stmt, OCI_HTYPE_STMT);

    return 0;
}
Example #8
0
static int oracle_update(void *theconn, const Octstr *sql, List *binds)
{
    OCIStmt *stmt;
    sword status;
    ub4 rows = 0, i;
    struct ora_conn *conn = (struct ora_conn*) theconn;
    int binds_len = (binds ? gwlist_len(binds) : 0);

    /* allocate statement handle */
    status = OCIHandleAlloc(conn->envp, (dvoid**)&stmt, OCI_HTYPE_STMT, 0,0);
    if (OCI_SUCCESS != status) {
        oracle_checkerr(conn->errhp, status);
        return -1;
    }
    debug("dbpool.oracle",0,"OCIStmt allocated");
    /* prepare statement */
    status = OCIStmtPrepare(stmt, conn->errhp, (unsigned char*)octstr_get_cstr(sql),
                            octstr_len(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
    if (OCI_SUCCESS != status) {
        oracle_checkerr(conn->errhp, status);
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }
    debug("dbpool.oracle",0,"OCIStmtPrepare done");

    /* bind variables */
    for (i = 0; i < binds_len; i++) {
        Octstr *bind = gwlist_get(binds, i);
        OCIBind *bndhp = NULL;
        status = OCIBindByPos(stmt, &bndhp,
                              conn->errhp, (i+1), (dvoid *) octstr_get_cstr(bind),
                              (sword) octstr_len(bind)+1, SQLT_STR, (dvoid *) 0, (ub2 *)0,
                              (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT);
        if (OCI_SUCCESS != status) {
            oracle_checkerr(conn->errhp, status);
            OCIHandleFree(stmt, OCI_HTYPE_STMT);
            return -1;
        }
    }

    /* execute our statement */
    status = OCIStmtExecute(conn->svchp, stmt, conn->errhp, 1, 0, NULL, NULL,
                            /*OCI_DEFAULT*/ OCI_COMMIT_ON_SUCCESS);
    if (OCI_SUCCESS != status && OCI_NO_DATA != status) {
        oracle_checkerr(conn->errhp, status);
        OCIHandleFree(stmt, OCI_HTYPE_STMT);
        return -1;
    }
    debug("dbpool.oracle",0,"OCIStmtExecute done");
    /* retrieve #rows processed so far */
    status = OCIAttrGet(stmt, OCI_HTYPE_STMT, &rows, 0, OCI_ATTR_ROW_COUNT,
                        conn->errhp);
    if (status != OCI_SUCCESS) {
        oracle_checkerr(conn->errhp, status);
        /* we doesn't return error here, because sql is executed and commited already */
    }
    debug("dbpool.oracle",0,"rows processed = %d", rows);

    OCIHandleFree(stmt, OCI_HTYPE_STMT);

    return (int) rows;
}
Example #9
0
static void get_db_charsets(conn_info_t *params_p, ub2 *char_csid, 
                            ub2 *nchar_csid)
{
  OCIDefine  *defnp1 = (OCIDefine *) NULL;
  OCIDefine  *defnp2 = (OCIDefine *) NULL;
  oratext     parm[PARM_BUFLEN];
  oratext     value[OCI_NLS_MAXBUFSZ];
  ub2         parm_len = 0;
  ub2         value_len = 0;
  oci_t       ocistruct; 
  oci_t      *ocip = &ocistruct;
   
  *char_csid = 0;
  *nchar_csid = 0;
  memset (ocip, 0, sizeof(ocistruct));

  if (OCIEnvCreate(&ocip->envp, OCI_OBJECT, (dvoid *)0,
                   (dvoid * (*)(dvoid *, size_t)) 0,
                   (dvoid * (*)(dvoid *, dvoid *, size_t))0,
                   (void (*)(dvoid *, dvoid *)) 0,
                   (size_t) 0, (dvoid **) 0))
  {
    ocierror(ocip, (char *)"OCIEnvCreate() failed", TRUE);
  }

  if (OCIHandleAlloc((dvoid *) ocip->envp, (dvoid **) &ocip->errp,
                     (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0))
  {
    ocierror(ocip, (char *)"OCIHandleAlloc(OCI_HTYPE_ERROR) failed", TRUE);
  }

  OCICALL(ocip, 
          OCILogon(ocip->envp, ocip->errp, &ocip->svcp,
                   params_p->user, params_p->userlen,
                   params_p->passw, params_p->passwlen,
                   params_p->dbname, params_p->dbnamelen));

  OCICALL(ocip, 
          OCIHandleAlloc((dvoid *) ocip->envp, (dvoid **) &ocip->stmtp,
                         (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));

  /* Execute stmt to select the db nls char and nchar character set */ 
  OCICALL(ocip, 
          OCIStmtPrepare(ocip->stmtp, ocip->errp,
                         (CONST text *)GET_DB_CHARSETS,
                         (ub4)strlen((char *)GET_DB_CHARSETS),
                         (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

  OCICALL(ocip,
          OCIDefineByPos(ocip->stmtp, &defnp1,
                         ocip->errp, (ub4) 1, parm,
                         PARM_BUFLEN, SQLT_CHR, (void*) 0,
                         &parm_len, (ub2 *)0, OCI_DEFAULT));

  OCICALL(ocip,
          OCIDefineByPos(ocip->stmtp, &defnp2,
                         ocip->errp, (ub4) 2, value,
                         OCI_NLS_MAXBUFSZ, SQLT_CHR, (void*) 0,
                         &value_len, (ub2 *)0, OCI_DEFAULT));

  OCICALL(ocip, 
          OCIStmtExecute(ocip->svcp, ocip->stmtp, 
                         ocip->errp, (ub4)0, (ub4)0, 
                         (const OCISnapshot *)0,
                         (OCISnapshot *)0, (ub4)OCI_DEFAULT));

  while (OCIStmtFetch(ocip->stmtp, ocip->errp, 1,
                      OCI_FETCH_NEXT, OCI_DEFAULT) == OCI_SUCCESS)
  {
    value[value_len] = '\0';
    if (parm_len == strlen("NLS_CHARACTERSET") &&
        !memcmp(parm, "NLS_CHARACTERSET", parm_len))
    {
      *char_csid = OCINlsCharSetNameToId(ocip->envp, value);
      printf("Outbound database NLS_CHARACTERSET = %.*s (csid = %d) \n",
             value_len, value, *char_csid);
    }
    else if (parm_len == strlen("NLS_NCHAR_CHARACTERSET") &&
             !memcmp(parm, "NLS_NCHAR_CHARACTERSET", parm_len))
    {
      *nchar_csid = OCINlsCharSetNameToId(ocip->envp, value);
      printf("Outbound database NLS_NCHAR_CHARACTERSET = %.*s (csid = %d) \n",
             value_len, value, *nchar_csid);
    }
  }

  disconnect_db(ocip);
}
Example #10
0
/*
   Execute a SQL command that returns a result table, and and bind the
   default row.  Also check and bind the global array of bind variables
   (if any).
*/
int
cllExecSqlWithResult( icatSessionStruct *icss, int *stmtNum, const char *sql ) {
    OCIEnv           *p_env;
    OCISvcCtx        *p_svc;
    static OCIStmt          *p_statement;
    static OCIDefine        *p_dfn    = ( OCIDefine * ) 0;
    int stat, stat2, i, j;
    char *cptr;
    char sqlConverted[MAX_SQL_SIZE];

    icatStmtStrct *myStatement;
    int statementNumber;

    int counter;
    OCIParam     *mypard = ( OCIParam * ) 0;
    ub2 dtype;
    ub2 col_width;
    ub4 char_semantics;
    OraText  *colName;

    static int columnLength[MAX_TOKEN];
    static sb2 indicator[MAX_TOKEN];

    p_svc = ( OCISvcCtx * )icss->connectPtr;
    p_env = ( OCIEnv * )icss->environPtr;

    i = convertSqlToOra( sql, sqlConverted );
    if ( i != 0 ) {
        rodsLog( LOG_ERROR, "cllExecSqlWithResult: SQL too long" );
        return CAT_OCI_ERROR;
    }

    /* Allocate SQL statement */
    stat = OCIHandleAlloc( ( dvoid * ) p_env, ( dvoid ** ) &p_statement,
                           OCI_HTYPE_STMT, ( size_t ) 0, ( dvoid ** ) 0 );
    if ( stat != OCI_SUCCESS ) {
        rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIHandleAlloc failed: %d",
                 stat );
        logOraError( LOG_ERROR, p_err, stat );
        return CAT_OCI_ERROR;
    }

    /* set up our statement */
    statementNumber = -1;
    for ( i = 0; i < MAX_NUM_OF_CONCURRENT_STMTS && statementNumber < 0; i++ ) {
        if ( icss->stmtPtr[i] == 0 ) {
            statementNumber = i;
        }
    }
    if ( statementNumber < 0 ) {
        rodsLog( LOG_ERROR,
                 "cllExecSqlWithResult: too many concurrent statements" );
        return -2;
    }

    myStatement = ( icatStmtStrct * )malloc( sizeof( icatStmtStrct ) );
    icss->stmtPtr[statementNumber] = myStatement;
    myStatement->numOfCols = 0;

    myStatement->stmtPtr = p_statement;

    /* Prepare SQL statement */
    stat = OCIStmtPrepare( p_statement, p_err, ( OraText * )sqlConverted,
                           ( ub4 ) strlen( sqlConverted ),
                           ( ub4 ) OCI_NTV_SYNTAX, ( ub4 ) OCI_DEFAULT );
    if ( stat != OCI_SUCCESS ) {
        rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIStmtPrepare failed: %d", stat );
        rodsLog( LOG_ERROR, sqlConverted );
        logOraError( LOG_ERROR, p_err, stat );
        return CAT_OCI_ERROR;
    }

    if ( bindTheVariables( p_statement, sqlConverted ) != 0 ) {
        logTheBindVariables( LOG_ERROR );
        return CAT_OCI_ERROR;
    }

    logTheBindVariables( 0 );
    rodsLogSql( sqlConverted );

    /* Execute statement */
    stat = OCIStmtExecute( p_svc, p_statement, p_err, ( ub4 ) 0, ( ub4 ) 0,
                           ( CONST OCISnapshot * ) NULL, ( OCISnapshot * ) NULL,
                           OCI_DEFAULT );

    stat2 = logExecuteStatus( stat, sqlConverted, "cllExecSqlWithResult" );

    if ( stat2 ) {
        return stat2;
    }

    *stmtNum = statementNumber; /* return index to statement handle */

    /* get the number of columns and width of the columns */

    /* Request a parameter descriptor for position 1 in the select-list */
    counter = 1;
    stat = OCIParamGet( ( dvoid * )p_statement, OCI_HTYPE_STMT, p_err,
                        ( dvoid ** )&mypard, ( ub4 ) counter );

    /* Loop only if a descriptor was successfully retrieved for
       current position, starting at 1 */

    while ( stat == OCI_SUCCESS ) {
        /* Retrieve the datatype attribute */
        stat = OCIAttrGet( ( dvoid* ) mypard, ( ub4 ) OCI_DTYPE_PARAM,
                           ( dvoid* ) &dtype, ( ub4 * ) 0, ( ub4 ) OCI_ATTR_DATA_TYPE,
                           ( OCIError * ) p_err );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIAttrGet failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }

        /* Retrieve the length semantics for the column */
        char_semantics = 0;
        stat = OCIAttrGet( ( dvoid* ) mypard, ( ub4 ) OCI_DTYPE_PARAM,
                           ( dvoid* ) &char_semantics, ( ub4 * ) 0,
                           ( ub4 ) OCI_ATTR_CHAR_USED,
                           ( OCIError * ) p_err );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIAttrGet failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }

        /* Retrieve the column width in characters */
        col_width = 0;
        if ( char_semantics ) {
            stat = OCIAttrGet( ( dvoid* ) mypard, ( ub4 ) OCI_DTYPE_PARAM,
                               ( dvoid* ) &col_width, ( ub4 * ) 0,
                               ( ub4 ) OCI_ATTR_CHAR_SIZE,
                               ( OCIError * ) p_err );
        }
        else {
            stat = OCIAttrGet( ( dvoid* ) mypard, ( ub4 ) OCI_DTYPE_PARAM,
                               ( dvoid* ) &col_width, ( ub4 * ) 0,
                               ( ub4 ) OCI_ATTR_DATA_SIZE,
                               ( OCIError * ) p_err );
        }
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIAttrGet failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }

        /* get the col name */
        stat = OCIAttrGet( ( dvoid* ) mypard, ( ub4 ) OCI_DTYPE_PARAM,
                           &colName, ( ub4 * ) 0,
                           ( ub4 ) OCI_ATTR_NAME,
                           ( OCIError * ) p_err );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIAttrGet failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }

        columnLength[counter] = col_width;

        i = counter - 1;
        columnLength[i] = col_width;

        if ( strlen( ( char * )colName ) > col_width ) {
            columnLength[i] = strlen( ( char* )colName );
        }

        myStatement->resultColName[i] = ( char * )malloc( ( int )columnLength[i] + 2 );
        strncpy( myStatement->resultColName[i],
                 ( char * )colName, columnLength[i] );

        /* Big cludge/hack, but it looks like an OCI bug when the colName
           is exactly 8 bytes (or something).  Anyway, when the column name
           is "RESC_NETRESC_DEF_PATH" it's actually the running together of
           two names, so the code below corrects it. */
        if ( strcmp( myStatement->resultColName[i], "RESC_NETRESC_DEF_PATH" ) == 0 ) {
            strncpy( myStatement->resultColName[i],
                     "RESC_NET", columnLength[i] );
        }
        /* Second case, second cludge/hack */
        if ( strcmp( myStatement->resultColName[i],
                     "USER_DISTIN_NAMEUSER_INFO" ) == 0 ) {
            strncpy( myStatement->resultColName[i],
                     "USER_DISTIN_NAME", columnLength[i] );
        }

        /* convert the column name to lower case to match postgres */
        cptr = ( char* )myStatement->resultColName[i];
        for ( j = 0; j < columnLength[i]; j++ ) {
            if ( *cptr == '\0' ) {
                break;
            }
            if ( *cptr == ':' ) {
                break;
            }
            if ( *cptr >= 'A' && *cptr <= 'Z' ) {
                *cptr += ( ( int )'a' - ( int )'A' );
            }
            cptr++;
        }

        myStatement->resultValue[i] = ( char * )malloc( ( int )columnLength[i] + 2 );
        strcpy( ( char * )myStatement->resultValue[i], "" );

        stat = OCIDefineByPos( p_statement, &p_dfn, p_err, counter,
                               ( dvoid * ) myStatement->resultValue[i],
                               ( sword ) columnLength[i], SQLT_STR,
                               ( dvoid * )&indicator[i],
                               ( ub2 * )0, ( ub2 * )0, OCI_DEFAULT );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlWithResult: OCIDefineByPos failed: %d", stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }


        /* increment counter and get next descriptor, if there is one */
        counter++;
        stat = OCIParamGet( ( dvoid * )p_statement, OCI_HTYPE_STMT, p_err,
                            ( dvoid ** )&mypard, ( ub4 ) counter );
    }


    if ( counter == 1 ) {
        rodsLog( LOG_ERROR, "cllExecSqlWithResult: SQLNumResultCols failed: %d",
                 stat );
        return -2;
    }
    myStatement->numOfCols = counter - 1;

    return 0;
}
Example #11
0
/*
  Execute a SQL command which has no resulting table.  Examples include
  insert, delete, update.
*/
int
cllExecSqlNoResult( icatSessionStruct *icss, const char *sqlInput ) {

    int stat, stat2, stat3;
    OCIEnv           *p_env;
    OCISvcCtx        *p_svc;
    static OCIStmt          *p_statement;
    char sql[MAX_SQL_SIZE];
    ub4 rows_affected;
    ub4 *pUb4;

    stat = convertSqlToOra( ( char* )sqlInput, sql );
    if ( stat != 0 ) {
        rodsLog( LOG_ERROR, "cllExecSqlNoResult: SQL too long" );
        return CAT_OCI_ERROR;
    }

    p_svc = ( OCISvcCtx * )icss->connectPtr;
    p_env = ( OCIEnv * )icss->environPtr;

    if ( strcmp( sql, "commit" ) == 0 ) {
        rodsLogSql( sql );
        stat = OCITransCommit( p_svc, p_err, ( ub4 ) OCI_DEFAULT );
        stat2 = logExecuteStatus( stat, sql, "cllExecSqlNoResult" );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCITransCommit failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }
        return 0;
    }

    if ( strcmp( sql, "rollback" ) == 0 ) {
        rodsLogSql( sql );
        stat = OCITransRollback( p_svc, p_err, ( ub4 ) OCI_DEFAULT );
        stat2 = logExecuteStatus( stat, sql, "cllExecSqlNoResult" );
        if ( stat != OCI_SUCCESS ) {
            rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCITransRollback failed: %d",
                     stat );
            logOraError( LOG_ERROR, p_err, stat );
            return CAT_OCI_ERROR;
        }
        return 0;
    }


    /* Allocate SQL statement */
    stat = OCIHandleAlloc( ( dvoid * ) p_env, ( dvoid ** ) &p_statement,
                           OCI_HTYPE_STMT, ( size_t ) 0, ( dvoid ** ) 0 );
    if ( stat != OCI_SUCCESS ) {
        rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCIHandleAlloc failed: %d", stat );
        logOraError( LOG_ERROR, p_err, stat );
        return CAT_OCI_ERROR;
    }

    /* Prepare SQL statement */
    stat = OCIStmtPrepare( p_statement, p_err, ( OraText * )sql,
                           ( ub4 ) strlen( sql ),
                           ( ub4 ) OCI_NTV_SYNTAX, ( ub4 ) OCI_DEFAULT );
    if ( stat != OCI_SUCCESS ) {
        rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCIStmtPrepare failed: %d", stat );
        rodsLog( LOG_ERROR, sql );
        logOraError( LOG_ERROR, p_err, stat );
        return CAT_OCI_ERROR;
    }

    if ( bindTheVariables( p_statement, sql ) != 0 ) {
        logTheBindVariables( LOG_ERROR );
        return CAT_OCI_ERROR;
    }
    logTheBindVariables( 0 );
    rodsLogSql( sql );

    /* Execute statement */
    stat = OCIStmtExecute( p_svc, p_statement, p_err, ( ub4 ) 1, ( ub4 ) 0,
                           ( CONST OCISnapshot * ) NULL, ( OCISnapshot * ) NULL,
                           OCI_DEFAULT );
    stat2 = logExecuteStatus( stat, sql, "cllExecSqlNoResult" );
    if ( stat == OCI_NO_DATA ) { /* Don't think this ever happens, but... */
        return CAT_SUCCESS_BUT_WITH_NO_INFO;
    }

    /* malloc it so that it's aligned properly, else can get
       bus errors when doing 64-bit addressing */
    pUb4 = ( ub4* ) malloc( sizeof( rows_affected ) );
    *pUb4 = 0;
    rows_affected = 0;

    if ( stat == OCI_ERROR ) {
        rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCIStmtExecute failed: %d", stat );
        logOraError( LOG_ERROR, p_err, stat );
        free( pUb4 );
        if ( stat2 == CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME ) {
            return stat2;
        }
        return CAT_OCI_ERROR;
    }

    stat3 = OCIAttrGet( ( dvoid * )p_statement, OCI_HTYPE_STMT, pUb4, 0,
                        OCI_ATTR_ROW_COUNT, ( OCIError * ) p_err );
    rows_affected = *pUb4;
    free( pUb4 );

    stat = OCIHandleFree( ( dvoid * )p_statement, OCI_HTYPE_STMT ); /* free the
                                                                    statement */

    if ( stat3 != OCI_SUCCESS ) {
        rodsLog( LOG_ERROR, "cllExecSqlNoResult: OCIAttrGet failed: %d", stat );
        return stat3;
    }
    /* rodsLog(LOG_NOTICE, "cllExecSqlNoResult: OCIAttrGet, rows_affected: %d",
       rows_affected); */
    if ( rows_affected == 0 ) {
        return CAT_SUCCESS_BUT_WITH_NO_INFO;
    }

    return stat2;

}
Example #12
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;
}
Example #13
0
CPLErr OGROCIStatement::Execute( const char *pszSQLStatement,
                                 int nMode )

{
/* -------------------------------------------------------------------- */
/*      Prepare the statement if it is being passed in.                 */
/* -------------------------------------------------------------------- */
    if( pszSQLStatement != NULL )
    {
        CPLErr eErr = Prepare( pszSQLStatement );
        if( eErr != CE_None )
            return eErr;
    }

    if( hStatement == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "No prepared statement in call to OGROCIStatement::Execute(NULL)" );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Determine if this is a SELECT statement.                        */
/* -------------------------------------------------------------------- */
    ub2  nStmtType;

    if( poSession->Failed(
        OCIAttrGet( hStatement, OCI_HTYPE_STMT,
                    &nStmtType, 0, OCI_ATTR_STMT_TYPE, poSession->hError ),
        "OCIAttrGet(ATTR_STMT_TYPE)") )
        return CE_Failure;

    int bSelect = (nStmtType == OCI_STMT_SELECT);

/* -------------------------------------------------------------------- */
/*      Work out some details about execution mode.                     */
/* -------------------------------------------------------------------- */
    if( nMode == -1 )
    {
        if( bSelect )
            nMode = OCI_DEFAULT;
        else
            nMode = OCI_COMMIT_ON_SUCCESS;
    }

/* -------------------------------------------------------------------- */
/*      Execute the statement.                                          */
/* -------------------------------------------------------------------- */
    if( poSession->Failed(
        OCIStmtExecute( poSession->hSvcCtx, hStatement,
                        poSession->hError, (ub4)bSelect ? 0 : 1, (ub4)0,
                        (OCISnapshot *)NULL, (OCISnapshot *)NULL, nMode ),
        pszCommandText ) )
        return CE_Failure;

    if( !bSelect )
    {
        ub4 row_count;
        if( poSession->Failed(
            OCIAttrGet( hStatement, OCI_HTYPE_STMT,
                        &row_count, 0, OCI_ATTR_ROW_COUNT, poSession->hError ),
                        "OCIAttrGet(OCI_ATTR_ROW_COUNT)") )
            return CE_Failure;
        nAffectedRows = row_count;

        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Count the columns.                                              */
/* -------------------------------------------------------------------- */
    for( nRawColumnCount = 0; true; nRawColumnCount++ )
    {
        OCIParam     *hParmDesc;

        if( OCIParamGet( hStatement, OCI_HTYPE_STMT, poSession->hError,
                         (dvoid**)&hParmDesc,
                         (ub4) nRawColumnCount+1 ) != OCI_SUCCESS )
            break;
    }

    panFieldMap = (int *) CPLCalloc(sizeof(int),nRawColumnCount);

    papszCurColumn = (char **) CPLCalloc(sizeof(char*),nRawColumnCount+1);
    panCurColumnInd = (sb2 *) CPLCalloc(sizeof(sb2),nRawColumnCount+1);

/* ==================================================================== */
/*      Establish result column definitions, and setup parameter        */
/*      defines.                                                        */
/* ==================================================================== */
    poDefn = new OGRFeatureDefn( pszCommandText );
    poDefn->SetGeomType(wkbNone);
    poDefn->Reference();

    for( int iParm = 0; iParm < nRawColumnCount; iParm++ )
    {
        OGRFieldDefn oField( "", OFTString );
        OCIParam     *hParmDesc;
        ub2          nOCIType;
        ub4          nOCILen;

/* -------------------------------------------------------------------- */
/*      Get parameter definition.                                       */
/* -------------------------------------------------------------------- */
        if( poSession->Failed(
            OCIParamGet( hStatement, OCI_HTYPE_STMT, poSession->hError,
                         (dvoid**)&hParmDesc, (ub4) iParm+1 ),
            "OCIParamGet") )
            return CE_Failure;

        if( poSession->GetParmInfo( hParmDesc, &oField, &nOCIType, &nOCILen )
            != CE_None )
            return CE_Failure;

        if( oField.GetType() == OFTBinary )
        {
            /* We could probably generalize that, but at least it works in that */
            /* use case */
            if( EQUAL(oField.GetNameRef(), "DATA_DEFAULT") && nOCIType == SQLT_LNG )
            {
                oField.SetType(OFTString);
            }
            else
            {
                panFieldMap[iParm] = -1;
                continue;
            }
        }

        poDefn->AddFieldDefn( &oField );
        panFieldMap[iParm] = poDefn->GetFieldCount() - 1;

/* -------------------------------------------------------------------- */
/*      Prepare a binding.                                              */
/* -------------------------------------------------------------------- */
        int nBufWidth = 256, nOGRField = panFieldMap[iParm];
        OCIDefine *hDefn = NULL;

        if( oField.GetWidth() > 0 )
            /* extra space needed for the decimal separator the string
            terminator and the negative sign (Tamas Szekeres)*/
            nBufWidth = oField.GetWidth() + 3;
        else if( oField.GetType() == OFTInteger )
            nBufWidth = 22;
        else if( oField.GetType() == OFTReal )
            nBufWidth = 36;
        else if ( oField.GetType() == OFTDateTime )
            nBufWidth = 40;
        else if ( oField.GetType() == OFTDate )
            nBufWidth = 20;

        papszCurColumn[nOGRField] = (char *) CPLMalloc(nBufWidth+2);
        CPLAssert( ((long) papszCurColumn[nOGRField]) % 2 == 0 );

        if( poSession->Failed(
            OCIDefineByPos( hStatement, &hDefn, poSession->hError,
                            iParm+1,
                            (ub1 *) papszCurColumn[nOGRField], nBufWidth,
                            SQLT_STR, panCurColumnInd + nOGRField,
                            NULL, NULL, OCI_DEFAULT ),
            "OCIDefineByPos" ) )
            return CE_Failure;
    }

    return CE_None;
}